Skip to content

bsmali4/xssfork

master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Code

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
sql
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

 重要说明

kali下无法使用的话,请下载正确的phantomjs 到目录thirdparty/phantomjs/Linux

更多信息访问http://xssfork.secbug.net/

由于使用的是phantomjs,所以使用期间可能会造成内存,cpu消耗过大。对网络造成的破坏,本人不负任何法律责任。

免责申明

xssfork保证竭诚为网络用户提供最安全的上网服务,但因不可避免的问题导致出现的问题,我们尽力解决,期间引起的问题我们不承担以下责任。

第 一 条

xssfork使用者因为违反本声明的规定而触犯中华人民共和国法律的,一切后果自己负担,xssfork.secbug.net站点以及作者不承担任何责任。

第 二 条

凡以任何方式直接、间接使用xssfork资料者,视为自愿接受xssfork.secbug.net声明的约束。

第 三 条

本声明未涉及的问题参见国家有关法律法规,当本声明与国家法律法规冲突时,以国家法律法规为准。

第 四 条

对于因不可抗力或xssfork不能控制的原因造成的网络服务中断或其它缺陷,xssfork.secbug.net网站以及作者不承担任何责任。

第 五 条

xssfork之声明以及其修改权、更新权及最终解释权均属xssfork.secbug.net网所有。

更多信息访问http://xssfork.secbug.net/

更新xssforkapi,提供分布式部署方案。

概述

xssfork是新一代xss漏洞探测工具,其开发的目的是帮助安全从业者高效率的检测xss安全漏洞,关于xss的更多详情可以移步Cross-site Scripting (XSS)。不管什么语言,传统的xss探测工具,一般都是采用第三方库向服务器发送一个注入恶意代码的请求,其工作原理是采用payload in response的方式,即通过检测响应包中payload的完整性来判断,这种方式缺陷,很多。 例如 1.不能检测dom类xss(无法从源代码中检查) 2.不能模拟真正的浏览器 3.网页js无法交互,第三方库不认识网页中的js的代码。 与传统的工具相比,xssfork使用的是 webkit内核的浏览器phantomjs,其可以很好的模拟浏览器。工具分为两个部分,xssfork和xssforkapi,其中xssfork在对网站fuzz xss的时候会调用比较多的payload。

两者结合

可以使用xssforkapi来做批量xss检测工具,xssfork做深度fuzz工具。xssforkapi这种webservice方式十分适合分布式部署。

创建任务

关于key,为了保证外部不能非法调用服务,xssforkapi采用的是http协议验证key的方式。

key的获取方式

在每次启动xssforkapi的时候,会将key写入到根目录authentication.key中,你也可以在每次启动服务的时候看到key。 key默认是每次启动服务不更新的,你也可以在下一次启动服务的时候强制更新,只需要启动的时候指定--refresh True即可。值得注意的时候,refresh指定为true之后,原有的保存在data目录下xssfork.db将会清除,这意味着你将清除你之前所有的检测纪录。 ##新建扫描任务
需要向服务传递两个参数,1.key(主要用于验证身份);2.检测参数

get协议检测

###创建任务 1.get反射型类型

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/example1.php?name=hacker', ), headers={'Content-Type':'application/json'})
return req.content

2.post反射类型

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/post_xss.php', 'data':'name=233'), headers={'Content-Type':'application/json'})
return req.content

3.get反射型类型,需要验证cookie

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/example1.php?name=hacker', 'cookie':'usid=admin'), headers={'Content-Type':'application/json'})
return req.content

4.post反射型类型,需要验证cookie

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/post_xss.php', 'data':'name=2333', 'cookie': 'usid=admin'), headers={'Content-Type':'application/json'})
return req.content

5.get储存型,需要验证cookie

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/example1.php?name=hacker', 'cookie':'usid=admin', 'destination': 'http://10.211.55.13/output.php'), headers={'Content-Type':'application/json'})
return req.content

4.post储存型,需要验证cookie

req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75',data=json.dumps({'url':'http://10.211.55.13/xss/example1.php?name=hacker', 'data':'name=2333', 'cookie':'usid=admin', 'destination': 'http://10.211.55.13/output.php'), headers={'Content-Type':'application/json'})
return req.content

返回码

{"status": "success", "task_id": "1"}

调用者可以获取到任务id,以便于启动检测。 #启动任务

import requests
req = requests.get('http://127.0.0.1:2333/xssfork/start_task/tM0Xnl0qD6nsHku/%s' % (task_id))
print req.content

返回码

{"status": "success", "msg": "task will start"}

#查看状态

import requests
req = requests.get('http://127.0.0.1:2333/xssfork/task_status/tM0Xnl0qD6nsHku/%s' % (task_id))
print req.content

返回码分为4种,分别如下:
1.任务不存在

{"status": -1, "msg": "task isn’t existed"}

2.任务创建了,但是未启动

{"status": 0, "msg": "task isn't started"}

3.任务正在作业中,未完成

{"status": 1, "msg": "task is working"}

4.任务作业完成

{"status":2, "msg": "task has been done"}

#获取结果

req = requests.get('http://127.0.0.1:2333/xssfork/task_result/7T2o22NcQSLGk75/%s' % (task_id))
	print req.content

返回分为两种
1.检测到漏洞,并且返回payload

{"payload": "{'url': "http://10.211.55.13/xss/example1.php?name=%22<xss></xss>//", 'data': null}"}

2.未检测到漏洞

{"payload": null}

#结束任务

req = requests.get('http://127.0.0.1:2333/xssfork/kill_task/7T2o22NcQSLGk75/%s' % (task_id))
	print req.content

返回结果可能有4种 1.结束任务失败,因为任务不存在

{"status": "false", "msg": "task isn’t existed"}

2.结束任务失败,因为任务根本没启动

{"status": "false", "msg": "task isn't started"}

3.结束任务失败,因为任务本已经结束,不需要强制杀死

{"status": "false", "msg": "task has been done"}

4.结束任务成功,任务原本是处于运行中的状态

{"status": "success", "msg": "task will be killed"}

#完整的例子 1.一次带有cookie验证的post xss 漏洞示例代码

<?php
if (isset($_COOKIE['usid']) && isset($_POST['id']))
{
	if ($_COOKIE['usid']=="admin")
		{
			echo $_POST['id'];
		}
}
?>

客户端代码

#! /usr/bin/env python
# coding=utf-8
import json
import time
import requests


def creat_task(url, data, cookie):
    json_data = json.dumps({'url': url, 'data': data, 'cookie': cookie})
    req = requests.post('http://127.0.0.1:2333/xssfork/create_task/7T2o22NcQSLGk75', data=json_data, headers={'Content-Type':'application/json'})
    return req.content


def start_task(task_id):
    req = requests.get('http://127.0.0.1:2333/xssfork/start_task/7T2o22NcQSLGk75/{}'.format(task_id))
    return req.content


def get_task_status(task_id):
    req = requests.get('http://127.0.0.1:2333/xssfork/task_status/7T2o22NcQSLGk75/{}'.format(task_id))
    return req.content


def get_task_result(task_id):
    req = requests.get('http://127.0.0.1:2333/xssfork/task_result/7T2o22NcQSLGk75/{}'.format(task_id))
    return req.content


def running(task_id):
    time.sleep(5)
    task_status = int(json.loads(get_task_status(task_id)).get('status'))
    return task_status in [0, 1]


if __name__ == "__main__":
    url = "http://10.211.55.3/xsstest/cookie_xss_post.php"
    data = "id=1"
    cookie = "usid=admin"
    task_id = json.loads(creat_task(url, data, cookie)).get('task_id')
    start_task(task_id)
    while running(task_id):
        print "the task is working"
    print get_task_result(task_id)

效果

xssfork简介

xssfork作为sicklescan的一个功能模块,其开发主要目的是用于检测xss漏洞。 传统的xss探测工具,一般都是采用 payload in response的方式,即在发送一次带有payload的http请求后,通过检测响应包中payload的完整性来判断,这种方式缺陷,很多。
第一:不能准确地检测dom类xss
第二:用类似于requests之类的库不能真正的模拟浏览器
第三:网页js无法交互
怎么解决?如果能够用浏览器代替这个模块,去自动hook是最好的。所幸,我了解到phantomjs,当然现在google浏览器也支持headless模式,类似的,你也可以采用google浏览器去做检测。

原理

对于这类fuzz过程,基本都是预先准备好一些payload,然后加载执行。对于这类io型密集的扫描模型,后端使用多线程就比较适用,但是由于phantomjs你可以理解为一个无界面的浏览器,在加载的时候,其缺陷也比较明显,比较吃内存,用它来发包自然不像requests库轻量。

编码脚本

由于基础的payload模块,我收集了71个。 基础payload会在现有的基础上,会添加上各种闭合的情况。 除了这些基础的payload,xssfork还提供了几个编码脚本,查看脚本,可以看help 现阶段提供了10进制,16进制,随机大小写,关键字叠加四个脚本。

10hex_encode

将html标签内部字符10进制化 <a href=&#x6a&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3a&#x61&#x6c&#x65&#x72&#x74&#x28&#x36&#x35&#x35&#x33&#x34&#x29&#x3b>aaa</a> 其效果如下

16hex_encode

将html标签内部字符16进制化

uppercase

随机大小写 将 <script>alert(65534);</script> 转换成 <ScRIPt>alert(65534);</ScRIpT>

addkeywords

主要是应对过滤为replace('keyword>s','')的情况
<script>alert(65534);</script> 变成 <<script>script>alert(65534);</script> 当然默认开启的是轻量模式,即只返回一个payload,开启重量模式,可以生成更加丰富的pyaload,效果如下 <script>alert(65534);</script>
<script>alert(65534);</ScrIpt>
<ScrIpt>alert(65534);</sCrIpt>
<scRiPt>alert(65534);</script>
<ScrIpt>alert(65534);</script>

演示

场景1.反射型xss

场景2.大小写绕过

场景3.dom型xss
场景3.post类型 场景4.需要验证cookie

post类型
python xssfork.py -u "xx" -d "xx" 存储型
python xssfork.py -u "xx" -d "xxx" -D "输出位置" 带cookie python xssfork.py -u "xx" -c "xx"

支持伪静态的检测

说明

开源只为分享,请勿将本脚本做任何商业性质的集成。开发的时候,有可能很多情况没有考虑到,如果你有更好的建议或者发现bug, root@codersec.net
开源地址 https://github.com/bsmali4/xssfork 记得不要吝啬你的star

更新日志:2017-10-24 修复卡住进度bug

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages