
32비트 아키텍처에서 작동하는 서버의 프로그램을 익스플로잇한다.

버퍼에 128바이트를 할당했다. 문자열은 gets 로 받는다.
read_flag() 가 존재하는 것을 보아 저걸 실행 시키면 되는 듯하다.
gets 함수의 인자로 전달되는 것은 메모리 주소 값이다. 엔터(\n)가 입력될 때까지 입력한 값들을 인자로 주어진 메모리 주소에 저장한다.

값을 입력해보면 오버플로우 취약점이 존재하는 것을 확인할 수 있다.

코어 덤프를 확인하려 했는데 그새 리눅스가 꺼졌던 탓인가, ulimit가 0으로 설정되어있어서 다시 풀어주었다.
근데 주어진 프로그램에 디버거를 쓰면 된다는 것을 깨달아서 ... 프로그램을 확인해줍니다.

disass main으로 어셈블리어를 출력하면, ebp-0x80이 buf의 주소인 것을 확인할 수 있다.
구조는 다음과 같을 것이다.

buf에 쉘코드와 더미데이터, SFP에 더미데이터를 집어넣고 RET에 read_flag()의 주소를 집어넣어서 흐름을 조작한다.
read_flag의 주소는 0x80485b9이다.




참고로 xxd -p <파일명>으로 -p 옵션을 쓰면 값이 모두 연결?되어서 나온다.

위의 코드에서 널코드를 잘못 입력했던 것 같다.
\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80

쉘코드 실행해서 함수를 실행한다?고 생각하고 있었는데
그냥 함수만 실행하면 되는 것이었다.
목적은 프로그램 안에 함수가 존재하기 때문에 굳이 쉘코드를 만들어서 쉘을 얻을 필요가 없는 것이다.!!!!

다시 추측한 대로 구조를 생각해보면 위와 같다. buf에도 그냥 더미데이터만 채우고, RET에 read_flag() 주소를 주면 함수가 작동하여 플래그를 얻을 수 있을 것이다.


symbol이 남아있을 경우 pwntool로 주소를 바로 가져올 수도 있다.
e = ELF("<파일명>")
e.symbols["<함수명>"]

'Write-up > DreamHack' 카테고리의 다른 글
| ssp_001 (0) | 2026.05.19 |
|---|---|
| Return to Shellcode (0) | 2026.05.18 |
| basic_exploitation_000 (0) | 2026.05.17 |
| Return Address Overwrite (0) | 2026.05.16 |
| shell_basic (0) | 2026.05.13 |