白盒法和IDA分析漏洞 |
“大家用Fuzzer分析warFTP怎么样啊? ”老师进入教室后问道。\
“Fuzzer太好用了! ”古风说道。 👩👚🎷🤐🖕 “是啊,Python也是,方便的定位出USER 485的地方是溢出点! ”玉波说道。 “嗯,不错,那漏洞分析呢? ”老师问道。 大家互相望了望,谁都没调出来。 🧑🎤🩴✏😴🖕 “老师,那个方法不管用啊! ”宇强鼓足勇气说道,“被中断的地方太多了,不能在发生溢出的前方中断 下来。而且我们又要考试了,没有太多的时间进行调试啊!” “是啊!”大家都很赞同宇强的说法。 🩳📀😀🤳 “好的,这节课是本学期最后一次课了。在黑盒法分析失效的情况下,我们可以使用白盒法辅助分析漏洞。 白盒法测试 “白盒测试也称结构测试或逻辑驱动测试,它知道产品内部工作过程,通过测试来检测产品内部动作是否按照规格说明书的规定正常进行。它检验程序中的每条通路是否都有按预定要求正确工作。” 👨🚒🦺🪟😂🧠 小知识:白盒法测试 白盒法全面了解程序内部逻辑结构,对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。白盒测试的主要方法有逻辑驱动、基路测试等。 “白盒法也不能‘证明’一个程序是‘正确’的! ”老师补充道,“贯穿程序的通路是天文数字,而且即使每条路径都测试了,仍然可能有错误。第一、穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。第二、穷举路径测试不可能查出程序中因遗漏路径而出错。第三、穷举路径测试可能 发现不了一些与数据相关的错误。” “老师,还是快说说漏洞分析吧!”台下焦急的说道。 ✊🗼🥩🈴🦬 IDA帮助分析warFTP漏洞 “好,我们在IDA的帮助下来分析warFTP的漏洞吧!” 👊🚘🥑⁉🦬 “IDA是强大的反汇编工具,不仅可以给出反汇编代码,还可以在我们的指引下主动进行一些分析;而且可以写些脚本IDC来进行自动分析。IDA是白盒法测试时必用的工具!” “打开IDA后,选择‘open’,打开warFTP.exe程序就开始分析反汇编了。” 🤛🏠🍧🆗🦮 “等一会儿分析完毕后,在‘Function’ 一栏可以直接看到调用的函数,包括MFC的函数名都可清楚的分析出来。”大家看了看下图,果然如此! ![]() 👩✈️💄📟👃 “我们想一下,warFTP是因为我们的过长字符串才引发的溢出;而且是远程溢出;所以……”老师慢慢的 说,“一定是通过网络,warFTP接收了我们的过长字符串才引起的溢出。” “嗯! ”大家点点头。 “一般的网络编程,百分之九九都是用Socket来完成的。warFTP接收我们的字符串,应该就是通过……” “哦! 一定是使用Socket,用recv或类似函数来完成的吧! ”宇强抢着说道。 🧑🍳🕶🛋🥱🖕 “对!我们看看IDA的‘function’那一栏,查看Socket相关的函数。发现了 MFC的CAsyncSocket ::Receive 函数,那是MFC封装的用于接收网络数据的函数,其位置在0x004345B8。” text:004345B8 ; public: virtual int 一thiscall CAsyncSocket::Receive(void *, int, int) 小知识:MFC 微软基础类库,是微软对Windows API的再次封装,期望简化编程的复杂度,提高软件开发效率并减 少软件成本。 👃🚂🎂☯🐶 “经过白盒法的辅助分析后,我们得到了关键的启发。再运行Ollydbg,加载程序,然后对0x004345B8地 址设断点,如下图。” ![]() 🥷🥼🪟😊💅 “运行全A的超长字符串攻击程序,果然被Ollydbg成功中断下来。Receive其实还是调用了 WS0CK32的 recv函数。我们跟进去就可以看见如下代码:” [mw_shl_code=c,true]73D4A22E > FF7424 0C PUSH DWORD PTR SS:[ESP+C] 73D4A232 FF7424 0C PUSH DWORD PTR SS:[ESP+C] 73D4A236 FF7424 0C PUSH DWORD PTR SS:[ESP+C]👮♂️🩴🔍😈👂 73D4A23A FF71 04 PUSH DWORD PTR DS:[ECX+4] 73D4A23D E8 03000000 CALL MFC42.73D4A245 ; JMP to WSOCK32.recv 73D4A242 C2 0C00 RETN 0C[/mw_shl_code] “看,最后一个参数是[ECX+4],值为00D7E93C,是接收后数据存放的地方。我们在左下角的内存窗口中 按Ctrl + G,弹出地址对话框,输入00D7E93C就会显示该地址的内容。recv执行完后,可以看到,收到的就是我们发的东东:User AAAAA……如下图。” 🤛🌕🍟🅱🦊 ![]() “哦! ” 👩✈️🧢🖨😒✋ “这就完成了我们漏洞分析最关键的一步,在字符串处理的前端中断了下来!我们继续跟踪,注意随时查看各个参数里的内容,发现我们发送的字符串就多多观察。” “到了下面这里,是在判断开头的命令字符,这里是USER命令,如下图。” 🦴🗼🍓⚛🦚 ![]() “然后程序处理后面的字符串,经过耐心的跟踪,在0042E2FA: call 004044c0时,有对00BBFD54进行了写操作!即该函数把地址保存在00BBFD54这个位置。如下图。” ![]() “哦!但00BBFD54和00BBFD5C不是同一个地址啊!”古风一脸疑问的表情。 “莫非是ret n?”宇强说道。 👂🏝🥛♑🐡 “呵呵!我们按F8跟进去看看!” “好,一下子就看见有一个sprinft函数!如下图。” ![]() 🧑⚕️🕶🛒😒👀 “我们边单步运行,边查看它的参数 “首先PUSH EAX,这个EAX为如下: "[C 2004 11 26 22:42] 00001 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA “就是日期时间加上我们输入的超长字符串。” “然后,PUSH war-ftpd.004406C0,这里是%3,一个标准的字符串拷贝。” 💅🔪‼🐖 “最后 PUSH ECX,再 CALL〈&MSVCRT.sprintf>。” “我们来计算一下,ecx = 0x00BBFB54;而保存返回地址在ESP=0x00BBFD54中。” 👦👠📠😇🤌 “相减,0x00BBFD54 —0x00BBFB54 = 0x200 = 512。” “而前面[C 2004 11 26 22:42] 00001 AAA…有28个字符,所以填充A为是512-27 = 485。果然是这样!” “继续跟踪,到函数返回的时候,果然和宇强同学说的一样,是RETN 4,如下图。” 🤞🗺🥛©🦖 ![]() “我们说过RET 4 = POP EIP,ADD ESP,4。现在ESP=00BBFD54,对应的值为41414141,所以返回后,系统会执行0x41414141的地方,如下图。 👃🧳🫖♻🐕 ![]() “最后看看为什么RET 4返回后,ESP会成为00BBFD5C。” “RET 4 = P0P EIP, ADD ESP, 4。首先 POP EIP,那么 EIP 变成 0x41414141,而 ESP+4 = 00BBFD54 + 4 = 00BBFD58;再 ADD ESP, 4 = ESP+4 = 00BBFD58 + 4 = 00BBFD5C。”🧑💻🩴🪗😊👀 “所以返回后,EIP=41414141,ESP=00BBFD5C,果然验证了我们的分析,如狭隘图。” ![]() ✌🚘🥑❗🦟 “小结一下,溢出是因为执行了 sprintf (eax,” ,” [] AAAAAAAAAA”)。这里,eax是一个局部变量,而sprinf没有验证字符串的长度,所以就发生溢出了!” 黑白结合,LSA漏洞的分析利用 🧑⚕️👜🏮😇🤛 ”一气呵成!不知不觉中就把漏洞找了出来,”宇强感叹道。 ‘呵呵!最后来一个高难度的吧! LSA的远程溢出漏洞分析利用。这就需要黑白法结合了。 “首先看看本地溢出,这个比较简单,下图里的代码就可引发本地溢出。” 🙏⛴🥣🈴🐖 ![]() ”其功能是从系统Netapi32.dll中找到DsRolepEncryptPasswordStart函数,然后执行该函数,函数的第一个参数过长,就会溢出,溢出效果么?呵呵,弹出一个出错对话框,倒计时1分钟后就重启。” 👎🦼🍇♂🐅 “哦!和震荡波的效果一样啊!””只能等它重启,没有办法了吗?” “大家在运行程序里输入shutdown -a,可以终止系统关机。Shutdown命令的帮助如下图。”🧓🥼🛒😍🖕 ![]() “因为可以直接用DsRolepEncryptPasswordStart函数引发本地异常,所以本地漏洞利用比较简单,大家用Ollydbg加载lsass.exe进程,然后填充buf用定位大法,就可轻松实现定位和利用!大家都应该很清楚了吧,这个作为寒假作业,大家自己跟入分析一下。” 👨🎨👗🧹😷👏 大家纷纷埋头记下来。 “好了,我们来看看感兴趣的一远程利用!” 👩✈️🥼📬😶👊 “我们刚才用的Netapi32.dll中的DsRoleUpgradeDownlevelServer函数是个客户端函数,我们给它的超长参数会在服务端函数LSASRV.dll中的DsRolerUpgradeDownlevelServer?处理!注意,函数名只相差一个‘r’。大家下去亲自跟踪一下就清楚了。” “服务端函数不会判断请求是哪儿来的,但微软实现时就固定好了客户端函数只向本机发请求。所以我们发请求,默认给本机,本机LSASRV.dll中的服务器函数处理就会出现问题重启。” “好,现在我们的目标就是要给远程机器发送请求!但刚才说了,微软在实现代码时就固定了只能向本机发请求,那怎么办呢?” 🤟🚐🍞🈴🪰 “是啊!不好办啊! ”台下说道。 “其实,平时我们使用修改后的东西也多了;要注册码,我们就破解注册码;要过期,我们就破解过期补丁。所以,我们也把比尔盖茨实现好的客户端代码改一下,不仅向本机发请求,也能向远程主机发请求。” 🙌🚤🍟🔞🐋 “真正的黑客精神,就是不断的深入研究技术,大胆创新,发扬共享精神。” “我们用IDA反编译NetApi32.dll。好,结束后,用名字找到DsRoleUpgradeDownlevelServer()的地方。 如下图。” ![]() “好,从函数开始的地方,往下走一点点,代码如下:” [mw_shl_code=c,true].text:7513D5F7 8D 45 CC lea eax, [ebp+var_34] .text:7513D5FA 50 push eax 🤌🍭❓🐥.text:7513D5FB 6A 00 push 0 .text:7513D5FD E8 0F 05 00 00 call _DsRolepEncryptPasswordStart@24 ;[/mw_shl_code] “在IDA中,默认是不显示机器码的,在‘Options—General—Disassembly’页面中,有Number of opcode bytes,默认是0,我们把它改成6或8就行了。如下图。” 🧠🚗🥣➡🐖 ![]() “根据eEye的文档,那里就是我们要修改的地方! _DsRolepEncryptPasswordStart函数的第一个参数就 是主机。微软用的是0,即为空,表示把请求发给本机。我们要把它改成远程主机的地址就0K 了。” 👮♂️🎩🪝🥱🦴 “ShellCode的是DsRoleUpgradeDownlevelServer的参数传来的;那么远程主机的地址也从那里传来吧! 用DsRoleUpgradeDownlevelServer函数的第九个参数传主机地址;然后作为第一个参数给 DsRolepEncryptPasswordStart。 ” “因为前面第九个参数已经给了 [ebp+var + 34] 了,我们把[ebp+var + 34]的内容压入就行了。” “明白了思路,现在改写代码。注意,改写时要保证字节个数和原来的相同,参数也要压足。除了保证第一个参数压的是[ebp+var + 34]外,其他的乱压也可以,所以我们就这样吧:”🧑🍳💎📡😷🖕 [mw_shl_code=c,true]50 push eax 8B 45 CC mov eax, [ebp+var_34] 50 push eax 90 nop[/mw_shl_code] ✍⛴🍼📵 “这样就把存在[ebp+var_34]中的远程主机地址作为第一个参数压入;nop是什么都不做的空指令,目的只是为了保证字节数和原来的相同。” “好,我们调出WinHex,搜索至我们要修改的地方,作如下图的的修改。” 👦👓📥🤤👈 ![]() “啊,诺顿报警了!这么厉害啊!”古风发现道。 🙏🚈🌶❌🐢 “我们等会再来考虑这个问题,先把诺顿关掉,然后LoadLibrary我们改过后的ww1NetApi.dll,并把第九个参数改成远程主机的地址,即\\ip\ipc$的Unicode形式。指定远程主机的IP地址,编译执行 LSAl.cpp,再Telnet远程主机的1234端口。‘啪’!果然连上了我们要攻击的远程主机。”“成功了! ”大家欢呼起来。 🧓💎📬😷👍 “我们再来改进改进。首先,辛辛苦苦修改的dll会被查杀成病毒,那么就要想办法让杀毒软件不认识!” “杀毒软件是按照文件的特征码来识别一个病毒或木马的。我们只是在正常的系统文件NetApi32.dll的基础上改变了6个字节,其他完全相同;所以杀毒软件的特征码一定是判断的这6个字节!那我们就把这六个字节稍微改一下,看它还能否识别!” “刚才说了,90是nop,表示什么都不做的空指令,我们把它放在其它指令之间,如下图,和指令50 (即 汇编PUSH EAX)交换一下位置。” ![]() 👃🚂🥑❌🐢 “然后保存为ww2NetApi.dll,让诺顿再扫描看看。呵呵!这次没报警了。其实,如果还要报警,我们可以继续修改nop位置,如还不行,还可改成mov ebx ,再push ebx等。办法多得很呢!” “不会被查杀了,看看效果啊!我们把程序改为读ww2NetApi.dll,再运行,还是成功了!如下图。 ✍🎠🎂📶🐙 ![]() 小知识:特征码 现在绝大多数杀毒软件都是建立在“病毒特征码”基础上的。有新病毒出现时,厂商先要获得病毒的 一个样本,提取出它的特征码,用户把特征码加入到病毒库中才能查杀。如果我们测试出了杀毒软件的判断特征码,将其改成不影响功能的其他指令,就肯定不会被查杀!从这个意义上来说,反病毒的技术需要 一个革命化的突破! 🧑⚕️🕶🖌😶👂 “在此,我们是直接物理修改了 NetApi32.dll,就像破解一样,修改了物理文件。其实,我们还可在内存里动态修改,就如同内存注册机一样,动态读出内存的东西!这个交给大家下去完成吧!” “现在我们可以说是完美的实现远程溢出了,但带有一个300k的dll,试想震荡波拖着这个dll到处跑, 也太难为它了吧!所以我们就把dll也去掉,完全用一个程序实现!” 🧑🍳👓🪝😰 “啊?怎么实现呢?” “源代码是微软控制的,一般人都看不到。当然,对我们菜鸟来说,即使有了源代码,也是读不懂请求是如何实现的,更不用说自己写一个请求了。” “所以黑盒法出场了!本机向远程发起请求时,一定会通过网络的。所以,我们可把远程主机发的请求包抓下来,模拟客户端,向服务端发送这样的网络包就可以了! 👃🚘🥑🆎🦄 “好啊,说干就干! ”古风打开Ethereal ,再对远程主机攻击一次,然后把攻击发送的包 抓下来,如下图。 ![]() 👍⛪🔪🈳🐥 “192.168.1.166是攻击机,192.168.1.169的被攻击的服务机。192.168.1.166先是TCP三次握手,然后建立空连接,上图里NT Create Andx Request, Path:\lsarpc那排是关键!那就是发送一定的请求, 然后把我们的超长参数发过去。”“但我们不用具体了解它的含义,只管把请求拷贝下来存在数组中,直接向远程机器发送就是了。” “这次运行我们的LSA2.cpp,又成功了,它可是不带dll的哦!” 👨🦱👞📬😰🦷 “哇! ” “Sniffer是很有用的,如果有溢出的exe程序,那我们就不用具体搞清楚协议、实现什么的,到时直接 一抓包,发挥菜鸟吃苦精神,一句句的敲在发送数据中就可以了!而且这种方法分析微软未文档化的东西 (特别是RPC相关的东西),那更是相当有用!” 💅🌧🎂🅰🐺 尾声 “老师,好像LSA这样的网络通信也很有意思!和Socket好像不一样,讲讲它们的实现吧! ”古风说道。 “呵呵,快放假了,大家也要进入期末考试了。估计也不能投入太多时间来进行实际思考,更别提实践和演练了。而这门课,只懂得原理是远远不够的,实践才是关键。所以我打算布置一下寒假作业。”老师说道。 👍🚐🍒🆘🦚 同学们都拿起笔,听老师布置作业。 “第一道题就是上节课说的,利用寒假时间通过查阅网上的相关资料,用高级语言实现一个找出已有 Socket,并利用它传输数据的程序,用于穿透防火墙!” “代码还能够执行远程传输过来的命令,最后再把它提取成我们的ShellCode。”老师接着说道。 🧑🚀🩰🏮😉👀 “哦,听起来还蛮有难度啊! ”玉波吐了吐舌头。 “第二道题:分析一个假期中出现的新漏洞。当然,如果你们能自己发现新漏洞,当然更好(在CVE留下 自己的名字吧)! 下学期开学后我们进行评讲,然后进一步深入各种漏洞,包括格式化溢出、静态溢出、 VC虚函数溢出、Linux环境下溢出等,还会涉及到其他方面的内容!到时看校长大人、土豆以及学校的安排吧!这学期的课就到这里。大家好好复习,准备考试!同学们,再见!希望大家过个好年!” 👃🪐🍭☣🐅 宇强和小倩来到教室外面······ 天空下起了雪花了,一片片落下,然后渗入水泥路面。整个世界,好像裹上了一层素装。 🧑💻👚✒😷✍ 在南方,下雪极不易啊! “平安夜,我们去天府广场听钟声吧?” 🧑🍳🕶🧻😅🤙 “好啊!” 不知何时,两人的手牵在了一起;两颗心,是如此的温暖和接近。 ······
帖子热度 9568 ℃
|
|
我要把你这篇帖子牢牢的记在心里,刻在脑海里;
我要去学活字印刷,把这篇帖子印成铅字; 我要去学雕刻,把这篇帖子雕成雕像; 我要去学作诗,把这篇帖子改为不朽的诗篇; 我要去学作词,把这篇帖子改为歌词;👩🩲🪟😀👂 我要去学歌唱,把这篇帖子广为流唱; 我要去学说梦话,在梦里也要深情的朗诵; 我要去学刺青,把这篇帖子刺在每个人的身上! 我要做黑客,把所有的网站都改成这篇帖子; 我要做法官,让所有的囚犯都抄写这篇帖子; 👴👙📐😪👀 我要做中国移动的董事长,给所有手机用户群发这篇帖子; 我要做微软总裁,把所有的电脑操作系统都改为这篇帖子; 我要做上帝,让亿万万信徒从此以后只靠这篇贴子来作为圣经,来指引他们的光明! #368: |