GNU PEDA Pwntools Python

Введение в PEDA и Pwntools. Часть 1

Введение в PEDA и Pwntools. Часть 1

В этой тстатье поёдет разговор про PEDA. Нет, не про тех “педа”, не, пугайтесь, а про Python Exploit Development Assistance, очень удобный кит для создания эксплоитов и азы работы с ним.

Предлагаю Вашему вниманию вольный перевод цикла статей: https://github.com/nnamon/linux-exploitation-course

Предварительная подготовка:

  1. Понимание архитектуры и языка ассемблер intel x86-64
  2. Знание отладчика GDB
  3. Знание C и Python
  4. Понимание механизма обычных прыжков(jump) в шеллкод
  5. Умение работать с виртуальными машинами и виртуальным окружением

План курса:

  1. Введение в PEDA и Pwntools
  2. Введение в возвратно-ориентированное программирование
  3. Классические техники эксплуатации уязвимостей
  4. Защитные механизмы бинарных файлов в Linux
  5. Обход NX используя технику возвратно-ориентированного программирования(Return Oriented Programming)
  6. Обход NX используя Ret2Libc
  7. ASLR изнутри
  8. Обход ASLR/NX используя Ret2PLT
  9. Обход ASLR/NX используя перезапись GOT
  10. Сложные(многоэтапные) эксплойты
  11. Уязвимости форматирования строк
  12. Дополнительные упражнения

Для работы понадобится виртуальная машина VMWare (https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html) или VirtualBox (https://www.virtualbox.org/wiki/Downloads) и Ваш любимый дистр линукс, например Kali (https://www.kali.org/downloads/)

Настройте удобный доступ к консоли виртуальной машины по SSH или Telnet, так как основная магия будет происходить при помощи командной строки.

Так же нам понадобятся дополнительные файлы для упражнений. Скачаем их в любую удобную папку:

root@kali:~# git clone https://github.com/nnamon/linux-exploitation-course

И так, погнали…

Введение в PEDA и Pwntools

GDB с плагином PEDA и Pwntools – это две утилиты, которые будут очень интенсивно использоваться на протяжении всего курса. Сейчас разберёмся что к чему и посмотрим как они работают.

Нашими подопытными будут, уже собранные, бинарные файлы, которые мы успешно скачали на этапе подготовки. Давайте переместимся в нужную директорию:

root@kali:~# cd linux-exploitation-course/lessons/3_intro_to_tools/build

Ну и запустим подопытный образец:

root@kali:~/linux-exploitation-course/lessons/3_intro_to_tools/build# ./1_sample
Hello, I am a sample program.

PEDA

PEDA (Python Exploit Development Assistance) это расширение для отладчика GDB, которое добавляет кучу плюх дополнительных функций, повышая эффективность и юзабельность отладчика.

Для установки PEDA достаточно выполнить пару команд:

root@kali:~# git clone https://github.com/longld/peda.git ~/peda
root@kali:~# echo "source ~/peda/peda.py" >> ~/.gdbinit

Ну а теперь можно и тестануть на примере. Запустим GDB для отладки нашего бинарного файла:

root@kali:~/linux-exploitation-course/lessons/3_intro_to_tools/build# gdb ./1_sample
GNU gdb (Debian 8.2.1-2) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./1_sample...(no debugging symbols found)...done.
gdb-peda$ r
Starting program: /root/linux-exploitation-course/lessons/3_intro_to_tools/build/1_sample
Hello, I am a sample program.
[Inferior 1 (process 3297) exited normally]
Warning: not running
gdb-peda$

Командная строка так и должна показывать gdb-peda$, если не показывает, значит что-то пошло на этапе установки плагина. Давайте поставим точку останова в самом начале на функции main и запустим на выполнение:

gdb-peda$ br main
Breakpoint 1 at 0x40052a
gdb-peda$ r
Starting program: /root/linux-exploitation-course/lessons/3_intro_to_tools/build/1_sample
[----------------------------------registers-----------------------------------]
RAX: 0x400526 (<main>:  push   rbp)
RBX: 0x0
RCX: 0x7ffff7fab718 --> 0x7ffff7facd80 --> 0x0
RDX: 0x7fffffffe518 --> 0x7fffffffe791 ("SHELL=/bin/bash")
RSI: 0x7fffffffe508 --> 0x7fffffffe749 ("/root/linux-exploitation-course/lessons/3_intro_to_tools/build/1_sample")
RDI: 0x1
RBP: 0x7fffffffe420 --> 0x400540 (<__libc_csu_init>:    push   r15)
RSP: 0x7fffffffe420 --> 0x400540 (<__libc_csu_init>:    push   r15)
RIP: 0x40052a (<main+4>:        mov    edi,0x4005c4)
R8 : 0x7ffff7facd80 --> 0x0
R9 : 0x7ffff7facd80 --> 0x0
R10: 0xfffffffffffff35c
R11: 0x7ffff7e13fb0 (<__libc_start_main>:       push   r14)
R12: 0x400430 (<_start>:        xor    ebp,ebp)
R13: 0x7fffffffe500 --> 0x1
R14: 0x0
R15: 0x0
EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x400521 <frame_dummy+33>:   jmp    0x4004a0 <register_tm_clones>
   0x400526 <main>:     push   rbp
   0x400527 <main+1>:   mov    rbp,rsp
=> 0x40052a <main+4>:   mov    edi,0x4005c4
   0x40052f <main+9>:   call   0x400400 <puts@plt>
   0x400534 <main+14>:  mov    eax,0x0
   0x400539 <main+19>:  pop    rbp
   0x40053a <main+20>:  ret
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe420 --> 0x400540 (<__libc_csu_init>:   push   r15)
0008| 0x7fffffffe428 --> 0x7ffff7e1409b (<__libc_start_main+235>:       mov    edi,eax)
0016| 0x7fffffffe430 --> 0x0
0024| 0x7fffffffe438 --> 0x7fffffffe508 --> 0x7fffffffe749 ("/root/linux-exploitation-course/lessons/3_intro_to_tools/build/1_sample")
0032| 0x7fffffffe440 --> 0x100100000
0040| 0x7fffffffe448 --> 0x400526 (<main>:      push   rbp)
0048| 0x7fffffffe450 --> 0x0
0056| 0x7fffffffe458 --> 0xa3601b7a6a4817f7
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value

Breakpoint 1, 0x000000000040052a in main ()
gdb-peda$

Должно быть прикольно, всё видно стек, код, регистры. Замечу, что при пошаговом выполнении кода, картинка будет обновляться и будет видна динамика выполнения, что очень удобно. У PEDA в запасе куча всего интересного, полный список можно просмотреть выполнив команду peda:

gdb-peda$ peda
PEDA - Python Exploit Development Assistance for GDB
For latest update, check peda project page: https://github.com/longld/peda/
List of "peda" subcommands, type the subcommand to invoke it:
aslr -- Show/set ASLR setting of GDB
asmsearch -- Search for ASM instructions in memory
assemble -- On the fly assemble and execute instructions using NASM
breakrva -- Set breakpoint by Relative Virtual Address (RVA)
checksec -- Check for various security options of binary
cmpmem -- Compare content of a memory region with a file
context -- Display various information of current execution context
context_code -- Display nearby disassembly at $PC of current execution context
context_register -- Display register information of current execution context
context_stack -- Display stack of current execution context
crashdump -- Display crashdump info and save to file
deactive -- Bypass a function by ignoring its execution (eg sleep/alarm)
distance -- Calculate distance between two addresses
dumpargs -- Display arguments passed to a function when stopped at a call instruction
dumpmem -- Dump content of a memory region to raw binary file
dumprop -- Dump all ROP gadgets in specific memory range
eflags -- Display/set/clear/toggle value of eflags register
elfheader -- Get headers information from debugged ELF file
elfsymbol -- Get non-debugging symbol information from an ELF file
gennop -- Generate abitrary length NOP sled using given characters
getfile -- Get exec filename of current debugged process
getpid -- Get PID of current debugged process
goto -- Continue execution at an address
help -- Print the usage manual for PEDA commands
hexdump -- Display hex/ascii dump of data in memory
hexprint -- Display hexified of data in memory
jmpcall -- Search for JMP/CALL instructions in memory
loadmem -- Load contents of a raw binary file to memory
lookup -- Search for all addresses/references to addresses which belong to a memory range
nearpc -- Disassemble instructions nearby current PC or given address
nextcall -- Step until next 'call' instruction in specific memory range
nextjmp -- Step until next 'j*' instruction in specific memory range
nxtest -- Perform real NX test to see if it is enabled/supported by OS
patch -- Patch memory start at an address with string/hexstring/int
pattern -- Generate, search, or write a cyclic pattern to memory
pattern_arg -- Set argument list with cyclic pattern
pattern_create -- Generate a cyclic pattern
pattern_env -- Set environment variable with a cyclic pattern
pattern_offset -- Search for offset of a value in cyclic pattern
pattern_patch -- Write a cyclic pattern to memory
pattern_search -- Search a cyclic pattern in registers and memory
payload -- Generate various type of ROP payload using ret2plt
pdisass -- Format output of gdb disassemble command with colors
pltbreak -- Set breakpoint at PLT functions match name regex
procinfo -- Display various info from /proc/pid/
profile -- Simple profiling to count executed instructions in the program
pyhelp -- Wrapper for python built-in help
readelf -- Get headers information from an ELF file
refsearch -- Search for all references to a value in memory ranges
reload -- Reload PEDA sources, keep current options untouch
ropgadget -- Get common ROP gadgets of binary or library
ropsearch -- Search for ROP gadgets in memory
searchmem -- Search for a pattern in memory; support regex search
session -- Save/restore a working gdb session to file as a script
set -- Set various PEDA options and other settings
sgrep -- Search for full strings contain the given pattern
shellcode -- Generate or download common shellcodes.
show -- Show various PEDA options and other settings
skeleton -- Generate python exploit code template
skipi -- Skip execution of next count instructions
snapshot -- Save/restore process's snapshot to/from file
start -- Start debugged program and stop at most convenient entry
stepuntil -- Step until a desired instruction in specific memory range
strings -- Display printable strings in memory
substr -- Search for substrings of a given string/number in memory
telescope -- Display memory content at an address with smart dereferences
tracecall -- Trace function calls made by the program
traceinst -- Trace specific instructions executed by the program
unptrace -- Disable anti-ptrace detection
utils -- Miscelaneous utilities from utils module
vmmap -- Get virtual mapping address ranges of section(s) in debugged process
waitfor -- Try to attach to new forked process; mimic "attach -waitfor"
xinfo -- Display detail information of address/registers
xormem -- XOR a memory region with a key
xprint -- Extra support to GDB's print command
xrefs -- Search for all call/data access references to a function/variable
xuntil -- Continue execution until an address or function

Type "help" followed by subcommand for full documentation.

Рассмотрим несколько особо интересных команд.

checksec

Данная команда выводит список защитных механизмов, которые включены и используются для бинарного файла. Очень удобно во время разработки своего эксплойта:

gdb-peda$ checksec
CANARY    : disabled
FORTIFY   : disabled
NX        : ENABLED
PIE       : disabled
RELRO     : Partial

distance

Часто во время разработки своего шеллкода необходимо расчитать расстояние в байтах (дистанцию) между адресами, данная команда служит для быстрого поиска дистанции:

gdb-peda$ distance 0x7fffffffe4f0 0x7fffffffe528
From 0x7fffffffe4f0 to 0x7fffffffe528: 56 bytes, 14 dwords
gdb-peda$

elfsymbol

В том случае, если нужной найти адрес определённого отладочного символа, вы можете использовать данную команду:

gdb-peda$ elfsymbol
Found 2 symbols
puts@plt = 0x400400
__libc_start_main@plt = 0x400410
gdb-peda$

pattern

Генератор паттернов одна из самых оху*льных часто используемых функций. Данная команда генерирует последовательность де Брёйна нужной длинны. Последовательность де Брёйна – это последовательность, которая имеет уникальные подпоследовательности длины n в любой из своих точек (ну или типа того).

В нашем случае, нас будут интересовать уникальные последовательности длинны 4, так как регистры 32-бита (4 байта). Особенно эффективно при нахождении смещений по которым данные записываются в регистры.

Давайте создадим паттерн размером 64:

gdb-peda$ pattern create 64
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAA1AAGAAcAA2AAH'
gdb-peda$

Представим, что мы вызвали переполнение буфера и определили, что указатель выполнения скрэшился на адресе 0x48414132 (‘2AAH’ in ASCII). Мы можем определить точное смещение наших данных, для того чтобы разместить адрес для перенаправления потока выполнения.

gdb-peda$ pattern offset 0x48414132
1212236082 found at offset: 60
gdb-peda$ pattern offset 2AAH
2AAH found at offset: 60
gdb-peda$

procinfo

Эта команда выводит информацию из директории /proc/pid/x напрямую в консоль:

gdb-peda$ procinfo
exe = /vagrant/lessons/3_intro_to_tools/build/1_sample
fd[0] -> /dev/pts/0
fd[1] -> /dev/pts/0
fd[2] -> /dev/pts/0
pid = 11038
ppid = 11028
uid = [1000, 1000, 1000, 1000]
gid = [1000, 1000, 1000, 1000]

Удобно зырить, какие дескрипторы открыты

vmmap

Данная команда отображает карту памяти процесса (memory mapping):

gdb-peda$ vmmap
Start              End                Perm	Name
0x00400000         0x00401000         r-xp	/vagrant/lessons/3_intro_to_tools/build/1_sample
0x00600000         0x00601000         r--p	/vagrant/lessons/3_intro_to_tools/build/1_sample
0x00601000         0x00602000         rw-p	/vagrant/lessons/3_intro_to_tools/build/1_sample
0x00007ffff7a0e000 0x00007ffff7bcd000 r-xp	/lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7bcd000 0x00007ffff7dcd000 ---p	/lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dcd000 0x00007ffff7dd1000 r--p	/lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dd1000 0x00007ffff7dd3000 rw-p	/lib/x86_64-linux-gnu/libc-2.23.so
0x00007ffff7dd3000 0x00007ffff7dd7000 rw-p	mapped
0x00007ffff7dd7000 0x00007ffff7dfd000 r-xp	/lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7fec000 0x00007ffff7fef000 rw-p	mapped
0x00007ffff7ff6000 0x00007ffff7ff8000 rw-p	mapped
0x00007ffff7ff8000 0x00007ffff7ffa000 r--p	[vvar]
0x00007ffff7ffa000 0x00007ffff7ffc000 r-xp	[vdso]
0x00007ffff7ffc000 0x00007ffff7ffd000 r--p	/lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7ffd000 0x00007ffff7ffe000 rw-p	/lib/x86_64-linux-gnu/ld-2.23.so
0x00007ffff7ffe000 0x00007ffff7fff000 rw-p	mapped
0x00007ffffffde000 0x00007ffffffff000 rw-p	[stack]
0xffffffffff600000 0xffffffffff601000 r-xp	[vsyscall]
gdb-peda$

Из важного, стоит обратить внимание на флаг дотсупа к сегментам памяти. Очень часто при разработке эксплойта нужно размещать всякие разные данные: шеллкод, указатели и всякое такое. В таком случае нужно убедиться, что область памяти доступна для записи.

find aka searchmem

Команда find служит для поиска нужного паттерна в памяти.

Например, часто встречается строка “/bin/sh”. Давайте попробуем найти её при помощи команды find:

gdb-peda$ find /bin/sh
Searching for '/bin/sh' in: None ranges
Found 1 results, display max 1 items:
libc : 0x7ffff7b9a177 --> 0x68732f6e69622f ('/bin/sh')
gdb-peda$
Очень злой админ
Очень злой админ Автор статьи

Админ сайта. Публикует интересные статьи с других ресурсов, либо их переводы. Если есть настроение, бывает, что пишет и что-то своё.

Leave a Reply

Your email address will not be published. Required fields are marked *