rop
FB招聘站
分类阅读
专栏
公开课
FIT 2019
企业服务
用户服务
搜索
投稿
登录
注册
WIN10下ROP初体验 与非门salome2016-09-30现金奖励共251204人围观 ,发现 6 个不明物体 新手科普系统安全
* 本文原创作者:与非门salome,本文属FreeBuf原创奖励计划,未经许可禁止转载
首先,在windows10下编写一个具有一定安全机制但又存在漏洞的程序作为实验。接着通过一定的分析,编写出能够成功反弹shell功能的漏洞程序。
值得说明一下的是,本次的实验环境是Windows10 x64版本,漏洞程序为32位程序,关闭gs代码生成选项(以便去除干扰文章重点rop的因素),开启DEP (数据执行保护)。
首先需要说明几个概念以及本文的意义。DEP基本可以理解为让能够执行代码的内存区域执行指令,而不具有执行特性的内存区无法执行指令(硬件DEP主要通过页表项的特殊位来指示),如果在不可执行的区域执行了这些指令,那么便会抛出异常。当然在Windows中支持硬件DEP的话,其也是可以被配置的。配置选项有AlwaysOn,AlwaysOff,OptIn,OptOut 。在MSDN的详细说明如下图。
Clipboard Image.png
我们尝试将普通的shellcode(jmp esp地址写入函数返回地址达到控制),确实我们转入了shellcode的布置空间,但是我们执行第一个熟悉的shellcode,我们便无法执行了,理所当然,我们的程序抛出了异常。
Clipboard Image.png
由于上述安全机制的存在,那么我们就不能直接把shellcode放在栈种控制程序的流程。所以我们需要一些手段。本文中将会展示2类方法绕过DEP,但其核心都是ROP(返回导向编程的思想)。
先不急,我们来看漏洞实验程序。由于这是一个漏洞程序,我们直接看存在栈溢出漏洞的程序,非常简单,一个有限空间的栈上分配的数组允许使用者无限制的用户输入。
Clipboard Image.png
同时看到,这里的坏字节是\x00,所以我们的漏洞利用代码不能存在\x00的字节。这里我们开始一种漏洞利用程序的分析及编写。
攻击姿势1:
既然我们的栈中的数据不能被作为指令来被执行,但是我们可以把像ntdll.dll,kernel32.dll中我们需要的指令地址溢出并填充到栈中,ntdll.dll等模块中的多个组合的指令便就是我们的shellcode。其中ROP的形式为 retn结尾,以便能够在栈中依次执行rop 链中的每个gadget。
现在我们期望通过溢出布置WinExec来完成calc.exe的执行。我们的大致从低地址到高地址栈空间将会是如下。
WinExec
ExitThread
指向calc.exe位置
0×01010101
ret address
exitcode
calc
.exe
0xffffffff
WinExec的第一个参数指向栈高位置的calc.exe,因为如果放在相对存放WinExec地址栈位置的低地址的话,WinExec里的流程可能就会把calc.exe 冲刷掉,那么我们本期望指向calc.exe的指针指向不可预知的内容,那么WinExec将会失败。另外,calc.exe后跟的0xffffffff的意义是\x00是坏字节,我们不能在shellcode中存在\x00,而我们的calc.exe字符串必须后跟随一个\x00作为结束符。那么紧跟在上述栈结构的位置后面的是修正参数的一些指令。
使用WinDbg中的python插件mona生成一些关于rop有用的信息,命令的使用方法是先设置生成后文件的存放位置,如!py mona config -set workingfolder ” 你希望的位置”,再使用命令!py mona rop -m kernel32.dll,ntdll.dll,msvcr120.dll即在这3个指定的加载模块中搜索对rop有用的指令。由于修正shellcode的loader位于前面讨论的结构的下方,而且那个栈位置布置占9个栈空间,那我们需要9*4字节(32位漏洞程序每个栈位置占用的空间大小)=0x 24 字节的调整。我们打开之前在mona工作目录下的stackpivot.txt。但是发现没有直接add esp,0×24 retn的,所以选择导致栈位置调整0×28的add esp,0×24 pop ebp retn。其在MSVCR120.dll中,位置为MSVCR120 base+0x476c6中。
Clipboard Image.png
这个stackpivot操作对应在WinExec-ROP的低位置。然后我们开始了解一下WinExec和ExitThread 的RVA信息。WinExec位于kernel32.dll,将其拖入depends工具中。
Clipboard Image.png
通过depends工具查看kernel32.dll+0x3ff70的位置处。
ExitThread位于kernel32.dll中,但是该工具中发现其对应ntdll.dll中的RtlExitUserThread,也就是ntdll base+0x681b0。
Clipboard Image.png
现在再来回头看看之前描述结构对应的实体信息。
Clipboard Image.png
根据之前的分析,运行了第一个语句后,将会运行到在栈中定位到0xffffffff(add esp,0×24 pop ebp retn对应pop到ebp的值)后的一个地址进行retn。在这里我们先完成修正calc.exe字符串后的\x00的工作。其中,对应的工作就是得到当前的栈地址(每次运行时的栈位置各不相同),再根据该栈位置向低地址调整到需要被修改为0的0xfffffff地址处。所以我们需要类似push esp,pop reg32类型的指令。我们在生成的rop_suggestion.txt中我们看到如下几类指令(使用move esp ->搜索)。
Clipboard Image.png
我们先点击move esp->eax处查看一下对应指令的具体情况,我们截取了一小部分,可以发现并不适用,因为eax和esp交换了之后,eax的不确定性可能导致程序崩溃。
Clipboard Image.png
同样地,move esp->esi对应如下,以不确定的寄存器值作为寻址的决定因素是不可靠的,只能放弃。
Clipboard Image.png
经过一系列的排查后,发现少数能使用的语句如下:
Clipboard Image.png
如当使用第2个时,则不会存在访问违例的问题。但是mov esp,ebp则需要保证ebp的有效性,而在前面选择stackpivot时,我们选择了add esp,0×24 pop ebp完成了栈位置的跳跃,pop ebp我们由于不知道在对应栈的位置给ebp设置成什么值来匹配而设置成了0xffffffff。这也就违反了使用push esp,xor eax,eax……retn的mov esp,ebp问题。所以我们对前面的栈跳跃换选其他指令。我们尝试替换成如下。
Clipboard Image.png
但是,注意到move esp->edi的过程中,retn 后esp会进入ebp+4的位置也就是stackpivot的位置,而这里ebp我们同样无法正确设置(溢出后的ebp位置总是被我们的内容覆盖)。
所以我们还得不断替换现在的这个指令。继而选择move esp->edx类型的gadget。我们现在尝试把eax设置为为一个有效地址。
Clipboard Image.png
使用这个gadget时,注意需要在retn address前设置好pop ebp的位置。我们这里在运行时输入!dh kernel32,以查看其pe头部信息,因为mov [eax],al代表了需要该ebp位置需要可写(存在一处ebp eax交换的指令,而ebp我们可控,那么我们就能控制eax内容指向地址的可写性质)。
Clipboard Image.png
通过输入!dh 模块名的命令,可以看到.data段使具有可写属性的。所以设置kernel32.dll的偏移0xb0000处。但是\x00是一个坏字节,相应做一些修改即可(如0xb0101也在.data段范围内)。
现在经过这些处理,这里gadget使用的add byte ptr[eax],al便不会导致访问违例的异常了。
由于现在edx已经指向当前gadget的后4字节位置,所以还需要让edx向低地址移动。
可是我们搜索带有sub edx,imm 类型的指令并没有。只有sub eax,imm的类型。所以我们尝试将指向here的edx设置到eax中。
Clipboard Image.png
由于eax当前还和需要调整的calc.exe结尾的0xffffffff相差6*4的距离。所以使用SUB EAX,0×16 RETN和7次SUB EAX,2 POP EBP RETN组合调整到该位置。
现在我们目标将该dword大小的地址的低字节设置为0,我们在rop.txt里搜索mov dword ptr[eax]的gadget看看结果如何?
Clipboard Image.png
我们看到了一个mov dword ptr [eax],0xb5000000的指令感兴趣。只要低字节为0即可。
Clipboard Image.png
其位于ntdll+0x196cb处。至此,我们完成了修正rop链的第一步。
现在我们进入第二步,将WinExec的参数1指向calc.exe。别忘了,我们现在的eax位于calc.exe+0×8处哦。由于前面看到只有eax可以进行sub调整,所以我们将当前eax存储到其他寄存器中,并将eax调整到calc.exe的起始位置。我们使用下图的gadget将eax存储到ecx中。
现在我们进入第二步,将WinExec的参数1指向calc.exe。别忘了,我们现在的eax位于calc.exe+0×8处哦。由于前面看到只有eax可以进行sub调整,所以我们将当前eax存储到其他寄存器中,并将eax调整到calc.exe的起始位置。我们使用下图的gadget将eax存储到ecx中。
Clipboard Image.png
其位于ntdll.dll的0×21110处。之后,我们将eax向低地址推进8个字节的距离。我们依旧选取之前使用过的gadget(# SUB EAX,2 # POP EBP # RETN)。ecx在被设置为eax原值后和WinExec所需的_stdcall参数1位置相差0xc。我们理想中的gadget为mov [ecx+0ch],eax retn类型的。
Clipboard Image.png
非常幸运,我们在ntdll中找到了这个gadget。
Clipboard Image.png
接着最后一步我们需要调整esp使其进入WinExec的流程。
我们输入正则表达式mov esp,(?!ebp)来匹配直接对esp值设置的指令(由于mov esp,ebp的指令会很多)。
Clipboard Image.png
简单地发现了,ntdll.dll中存在mov esp,ebx pop ebx retn。这也就需要ebx在WinExec-0×4位置处才行。依据这些,我们寄希望ebx,能通过eax交换到ebx(因为能方便加减的寄存器为eax),所以我们尝试搜索,xchg eax,ebx mov ebx,eax等。我们看到了如下的结果。
Clipboard Image.png
比如针对前2条我们看到了mov esp,ebp的指令,之前由于一些gadget存在pop ebp,导致垃圾数据被填充到了ebp中。又如倒数第2句,ebx必然不为-2所以导致肯定会跳转导致崩溃。
所以,我们在文本编辑器中继续输入正则表达式xchg (.*?),esp时发现了直接将eax,设置到esp的指令。位于ntdll偏移0x916c9。
Clipboard Image.png
这下好办了,我们在最下方部署gadget1:调整eax到rop链中的WinExec类似add esp,xx;gadget2:设置eax到esp如xchg eax,esp。便成功异常绕过dep并通过rop弹出了计算器。
Clipboard Image.png
攻击姿势2:
绕过DEP的方式各版本系统有VirtualProtect设置shellcode所在内存页面为可执行;使用VirtualAlloc存在执行权限的内存页;使用HeapCreate+HeapAlloc分配有执行权限的堆。
而如一些其他的公布的绕过方式中,有些方式的限制较多。如SetProcessDEPPolicy设置当前进程的限制仅能为32bit的程序且系统DEP选项不能为AlwaysOn以及调用过SetProcessDEPPolicy的程序。
如NtSetInformationProcess同样对AlwaysOn的无效以及对NtSetInformationProcess调用过的程序无效。
对于使用VirtualProtect的情况,我们只需要对shellcode范围内的地址设置为0×40(PAGE_EXECUTE_READWRITE)便可以使用之前的方式调用shellcode了。
Clipboard Image.png
在生成的rop_chain.txt可以看到python版的VirtualProtect的绕过实现。
Clipboard Image.png
现在,我们开始对这个自动生成的shellcode进行改造,因为它包含了一些空字节以及未使用base+rva的表示方式导致了ASLR被允许的情况下的无法运行。
可以观察到最后第二句为pushad retn的指令,这里我们补充一下PUSHAD/POPAD将EAX ECX EDX EBX ESP(该指令执行之前的初始值) EBP ESI EDI分别出入堆栈。所以大致上这个rop chain的做法是设置好对应寄存器在压栈时位置对应的参数和地址pushad retn以进入Virtual Protect将shellcode范围设置为可执行,之后直接跳入shellcode中。
edi nop retn的地址
esi jmp [eax]的地址
ebp pop retn的地址
esp LpAddress
ebx dwSize
edx NewProtect
ecx lpOldProtect
eax dll中存放VirtualProtect的iat
jmp esp的地址
第一步使ebp指向pop retn的指令搜索# pop ebp # retn。
设置完ebp->pop retn后,我们开始设置ebx为0×400,即VirtualProtect的dwsize为0×400(1k)大小,由于存在本程序的坏字节0×400,我们构造2个相加为0×400的数这里我们使用0x1111221f和0xeeeee1e1,分别通过如pop ebx,retn等设置到ebx和ecx后转入add ebx,ecx retn。
使用相同的办法我们使得edx(NewProtect)为0×00000040。只是需要注意我们相加使用edx和另外的一个寄存器,ebp,ebx都使用过了我们需要选择其他的。这里我们输入正则表达式add edx,e\S\S #retn的指令 发现只有较少的指令与edx有相加的操作,并且普遍都是edi寄存器。
对于ecx需要设置为填充lpOldProtect即out 原先保护熟悉的地址。我们这里设置一个可写的地址即可。
Clipboard Image.png
即kernel32.dll+0xb0b38处。
Clipboard Image.png
通过windbg使用!dh kernel32命令看到其实这里就是一个.data段的地址,确实可写。
现在我们让esi指向jmp [eax],其位于ntdll.dll偏移0x00042cde,注意这里的eax会指向某个模块中virtualprotect(KERNELBASE.dll)的IAT。
最后我们需要布置lpaddress对应的esp由于我们需要设置的是栈中可能动态变化的shellcode的位置。比较技巧的是,由于esp提供lpaddress,在pushad retn后对应virtualprotect也将会在附近。所以无需我们手工再次专门设置esp。
最后的成功溢出执行代码的效果便是连接本地的1514端口反向shell。
本次实验测试内容包括漏洞程序工程、2类漏洞编写程序工程等(系统版本不同可能需要自行修改漏洞利用程序中的部分编码才能成功运行)。
内容可以通过链接:http://pan.baidu.com/s/1pLs6m2v,密码:p5um进行下载。
* 本文原创作者:与非门salome,本文属FreeBuf原创奖励计划,未经许可禁止转载
与非门salome
与非门salome
2 篇文章
等级: 2级
||
上一篇:解包分析攻击越南机场和其它组织机构的间谍程序下一篇:这个恶意软件“奇葩”的反虚拟机技巧
发表评论已有 6 条评论
_等一分钟 2016-09-30回复 1楼
Mark
亮了(0)
死宅10086 (7级) 2016-09-30回复 2楼
亮了(1)
LeonChan (1级) 2016-09-30回复 3楼
goog job
亮了(0)
lzldhu_oreo (1级) 2016-09-30回复 4楼
更新过了会有些变化
亮了(1)
x565178035 (2级) 2018-01-09回复 5楼
链接坏了 可以补上嘛?
亮了(1)
elli0tn0phacker (2级) 2018-02-26回复 6楼
“由于eax当前还和需要调整的calc.exe结尾的0xffffffff相差6*4的距离。所以使用SUB EAX,0×16 RETN和7次SUB EAX,2 POP EBP RETN组合调整到该位置。”
应该是1次SUB EAX,2 POP EBP RETN吧
亮了(2)
昵称
请输入昵称
必须您当前尚未登录。登陆?注册邮箱
请输入邮箱地址
必须(保密)表情插图
有人回复时邮件通知我
与非门salome
与非门salome
这家伙太懒,还未填写个人描述!
2
文章数
1
评论数
最近文章
点融招聘安全人才
2018.02.01
WIN10下ROP初体验
2016.09.30
浏览更多
相关阅读
BUF 早餐铺 | Ubuntu 18.04 正式版发布,针对安全性优化;Win10被指非法收集数据,微软恐面临287万美金罚款;谷歌帐户获得新的验证功能 以防止网络钓鱼攻击;疑似与朝鲜相关的黑客盗取17个国家的数据技术讨论 | Windows全版本提权之Win10系列解析技术讨论 | Windows 10进程镂空技术(木马免杀)巴西检方起诉Win10非法收集数据,微软恐面临287万美金罚款动手打造Bypass UAC自动化测试小工具,可绕过最新版Win10
特别推荐
关注我们 分享每日精选文章
活动预告
11月
FreeBuf精品公开课·双11学习狂欢节 | 给努力的你打打气
已结束
10月
【16课时-连载中】挖掘CVE不是梦(系列课程2)
已结束
10月
【首节课仅需1元】挖掘CVE不是梦
已结束
9月
【已结束】自炼神兵之自动化批量刷SRC
已结束
FREEBUF免责声明协议条款关于我们加入我们广告及服务寻求报道广告合作联系我们友情链接关注我们
官方微信
新浪微博腾讯微博Twitter赞助商
Copyright © 2018 WWW.FREEBUF.COM All Rights Reserved 沪ICP备13033796号
css.php 正在加载中...0daybank
文章评论