安云网 - AnYun.ORG | 专注于网络信息收集、网络数据分享、网络安全研究、网络各种猎奇八卦。
当前位置: 安云网 > 技术关注 > WEB安全 > 安全扫描器BugScan插件初写心语

安全扫描器BugScan插件初写心语

时间:2015-05-01来源: 作者:kun点击:
注意Bugscan平台是基于Python2.7.X开发,所以为了实现良好的兼容,编写插件的时候所使用的平台也应该为Python 2.7.X。Python 2.7.X 下载地址:https://www.python.org/downloads/这里对于Python如何使用不再…

//安云网,anyun.org

注意
//copyright AnYun.ORG

Bugscan平台是基于Python2.7.X开发,所以为了实现良好的兼容,编写插件的时候所使用的平台也应该为Python 2.7.X。

//安云网咨询系统

Python 2.7.X 下载地址: //copyright AnYun.ORG

https://www.python.org/downloads/ //copyright AnYun.ORG

这里对于Python如何使用不再赘述,请自己查找相关资料 //安云网咨询系统

不会Python怎么办

//内容来自AnYun.ORG

如果不会Python的话,可以去看看相关的资料/视频,这里给出一些资料

//copyright AnYun.ORG

廖雪峰的Python教程: //内容来自安云网

http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000

//ANYUN.ORG

简明 Python 教程:

//内容来自安云网

http://www.kuqin.com/abyteofpython_cn/ //安云网,anyun.org

中谷教育Python教学视频: //安云网,anyun.org

http://pan.baidu.com/s/1c02HoZm 密码: 03va //安云网,anyun.org

我自己学Python的笔记:

//本文来自安云网

http://blog.l1n3.net/tag/python-2/ //ANYUN.ORG

编写前的准备 //ANYUN.ORG

首先去下载BugScan的SDK,放置到Python目录中的lib中,方便插件的调试 //内容来自AnYun.ORG

SDK链接地址:https://www.bugscan.net/sdk.zip

//内容来自AnYun.ORG

默认安装路径: C:\Python27 //安云网,anyun.org

建议SDK存放位置: C:\Python27\Lib\ //本文来自安云网

仔细阅读过官方的SDK文档:https://www.bugscan.net/#!/i/ //ANYUN.ORG

前置技能(不绝对) //copyright AnYun.ORG

如果需要为BugScan编写插件,需要以下前置技能

//内容来自安云网

1.熟练运用Python中的数字,列表,字典等数据类型
2.熟练运用Python的函数
3.熟练运用Python的流程控制
4.熟练运用Python的正则表达式(re模块) 

//copyright AnYun.ORG

如果想学习BugScan插件,需要以下前置技能

//copyright AnYun.ORG

1.最少能够熟练的运用Python类以下的所有函数/类型/方法
2.了解漏洞利用方法,最好也能了解漏洞成因
3.了解大多数网站的架构Windows/Linux +IIS/Apache/Nginx + SQL Server/Mysql/Oracle + ASP/PHP/JSP/ASPX
4.了解大部分漏洞的原理,注入,XSS,CSRF,远程命令执行,上传截断,改包等
如果想自主的去发现漏洞
5.了解HTTP协议通信过程,GET方式和POST方式提交,cookie的作用等
6.熟练运用BurpSuite,SQLMAP,Chrome开发者工具,FireBug等工具(Fuzz)
7.能看懂ASP/PHP等代码(开源程序审计)
8.和大牛不断交(Gao)流(Ji) //安云网,anyun.org 

BugScan插件实现原理 //内容来自AnYun.ORG

一个标准的插件的代码如下 //copyright AnYun.ORG

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Plugin Format
#_Function_ = 插件格式
#_FileName_ = Plugin_Format.py
######建议把之上的东西都带上,以便于辨认######
 
 
def assign(service, arg):
    if service =="service":  # 1. service字符串
        return True, arg
 
def audit(arg):
    print"hello, world!"
    # 2.主体攻击代码部分
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('service', 'http://www.example.com/')[1])
    # 3. service字符串
    # 4.http://www.example.com/ 字符串 
//安云网咨询系统

需要修改的地方主要为代码中编号的4处,其中1处和3处的服务类型须保持一致 //安云网咨询系统

服务类型判断

//安云网咨询系统

服务类型列表在https://www.bugscan.net/#!/n/7 //本文来自安云网

请严格按照列表中的服务名称来书写

//内容来自安云网

主体攻击代码这里书写主要用于实现的攻击代码,如何实现请看下文

//内容来自安云网

服务类型提交这里也是服务类型,由框架传参进入,与1.处保持一致即可 //安云网咨询系统

测试URL

//安云网,anyun.org

上传插件时,这里写成存在该漏洞测试网站,方便管理员审核

//本文来自安云网

但插件在提交展示的时候会自动替换为http://www.example.com/

//本文来自安云网

只有管理员可以看到漏洞测试网站

//copyright AnYun.ORG

函数解说 //内容来自安云网

if __name__ == '__main__'主体函数 //安云网,anyun.org

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Plugin Format
#_Function_ = 插件格式
#_FileName_ = Plugin_Format.py
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('service', 'http://www.example.com/')[1])
    # 移交执行权至audit //ANYUN.ORG 

当调用到一个插件的时候,主体函数()即得到执行,该函数执行过程为assign函数判断服务类型(即该插件是否可用于该网站),如果返回True的话,即调用audit函数来完成攻击/扫描的过程 //安云网咨询系统

assign函数 //安云网,anyun.org

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Plugin Format
#_Function_ = 插件格式
#_FileName_ = Plugin_Format.py
 
def assign(service, arg):
    if service =="service":  
        return True, arg 
    # 服务类型判断 

//安云网咨询系统

assign函数判断BugScan框架传入的服务类型,如果服务类型与插件中定义(即service字符串)的一致,则表明该插件可用于该网站,返回True和网站的URL(arg字符串)

//安云网,anyun.org

然后执行接下来的漏洞测试代码 //本文来自安云网

audit函数 //copyright AnYun.ORG

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Plugin Format
#_Function_ = 插件格式
#_FileName_ = Plugin_Format.py
 
def audit(arg):
    print"hello,world!"
    # 主体攻击代码部分 
//安云网,anyun.org

audit函数为主要实现攻击过程的函数,当扫描一个网站的时候大多数情况下需要调用curl.curl这个函数来完成扫描过程,随后会对curl进行单独解说 //内容来自AnYun.ORG

audit在执行的过程中会获取一个变量,变量名为arg,变量值为待扫描的URL,字符串类型

//copyright AnYun.ORG

我们是如何访问网站的 //内容来自安云网

众所周知,访问网站实际上也就是客户端HTTP请求和服务端HTTP返回的过程 //本文来自安云网

请求一般最常用的是GET和POST方法,而有时候我们访问的网站是动态页面,这就需要客户端传入一些参数来实现同一个样式的网页返回不同的信息

//安云网,anyun.org

GET提交 //copyright AnYun.ORG

动态网页的URL一般为:http://www.xxoo.com/1.php?id=1这里的id即为我们传入的参数

//本文来自安云网

而在W3C的规定里,以URL方式传入的参数为GET方式的提交,所以我们常见的大部分在URL上的注入起始都是GET方式的提交 //安云网咨询系统

GET提交一般常见于网页访问等

//ANYUN.ORG

POST提交 //ANYUN.ORG

POST提交中,带入的参数一般来说客户端不可见(隐性提交),我们需要通过抓包软件(如Burp)来获取传入的参数名和参数值 //安云网,anyun.org

一个POST提交的数据包可能像以下的样子:

//安云网咨询系统

POST /CheckLogin.asp HTTP/1.1
Host: www.xxoo.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36 LBBROWSER
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
If-None-Match: "4ded5b-199-4dc439c1e65c0"
If-Modified-Since: Thu, 09 May 201307:00:47 GMT
 
UserName=admin&PassWord=admin123 //安云网咨询系统 

而这个底下的UserName和PassWord即为我们传入的参数值,POST提交一般常见于登陆,搜索,上传等

//内容来自AnYun.ORG

让插件像个访问者一样

//内容来自安云网

在一些时候我们需要让插件像个正常访问者一样去请求网页 //本文来自安云网

这就需要我们的插件具备HTTP通信的能力,而这里BugScan官方给出了curl类的curl函数,能够更加方便的取获取网页的信息 //安云网,anyun.org

我们先看一下curl的帮助信息,中文版哦 //本文来自安云网

curl是一个使用纯Python编写的工具,只支持HTTP协议

//ANYUN.ORG

命令行格式: //内容来自安云网

curl [-I | -d DATA] [-A USER_AGENT] [-b COOKIE]
[--connect-timeoutCONNECT_TIMEOUT] [-e REFERER]
[-H HEADER][-i] [-m MAX_TIME]
[--max-filesizeMAX_FILESIZE] [--mime-type MIME_TYPE]
[-L][--max-redirs MAX_REDIRS] [-T] [--retry RETRY]
[--retry-delayRETRY_DELAY] [-u USER] [-X REQUEST]
<url> //安云网,anyun.org 

–mime-type 参数表示指定一个MimeType,如果MimeType类型不对,curl将会抛出一个错误(找不到指定字符串类型) //内容来自AnYun.ORG

curl函数执行以后会以元组形式返回5个值,我们可以使用5个变量去接收这5个返回值:

//copyright AnYun.ORG

code        :返回HTTP状态码
head        :返回HTTP头
body        :返回HTTP内容,即HTML
errcode     :返回curl的状态码,代码随后解释
final_url   :返回提交的URL //安云网咨询系统 

errcode状态码解释: //安云网,anyun.org

0 : 返回正常
1 : 不能连接目标URL
2 : 连接超时
3 : 返回异常
4 : 发送异常
5 : 发送数据包过大
6 : 不能确定的主机
7 : 不支持的协议
8 : 参数错误
9 : MimeType错误 

//内容来自安云网

一些举例: //内容来自AnYun.ORG

code, head,body, ecode, redirect_url = curl.curl('-L http://www.baidu.com')

//copyright AnYun.ORG

GET提交: //copyright AnYun.ORG

curl.curl('http://www.abc.com/')

//copyright AnYun.ORG

带HEAD提交:

//copyright AnYun.ORG

curl.curl('-Hhttp://www.abc.com/')

//本文来自安云网

POST提交:

//安云网,anyun.org

curl.curl('-duser=abc&pass=ddd http://www.abc.com/') //copyright AnYun.ORG

PUT提交: //内容来自AnYun.ORG

curl.curl('T -d"Content to put" http://www.abc.com/') //内容来自AnYun.ORG

带Cookie提交:

//安云网,anyun.org

curl.curl('-buser=abc&pass=ddd http://www.abc.com/')

//安云网咨询系统

带Referer提交:

//本文来自安云网

curl.curl('-ehttp://www.google.com/ http://www.abc.com/')

//ANYUN.ORG

重定向数据流:

//安云网,anyun.org

curl.curl('-Lhttp://www.abc.com/')  //安云网咨询系统

curl会在获取网页内容的过程中自动去接收cookie,在进行第二次请求的时候将附加到HTTP头,如果想保持cookie为空,请使用curl.reset()

//本文来自安云网

那么现在我们想让我们的插件去像个正常的访问者一样去访问百度,那么我们的代码可以这么写 //内容来自AnYun.ORG

#!/usr/bin/env python
code, head, body, errcode, final_url = curl.curl('http://www.baidu.com') //内容来自AnYun.ORG 

什么,你告诉我执行完了啥都没有?

//copyright AnYun.ORG

当然啥都没有了,这个只是一个获取并赋值的过程,你见过你定义一个变量之后就返回变量值么? //本文来自安云网

如果我要显示内容,我们可以用print打印出来 //安云网咨询系统

#!/usr/bin/env python
code, head, body, errcode, final_url = curl.curl('http://www.baidu.com')
# 以下显示HTTP状态码
print'---------------code---------------'
print code
# 以下显示HTTP头
print'---------------code---------------'
print head
# 以下显示HTTP主体内容(HTML)
print'---------------code---------------'
print body
# 以下显示curl的状态码
print'-------------err code-------------'
print errcode
# 以下显示curl访问的URL
print'------------final_url-------------'
print final_url //copyright AnYun.ORG 

这样我们就获取到了百度的主页内容,当然如果要像浏览器一样显示出来,我们还需要进行HTML解析和渲染,当然curl不具备此功能(一个命令行工具要求那么多作死啊)

//本文来自安云网

那么接下来我们带着一些参数去访问 

//ANYUN.ORG

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Test Plugin
#_FileName_ = Test_Plugint.py
 
def assign(service, arg):
    if service =="www":  
        return True, arg 
 
def audit(arg):
    payload ='readnews.asp?id=1 and 1=1'
# 注意这里的payload部分不需要在之前加入/
# 否则接下来的curl没办法正确识别url
    target = arg + payload
    code1, head, body1, errcode, final_url = curl.curl('"%s"', % arg)
    # 使用格式化输入,保证我们带入的字符串不被当做指令来执行
    code2, head, body2, errcode, final_url = curl.curl('"%s"', % target)
    #同上
    if code1 ==200and code2 ==200and body1 == body2:
        # 判断加和不加payload的网页的HTTP状态码是否为200
        # 同时判断加和不加payload的网页的内容是否一样
# (and 1=1返回是否与原网页一样)
        print'Find Vulnerability !'#打印信息
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('www', 'http://www.test.com/')[1]) //copyright AnYun.ORG 

这样我们就完成了一个最基本的检测注入漏洞的插件,当然这个插件功能上有些弱

//安云网,anyun.org

不过这个插件已经能说明一些问题了

//ANYUN.ORG

木有错,给BugScan写插件就这么简单 //内容来自安云网

这里我们的举例是GET方式的提交,那么POST方式的提交我们可以写成以下的样子

//copyright AnYun.ORG

使用POST提交的时候curl的参数为-d

//内容来自安云网

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Test Plugin
#_FileName_ = Test_Plugint.py
 
def assign(service, arg):
    if service =="www":  
        return True, arg 
 
def audit(arg):
    URL ='check.asp'
    POST_Data ='username=admin&password=admin888'      #正常的POST数据
    payload ='username=admin and 1=1&password=admin888'  #带有攻击语句的POST数据
    target = arg + payload
 
    code1, head, body1, errcode, final_url = curl.curl('"-d %s %s"'% (POST_Data, target))
    # 使用-d 参数带入POST数据
    # 使用格式化输入,保证我们带入的字符串不被当做指令来执行
    code2, head, body2, errcode, final_url = curl.curl('"-d %s %s"', % (payload, target))
    #同上
    if code1 ==200and code2 ==200and body1 == body2 :
        # 判断加和不加payload的网页的HTTP状态码是否为200
        # 同时判断加和不加payload的网页的内容是否一样(and 1=1返回是否与原网页一样)
        print'Find Vulnerability !'#打印信息
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('www', 'http://www.test.com/')[1]) //ANYUN.ORG 

我们也可以带着cookie提交 //本文来自安云网

使用cookie提交的参数为-b //安云网咨询系统

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Test Plugin
#_FileName_ = Test_Plugint.py
 
def assign(service, arg):
    if service =="www":  
        return True, arg 
 
def audit(arg):
    URL ='main.asp'
    cookie ='sessionid=PHPSESSIONADMIN;username=admin;passcode=21232f297a57a5a743894a0e4a801fc3'      #cookie值
    target = arg + payload
    code, head, body, errcode, final_url = curl.curl('"-b %s %s"'% (POST_Data, target))
    # 使用-d 参数带入POST数据
    # 使用格式化输入,保证我们带入的字符串不被当做指令来执行
    #同上
    if code ==200 :
        print'Find Vulnerability !'#打印信息
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('www', 'http://www.test.com/')[1]) //内容来自安云网 

我们也可以同时带着多个参数去请求

//本文来自安云网

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Test Plugin
#_FileName_ = Test_Plugint.py
 
def assign(service, arg):
    if service =="www":  
        return True, arg 
 
def audit(arg):
    URL ='main.asp'
    cookie ='sessionid=PHPSESSIONADMIN;username=admin;passcode=21232f297a57a5a743894a0e4a801fc3'      #cookie值
    POST ='SQL=select username,password from admin'
    target = arg + payload
    code, head, body, errcode, final_url = curl.curl('"-b %s -d %s %s"'% (cookie, POST, target))
    # 使用-b 参数带入cookie数据
    # 使用-d 参数带入POST数据
    # 使用格式化输入,保证我们带入的字符串不被当做指令来执行
    #同上
    if code ==200 :
        print'Find Vulnerability !'#打印信息
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('www', 'http://www.test.com/')[1]) //内容来自安云网 

OK就是这么简单

//安云网,anyun.org

在BugScan框架中,print是不会有任何效果的,因为print是打印到控制台了,而我们在扫描的时候并不能去登录到控制台上查看输出信息,所以我们这里就要使用报警函数

//内容来自AnYun.ORG

报警函数操作指南

//内容来自安云网

通知函数类型:

//安云网咨询系统

       通知消息(仅是信息,用绿色表示)      : security_note(str)
    敏感信息(看做低危,用蓝色表示)      : security_info(str)
    需要注意(看做中危,用橙色表示)      : security_warning(str)
    特别注意(看做高危,用红色表示)      : security_hole(str) 

//内容来自AnYun.ORG

当我们需要让插件进行报警的时候,选用相应的通知函数即可实现在BugScan的Web端的通知 //ANYUN.ORG

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#__Author__ = LinE
#_PlugName_ = Test Plugin
#_FileName_ = Test_Plugint.py
 
def assign(service, arg):
    if service =="www":  
        return True, arg 
 
def audit(arg):
    payload ='readnews.asp?id=1 and 1=1'
    # 注意这里的payload部分不需要在之前加入/,否则接下来的curl没办法正确识别url
    target = arg + payload
    code1, head, body1, errcode, final_url = curl.curl('"%s"', % arg)
    # 使用格式化输入,保证我们带入的字符串不被当做指令来执行
    code2, head, body2, errcode, final_url = curl.curl('"%s"', % target)
    #同上
    if code1 ==200and code2 ==200and body1 == body2 :
        # 判断加和不加payload的网页的HTTP状态码是否为200
        # 同时判断加和不加payload的网页的内容是否一样(and 1=1返回是否与原网页一样)
        security_hole(final_url) # 因为注入算是比较危险的漏洞,所以我们这里报警高危
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('www', 'http://www.test.com/')[1]) 

//本文来自安云网

一般来说,我们对一些信息的获取划分了等级 //安云网,anyun.org

低危:绝对路径获取,反射型XSS等

//内容来自AnYun.ORG

中危:备份下载,存储型XSS等 //安云网咨询系统

高危:远程命令执行,SQL注入,任意文件下载,拒绝服务等 //内容来自AnYun.ORG

现在回过头来看看官方SDK给出的DZ检测插件

//内容来自安云网

#!/usr/bin/env python
import re   # 引入re模块,来实现正则表达式相关操作
def assign(service, arg):
    if service =="discuz":
        return True, arg
 
def audit(arg):
    code, head, res, errcode, _ = curl.curl(arg +'uc_server/control/admin/db.php')  # 发出HTTP请求
    if code ==200: # 判断返回状态码,以保证有信息返回
        m = re.search('not found in ([^<]+) on line (\d+)', res) # 使用正则表达式来匹配返回HTML中的相关字符串
        if m: # 如果正则匹配到了
            security_info(m.group(1)) #报警
 
if __name__ =='__main__':
    from dummy import*
    audit(assign('discuz', 'http://www.test.com/')[1]) 

//本文来自安云网

BugScan插件编写教程基本到这里就算是完了 //安云网咨询系统

小菜我也是刚刚学会的初学者,如文中有什么不对的地方欢迎指正! //内容来自安云网

[作者/LinE,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)]
//安云网,anyun.org

顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
验证码: 点击我更换图片
相关内容
推荐内容