Python之Xss检测

00x1:

需要用到的模块如下:

import requests

00x2:

大致思路:

每次插入一个xss,判断网页内容是否存在,如果存在则输出

def req(url,xss):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    req = requests.get(url=url+xss,headers=headers,verify=False,timeout=3)
    print u"正在测试",url,xss
    if xss in req.content:
        print "[+]Find Xss url:%s    payload:%s"%(url,xss)

为了方便测试,我们先定义一个payload列表

xss = ["<script>alert('XSS')</script>",
       "%3Cscript%3Ealert('XSS')%3C/script%3E",
       '"><sc<script>ript>alert(/xss/)</script>',
       "<svg onload=alert(/1/)>"
       ]

00x3:

修改一下源代码,过滤script

1

2

ok,一切正常

00x4:

我们来运行一下,遍历xss payload

你也可以定义一个xss.txt,进行读取,然后遍历xss fuzz

(post请求也是如此,只需要一个post请求即可)

你也可以加上 如果存在xss则退出

00x5:

代码如下:

#!/usr/bin/python
#-*- coding:utf-8 -*-
import requests
import urllib3
urllib3.disable_warnings()

def req(url,xss):
    url = url + xss
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    req = requests.get(url,headers=headers,verify=False,timeout=3)
    print u"正在测试",url
    if xss in req.content:
        print "[+]Find Xss url:%s    payload:%s"%(url,xss)

xss = ["<script>alert('XSS')</script>",
       "%3Cscript%3Ealert('XSS')%3C/script%3E",
       '"><sc<script>ript>alert(/xss/)</script>',
       "<svg onload=alert(/1/)>"
       ]

for x in xss:
    req('http://127.0.0.1/xss.php?xss_input=1',x)

00x6:

当然这只是一个最简单的模型,下面我们来进行维护加强一下

思路:

我们可以匹配网页的form标签(表单提交),然后获取请求方式,以及请求参数,模拟请求,进行fuzz

def html(url):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    req = requests.get(url,headers=headers,verify=False,timeout=3)
    r =r'<form.*</form>'
    form = re.findall(r,req.content,re.S)
    print form

接着我们去获取他的请求方式,以及请求参数

method=re.findall(r'method="(.*?)"',str(form))
print method
name = re.findall(r'name="(.*?)"', str(form))
print name

Ok,我们设置全局变量,方便调用

global method,name

00x7:

添加判断,自动fuzz

if method[0] == 'get' or 'GET':
    req = requests.get(url=url+"?"+name[0]+"="+xss,headers=headers,verify=False,timeout=3)
    print u"正在测试",url,xss
    if xss in req.content:
        print "[+]Find Get Xss url:%s    payload:%s"%(url,xss)
if method[0] == 'post' or 'POST':
    data={name[0]:xss}
    req = requests.post(url=url,data=data,headers=headers,verify=False,timeout=3)
    print u"正在测试",url,xss
    if xss in req.content:
        print "[+]Find Post Xss url:%s    payload:%s"%(url,xss)

我们修改为post请求来测试一下

00x8:

为了更人性化,我们再修改一下,导入sys模块

sys.exit() 表示退出程序

def html(url):
    global method,name
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    req = requests.get(url,headers=headers,verify=False,timeout=3)
    r =r'<form.*</form>'
    form = re.findall(r,req.content,re.S)
    method=re.findall(r'method="(.*?)"',str(form))
    name = re.findall(r'name="(.*?)"', str(form))
    try:
        if method==None or name==None:
            sys.exit(0)
        else:
            print u"\nFind method = %s    name = %s\n"%(method[0],name[0])
    except:
        print u"\n自动分析失败!"
        sys.exit(0)

00x9:

完整代码:

#!/usr/bin/python
#-*- coding:utf-8 -*-
import requests,re,sys
import urllib3
urllib3.disable_warnings()

def req(url,xss):
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    if method[0] == 'get' or 'GET':
        req = requests.get(url=url+"?"+name[0]+"="+xss,headers=headers,verify=False,timeout=3)
        print u"正在测试",url,xss
        if xss in req.content:
            print "[+]Find Get Xss url:%s    payload:%s"%(url,xss)
            sys.exit(1)
    if method[0] == 'post' or 'POST':
        data={name[0]:xss}
        req = requests.post(url=url,data=data,headers=headers,verify=False,timeout=3)
        print u"正在测试",url,xss
        if xss in req.content:
            print "[+]Find Post Xss url:%s    payload:%s"%(url,xss)
            sys.exit(1)

def html(url):
    global method,name
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3314.0 Safari/537.36 SE 2.X MetaSr 1.0'
    }
    req = requests.get(url,headers=headers,verify=False,timeout=3)
    r =r'<form.*</form>'
    form = re.findall(r,req.content,re.S)
    method=re.findall(r'method="(.*?)"',str(form))
    name = re.findall(r'name="(.*?)"', str(form))
    try:
        if method==None or name==None:
            sys.exit(0)
        else:
            print u"\nFind method = %s    name = %s\n"%(method[0],name[0])
    except:
        print u"\n自动分析失败!"
        sys.exit(0)


if __name__ == '__main__':
    url = raw_input('\nurl:')
    if 'http' not in url:
        url = 'http://'+url
    xss = ["<script>alert('XSS')</script>",
           "%3Cscript%3Ealert('XSS')%3C/script%3E",
           '"><sc<script>ript>alert(/xss/)</script>',
           "<svg onload=alert(/1/)>"
           ]

    html(url)
    for x in xss:
        req(url,x)

演示:

文章写到这里就结束了,但还是存在一些缺陷,比如表单有多个name,所以你需要去加载多个name,进行请求,这里就不修改了,仅抛砖引玉,希望你可以开发出自己的大项目!

完整项目:https://github.com/hackxc/Pyhacker

#写了一些python安全开发的思路分享出来,对新手比较友好

2 Likes

能不能从文件读取xss的payload

额,这样会导致请求量暴增吧,建议先搞了一个检测疑似存在xss的探针,后面再上这个fuzz。也建议后面这个fuzz能够再动态渲染的情况下搞吧。不然会漏

xss 的检测除了chrome headless 这样真实情况渲染,还有模拟器之类的断言

assert("<script>alert(1)</script>") 

但是要都是要拿到链接,没有链接也谈不上检测。拿到链接还要甄别参数,做一个排列组合,每次只能一个参数变。

但是这样参数一多,比如:

?a={var1|var2|var3|...|varN}&b={var1|var2|...}&c=...

这样一来链接直接指数爆炸,指数从来都不是一个好的东西,很多时候更希望是多项式,所以在爬虫阶段,我们就需要启发式的去甄别一些参数,究竟是不是可控,可能这个参数只是一个逻辑参数,或者一个hash,那么我们就可以减少排列组合的项,可以根据参数hit数,或者参数格式来做一些具体的操作,这些东西都是我在毕业时做过的一些东西,可以参考。:)

1 Like

师傅说的对,如果有很多参数,那就需要再进行处理,这里仅抛砖引玉,网上也有很多开源的xss检测脚本,当时忘记把参数多种情况加入到文章里面了,谢谢师傅提醒

这样请求是很多,一个基础的fuzz xss,谢谢师傅提醒

可以open读文件啊,payload加入到列表就可以了

谢谢师傅分享 很基础的fuzz 刚好能用到感谢了