Windows 存储设备栈分析

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

 

通常为了实现某些与存储防护相关的功能,需要得到诸如volume/partition/class/port/miniport等设备,在客户端由于环境相对固定,所以可以假定驱动名为volmgr.sys (ftdisk.sys)/partmgr.sys/disk.sys/atapi.sys或scsiport.sys,但由于RAID、MPIO等应用和第三方厂商的介入,这种假设并不适用于Windows服务器,如symmpi.sys或是 Windows 2003 Server 后基于storport.sys 的 lsi_sas.sys 等。为了在Windows 服务器上保持良好的兼容性,就需要找到一种不依赖“驱动名称”和“设备名称”,可动态识别和定位的方法,同时要能够定位在“存储栈”中任意位置的存储设备,也就是需要从文件系统开始,依次定位“卷设备->分区设备->类驱动设备->小端口设备”,这需要跨越多个存储设备栈,我们的方法是跟踪DEVICE_OBJECT中StackSize的变化,这个值得变化表明一个IRP在存储设备栈中的走向和整体流程,此值为1表明IRP消亡,即再往下层设备传递时,不再以IRP形式发送。

 

这里以Windows 2008 R2为测试环境进行调试。通过DeviceTree观察,发现从NTFS文件系统开始其DeviceObject->StackSize为8 (如果上面还有Upper Filter Driver 此值还会更大),再往下查看发现除了设备的AttachedDevice域可以确认有上层设备(Upper Filter Driver)之外无法查看到其低层设备(Lower Device)同时也无法完成全部的跟踪,中间的StackSize总有不连续的地方。也就是说DeviceTree提供的信息不够详尽,无法以此写出符合要求的代码。

 

在这种情况下我尝试翻阅WDK,看看能否找到些线索,终于让我找到了一个内核API: IoGetDiskDeviceObject(),从说明中可以看到此函数返回的磁盘设备对象是一个“卷设备”,那么它是如何通过文件系统设备对象获得的?这也正是DeviceTree没有给出的信息。

 

通过WINDBG对此函数进行逆向分析:

 

kd> uf IoGetDiskDeviceObject

nt!IoGetDiskDeviceObject:

fffff800`0178c810 48895c2410      mov     qword ptr [rsp+10h],rbx… 阅读全文

Posted on 一月 19, 2015 at 下午1:38 by admin · Permalink · Comments Closed
In: 未分类

AIX 系统调用拦截函数 kmod_util() 的实现原理与BUG

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

 
环境:
bash-3.2# oslevel -r
6100-06

使用 kdb 调试器分析

bash-3.2# kdb
START              END <name>
0000000000001000 00000000040F0000 start+000FD8
F00000002FF47600 F00000002FFDF9C0 __ublock+000000
000000002FF22FF4 000000002FF22FF8 environ+000000
000000002FF22FF8 000000002FF22FFC errno+000000
F1000F0A00000000 F1000F0A10000000 pvproc+000000
F1000F0A10000000 F1000F0A18000000 pvthread+000000
read vscsi_scsi_ptrs OK, … 阅读全文

Posted on 一月 19, 2015 at 下午1:30 by admin · Permalink · Comments Closed
In: 未分类

AIX Hardware Storage Keys 调试

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

为了通杀所有 POWER AIX 系统,我的代码都是在最低平台和版本上进行编译的,如 POWER5 的 AIX 5300-00,为了向后兼容使用了解析内核镜像文件,动态获得函数及结构的方法,但这也带来了一些问题。比如 POWER6 后提供的 Hardware Storage Keys,在此平台编译使用没有任何问题,但拿到 POWER7 上则出现了崩溃现象,但将代码在 POWER7 上编译则没有任何问题,我查了编译选项没有使用任何优化参数,最终当我定位问题后不得不再次感叹,对这种硬件,OS,编译器都是自己的大型封闭系统真是没的治。

KDB(0)> dis @r0 – 4 10

.aix_kernel_get_diskdev+0002C4 bl <.new_hkeyset> –>调用new_hkeyset崩掉的,这是我写的包装函数。

.aix_kernel_get_diskdev+0002C8 ori r0,r0,0

.aix_kernel_get_diskdev+0002CC ld r3,90(stkp)

.aix_kernel_get_diskdev+0002D0 bl <.kputpath>

.aix_kernel_get_diskdev+0002D4 lwa

阅读全文
Posted on 一月 19, 2015 at 下午1:24 by admin · Permalink · Comments Closed
In: 未分类

PHP获取X-Forwarded-For值的有趣现象

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

 

今天发现了PHP一个有趣的现象,就是关于X-Forwarded-For这个值获取的方式。
关键字X-Forwarded-For是HTTP的一个扩展字段,有的Web程序就会使用这个字段获取用户的真实IP,类似下面的代码:
$ip = $_SERVER[‘HTTP_X_FORWARDED_FOR’];
而程序在后面如果不检查$ip这个变量的值而直接带入select进行数据库查询,就可能会造成SQL注入攻击点,如很老版本的discuz论坛就存在这种类型的注入。
PHP在接收HTTP_X_FORWARDED_FOR内容的时候很有意思,也可以说容错性非常高,客户端在发送的时候在X和FORWARDED和FOR之间的分隔字符可以是任意可显示的特殊字符,如下面HTTP请求:
GET /test.php HTTP/1.1
Host: 192.168.200.101:81
Proxy-Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
X-Forwarded!For:8.8.8.8… 阅读全文

Posted on 一月 10, 2015 at 下午4:19 by admin · Permalink · Comments Closed
In: 未分类

某EXCEL漏洞样本shellcode分析

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

起因

近日我得到一个EXCEL样本,据称是一个过所有杀软的0day,经过分析之后让我大失所望,这是一个2012年的老漏洞,根本不是0day。虽然没捡到0day,但是这个样本中的shellcode还是相当有特色的,确实可以绕过大多数的杀毒软件和主动防御。
下面就来分析一下这个EXCEL EXP所使用漏洞和shellcode技术。

漏洞分析

该漏洞是CVE-2012-0158,一个栈溢出漏洞,漏洞成因是MSCOMCTL.OCX在解析一个标志为Cobj的结构的时候直接使用文件内容的数据作为拷贝长度,导致拷贝数据的时候可以覆盖函数返回地址,造成了一个标准的栈溢出漏洞。

275C876D 55 push ebp
275C876E 8BEC mov ebp, esp
275C8770 51 push ecx
275C8771 53 push ebx
275C8772 8B5D 0C mov ebx, dword ptr [ebp+C]
275C8775 56 push esi
275C8776 33F6 xor 
阅读全文
Posted on 十二月 16, 2014 at 下午7:22 by admin · Permalink · Comments Closed
In: 未分类

某安全软件ROP防护分析笔记

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

原理

ROP是用来绕过DEP防护的常用方法, 攻击者通常会利用ROP链将真正的ShellCode拷贝到一个具有可执行权限的内存处并执行。为了达到这个目的,攻击者会使用一些类似VirtualAlloc这样的API进行分配或修改内存的属性。而这些函数是有限的,并且最终都会进入内核,某安全软件通过在内核层拦截这些关键函数,在关键函数内根据从当前线程获取到的陷阱帧拿到返回用户层时的调用栈信息。通过对关键函数调用栈的每一层栈帧进行检查,以此来进行ROP检测。

实现

在关键函数内首先进行Stack Pivot检查
栈置换利用类似下面的指令序列

xchg eax, esp 
retn

检测方法:如果调用 关键函数时, esp 指针不在用户空间栈范围内,则说明进行了栈置换。
绕过栈置换方法:首先通过简单的ROP链来调整原栈空间,将 包含关键函数操作的ROP链 拷贝到原栈空间,此时再利用栈置换重新将esp指向调整后的原栈空间,继续执行ROP链,可绕过此处的栈置换检测。
检测代码实现:

if ( func_switch & STACK_PIVOT )            // 栈置换攻击防护
{                                       
      if ( _teb->FiberData < 0x10000 )
      {
        if 
阅读全文
Posted on 十二月 8, 2014 at 下午4:02 by admin · Permalink · Comments Closed
In: 未分类

绕过百度杀毒溢出保护的一些方法

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

背景

前段时间参加了http://xp.erangelab.com/举办的XP挑战赛,把绕过一些安全防护软件的过程和大家分享一下。

其中百度杀毒的测试版本为1.8.14.1

使用的IE漏洞

由于比赛系统为XP SP3 +IE8未打任何其他补丁,所以从IE漏洞选取了CVE 2012-1889、CVE 2012-4969、CVE 2013-1347,原因就是这三个能在网上找到现成的exp,后来证明多找几个漏洞还是很必要的,因为适应各种突发变化。

百度防护手段

防堆喷射

这几个漏洞本身没什么可说的,拿到1889就开始在百度卫士上开测,直接IE加载exp,没有成功IE崩溃,这是必然的嘛,要不然还叫什么保护。因为yuange、tk等高人说的DVE技术我还没有学会,所以还是用被大牛们淘汰的堆喷射,用vmmap打开IE进程,发现堆喷的地址都被占位了:

spray1

这就是传说中的占坑,0C0C0C0C这种地址都被占了,这样我们堆喷的时候当然就占不到这个位置了。但是,事实证明这种方法对于防护堆喷射一点作用都没有,我不知道做这个功能的人自己试验了没有,在提前占坑的进程中堆喷射,喷射完成后内存布局是这样的:

spray2

可以看到除了开始的4K以外,后面该喷射占用的内存还是一样占用了,0C0D0000里面照样是我们的的shellcode,我们利用的时候直接用0C0E0C0C这个地址就好了,保证是成功喷射的,所以占坑这招只要改个地址就可以破解了。百度和金山都用了这种占坑的方法,而事实证明这种做法根本没有任何意义,而金山的实现更差,用explib直接喷射仍然占了0C0C0C0C。现在精确堆喷射的技术已经很成熟了,这方面不再多做介绍。

ROP

因为XP SP3上是没有ASLR的,因此我们只要ROP绕过DEP就可以了,喷射成功之后,就成功来到了shellcode中,但还是被百度报了ROP攻击,当然大牛们可以用DVE技术,但是咱还没学会不是,还是老老实实看看ROP怎么绕过保护。网上找的原始exp里的ROP是用VirtualProtect,跟踪发现调用这个API的时候被百度拦截了,于是要找其他的ROP,打开immunity debugger,用mona插件(https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/)找了几种不同的ROP,经过修改调试之后,在百度环境下测试发现VirtualAlloc没有被百度拦截,终于成功进入了真正的shellcode,不过最后一天百度升级补了此方法,最后没有用这种方法,后面绕过的方法随后再介绍。下面是VirtualAlloc的ROP:

var rop_chain = unescape(
"‰uBE4C‰u77BE" + // 0x77BEBE4C # retn [msvcrt.dll]
"‰uBE4B‰u77BE" + // 
阅读全文
Posted on 十一月 7, 2014 at 上午11:13 by admin · Permalink · Comments Closed
In: 漏洞分析

安全输入控件分析

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

 

随着B/S技术的发展当浏览器(如IE)中需要输入用户名和密码,而这个密码又和经济挂钩的时就产生了安全输入控件,安全输入控件通过软件技术实现了对用户密码的保护,使得攻击者无法通过键盘记录、输入框内容查看等技术得到用户输入的密码,保证用户的密码不被攻击者非法获得,目前安全输入控件技术被网上银行等广泛使用。

那么安全控件是否真的可以完全阻止黑客的攻击呢?应该是不行的。

在IE下,安全输入控件是一个ActiveX控件,而ActiveX使用了COM接口技术, COM接口是Windows的一项重要技术,Microsoft的许多技术都用到了COM接口,如ActiveX、DirectX等。

现在想通过传统的办法获取安全输入控件的内容是不行的,那么是不是可以通过COM接口做一些工作呢?当用户在安全输入控件中输入内容时是明文,控件内部会对用户输入的明文进行加密然后发送到服务器,如果能知道控件在那个函数处理的这部分工作应该可以获取明文内容的,下面就尝试通过COM接口的Hook技术找到这个函数。

与传统的API HOOK不同,所有的COM接口都是由一个虚函数表组成(vTable),虚函数表的内容为成员或函数地址,是纯地址列表。当调用IDispatchEx类的成员函数时也包括其派生类函数,程序会通过该函数地址列表找到函数的真正地址并进行调用。那么我们可以通过修改该地址列表,来达到拦截指定函数的目标。而Windows系统通过函数DispCallFunc来实现所有COM接口成员函数的分发,我们可以通过Windbg来挂钩OLEAUT32! DispCallFunc函数来观察COM接口的分发调用过程。

那么如何获得一个具体COM接口的虚函数表呢?我们可以通过CoCreateInstance函数获取虚函数表,但在IE中,其调用ActiveX控件时通过CoGetClassObject函数来获得虚函数表,所以,我们只要在不同的情况下Hook这2个函数,就可以获得指定COM接口的虚函数表。了解了COM接口的原理后,现在开始找一个目标,在很随机的情况下,我选择了一个银行的安全输入控件做测试。

首先,对IE里面加载的模块进行观察,找到安全输入控件的文件,如下图:

comi1

从这个图里面就可以发现xxxEdit.dll不是IE默认的DLL,应该就是银行的安全输入控件,首先获取此DLL的CLSID。然后注入代码到IE进程,对CoGetClassObject函数进行Hook,通过比较CLSID,确认获取安全控件的虚函数表地址(vTable)。

获取到接口的vTable后,现在就可以Hook接口的具体函数了,接着Hook成员函数CoGetClassObject:: CreateInstance,获得安全输入控件的方法vTable地址为0x10045220。

对比xxxEdit.dll的反汇编代码,可以看到这个COM接口提供的所有方法和属性,如下图:

comi2

查看银行的网页源代码可以发现JavaScript从安全控件获得卡号和密码的方法是:

loginInfo.AccountNo = document.getElementById(“DebitCardNo_Ctrl”).IValue;

loginInfo.Password = document.getElementById(“DebitCardQueryPwd_Ctrl”).IValue;

于是,开始分析10011521这个函数,发现执行到1001160F前ECX的值正好是卡号和密码的明文,这样攻击者可以要获得安全输入控件的内容只需要远程注入代码到IE中并inline Hook这个地址,获取ECX的值,就可以获得明文的卡号和密码。

可见,安全输入控件并不是绝对的安全,所以,为了尽可能的避免这样的情况发生,我们应该养成良好的上网习惯,包括:

 阅读全文

Posted on 十一月 6, 2014 at 下午1:02 by admin · Permalink · Comments Closed
In: 未分类

ASP下一句话木马的动态拦截技术

作者:椒图实验室

转载请注明出处:http://blog.jowto.com

        一句话木马如<%eval request(“MH”)%>,攻击者通过组织好的参数访问木马,就可以让参数中的恶意脚本在服务器端执行。为了防止执行恶意脚本,可以在IIS脚本引擎中拦截EVAL函数来过滤非法请求。

以下分析都在windows server 2003 x86下调试:
w3wp.exe是在IIS(Internet Information Server)与应用程序池相关联的一个进程,如果你有多个应用程序池,就会有对应的多个w3wp.exe的进程实例运行。当需要解析ASP脚本时会加载vbscript.dll,通过IDA搜索vbscript.dll中和“eval”有关的函数,找到

VbsEval(VAR *,int,VAR *) .text 7337da95

在windbg中调试发现脚本执行Eval函数时都会调用到VbsEval,见下图:
URL:

localhost/test.asp?MH=1*2

test.asp:

<%eval request("MH")%>

windbg:

image001

在内存中可以看到eval函数执行的脚本。现在只需要将此脚本与URL中请求参数内容对比,如果内存中执行的EVAL脚本在URL中存在则可以认为是URL请求试图调用一句话木马并执行。如上图截取的底层执行代码为1*2,判断1*2是否在localhost/test.asp?MH=1*2中存在,如果存在则直接返回恶意代码提示,最终效果如下图:

image003

HOOK住vbscript!VbsEval很容易截取到要执行的脚本,现在的问题是任何脚本执行eval都要调用vbseval函数,那么怎么才能找到当前执行脚本是由哪个URL触发的呢?如果无法取到URL则不能与EVAL中执行脚本对比,过滤是无从谈起的。

现在从vbseval函数往上看整个脚本解释执行的流程!

image005下asp!CViperAsyncRequest::OnCall断点,堆栈回溯如下:

image007

可以看出脚本执行eval函数是通过启动线程调用回调函数来触发的。但是下新建线程的API都断不下来,需要换个思路。通过上图可以看到线程启动后最先执行函数是asp.dll里的asp!CViperAsyncRequest::OnCall,查看asp.dll的导出函数如下图:image009

通过这3个导出函数可以判断asp.dll是ISAPI中的ISA。ISA简介如下:

ISA(Internet Server Application)也可称为ISAPI DLL,其功能和CGI程序的功能直接相对应
,使用方法和CGI也类似,由客户端在URL中指定其名称而激活。

ISA和服务器之间的接口主要有两个:GetExtentionVersion( )和HttpExtentionProc( )。任何
ISA都必须在其PE文件头的引出表中定义这两个引出函数,以供Web服务器在适当的时候调用。
ISA大概工作流程如下:

1、当服务器刚加载ISA时,它会调用ISA提供的GetExtentionVersion( )来获得该ISA所需要的服
务器版本,并与自己的版本相比较,以保证版本兼容。… 阅读全文

Posted on 十一月 5, 2014 at 下午2:04 by admin · Permalink · Comments Closed
In: Web安全
友情链接