binee::
[sCTF 2016] pwn2 write up 본문
pwn2는 remote buffer overflow 정석 문제였다.
개인적으로 remote buffer overflow 연습용 문제로 딱인 것 같다.
이 문제도 마찬가지로 워밍업으로 가볍게 풀었다.
Binary 분석
pwn2 바이너리를 확인 해보면
pwn2: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=4b6d53bc9aca0e73953173f153dc75bd540d6a48, not stripped
위와 같이 32bit elf 파일이고, stack canary가 없는 것을 확인 할 수 있다.
이 문제도 마찬가지로 buffer overflow 느낌이 팍팍 온다.
Program Logic 분석
.
IDA로 확인해보면 main함수에는 vuln()함수를 호출하는 것 외에 별거 없다.
아래는 vuln함수의 hex-xay 결과다.
기능을 간단히 요약하자면,
내가 쓰고 싶은 길이 값을 지정해서 문자열을 쓰면, echo 서버처럼 그대로 따라 출력하는 바이너리이다. 기능자체는 심플하다.
자세히 살펴보면 get_n 함수를 통해서 앞으로 입력할 문자열의 길이를 입력하는데,
최대 4 글자까지만 입력이 가능하므로 9999가 최대 값이다.
그리고 atoi함수를 이용해서 문자열로 표현된 숫자를 정수형으로 변환해준다.
정수형으로 변환된 값이 32보다 크면 사이즈를 초과했다고 알려주면서 종료한다.
따라서 최대 입력 할 수 있는 길이를 32글자로 제한하고 있다.
버퍼의 크기는 32byte이므로 겉으로 보기에는 buffer overflow가 발생하지 않는다.
get_n함수를 살펴보면 getchar를 통해서 두 번째 인자로 전달 된 정수값만큼
한글자씩 입력받는다.
Exploit
이 문제도 아는 사람은 금방 찾겠지만,
문자열 길이를 체크하는 변수의 타입을 볼 줄 아느냐가 중요한 문제이다.
vuln함수에서 get_n함수를 통해서 앞으로 입력 할 문자열의 길이를 입력받는다.
그리고 이를 atoi로 정수로 반환하여 v2에 저장한다.
v2의 자료형 int형이므로, 음수와 양수를 표현하는 변수이다.
따라서 길이값이 음수면 if(v2<=32) 조건을 무조건 통과한다.
하지만 이 문자열의 길이값이 get_n함수로 넘어가면
unsigned 자료형인 a2로 넘어가는 것을 확인 할 수 있다.
음수 값은 2147483648부터 4294967295으로 표현되는데,
부호가 없는 unsigned int형인 a2는 2147483648 이상 값을 입력 받을 수 있다.
결국 겉보기에는 buffer Overflow가 발생하지 않았지만
자료형 타입 문제로 취약점이 발생하게 됐다.
그 뒤로 exploit 과정은 RTL chain을 통해서 libc leak을 하여
라이브러리 주소를 알아낸다.
그리고 다시 vuln함수를 호출해서 system("/bin/sh")를 실행하는 RTL을 하면 된다.
exploit 코드는 아래와 같다.
'CTF' 카테고리의 다른 글
[Plaid CTF 2016] butterfly write up (1) | 2016.04.21 |
---|---|
[sCTF 2016] pwn3 write up (0) | 2016.04.21 |
[sCTF 2016] pwn1 write up (0) | 2016.04.19 |
[Codegate 2016] oldschool write up (2) | 2016.04.19 |
[Codegate 2016] manager write up (0) | 2016.04.02 |