w3af学习笔记(四)

2 分钟读完

本文分析了w3af的xss插件,旨在理解w3af检测xss漏洞的原理。

一、预备知识

1.XSS

当应用程序收到含有不可信的数据,在没有进行适当的验证和转义的情况下,就将它发送给一个网页浏览器,这就会产生跨站脚本攻击(简称XSS)。XSS允许攻击者在受害者的浏览器上执行脚本,从而劫持用户会话、危害网站、或者将用户转向至恶意网站。(参考:OWASP TOP 10 中文v1.2)

2.audit

对于审计(audit)的理解,审计就是找漏洞。代码审计是一种白盒测试方法,从源代码中发现漏洞;w3af中使用的audit,是一种黑盒测试方法,从外部寻找漏洞。

3.payload

有效载荷(payload)通常指的恶意代码执行破坏性操作的部分,在w3af中指的是包含特殊字符的测试字符串,用来检验这些特殊字符是否被过滤等,并非执行恶意操作。

4.fuzzing

模糊测试(fuzzing, fuzz testing)是一种基于缺陷注入的自动软件测试技术。通过编写fuzzer工具向目标程序提供某种形式的输入并观察其响应来发现问题,这种输入可以是完全随机的或精心构造的,为了寻找软件缺陷,主要是构造畸形数据。Fuzzer工具能很好的检测出可能导致程序崩溃的问题,如缓冲区溢出、跨站点脚本、拒绝服务攻击、格式漏洞和SQL注入。w3af中有一个FuzzableRequest类,该类灵活表示了一个http 请求包。

5.mutant

在w3af中mutant类是对FuzzableRequest类的包装,然后在mutant中添加设置不同的payload,用这些mutant扫描测试网站的漏洞。

二、XSS插件

以w3af\plugins\audit\xss.py的xss.audit函数为主线,深入分析了w3af扫描xss漏洞的原理。

1.xss.payloads

PAYLOADS = ['RANDOMIZE</->',
'RANDOMIZE/*',
'RANDOMIZE"RANDOMIZE',
"RANDOMIZE'RANDOMIZE",
"RANDOMIZE`RANDOMIZE",
"RANDOMIZE ="]

PAYLOADS中起作用的只是里面特殊字符:</->,/*,”,’,`,=; RANDOMIZE只是为了在http响应报文中定位到特殊字符的位置,在些它只是一个占位用的标识字符串,在使用时会随机生成一个字符串,替换RANDOMIZE;

2.xss.audit(freq,orig_response)

orig_response在函数中没有使用,可能是预留的一个参数; freq是FuzzableRequest类对象,表示一个模糊http请求包; 功能:检测一个URL的XSS漏洞,被检测的URL在freq中;
执行过程如下:

  1. 创建一组freq的变体fake_mutants;
  2. 对于一个fake_mutant,扫描(持久型)XSS漏洞;
  3. 首先扫描简单的XSS漏洞(所有字符不经过编码和过滤就直接反射回来),详细过程见_identify_trival_xss(),如果找到XSS漏洞,直接返回;
  4. 然后分析fake_mutant,扫描检测反射型XSS漏洞,详细过程见_search_xss();

3.xss._identify_trival_xss(mutant)

功能:识别简单的XSS漏洞:所有字符不经过编码和过滤就直接反射回来;

  1. 将所有的特殊字符(</->,/*,",',`,=)放在一块,组成一个payload;
  2. 将payload添加到mutant中;
  3. 将mutant发到服务器,返回一个HTTPResponse;
  4. 如果payload在reponse.body中(也就是说所有特殊字符没有被过滤或者编码就直接反射回来),那就是存在xss漏洞;
  5. _report_vuln()创建一个Vuln,并且mutant等存储到KB中;

4.xss._search_xss(mutant)

_search_xss()执行流程

  • 0.用xss.PAYLOADS构造http请求包变体列表mutant_list
  • 1.发送mutant,得到一个HttpResponse
  • 2.调用body=HttpResponse.get_body()
    • 调用HttpResponse._charset_handling(),返回unicode(decoded) body 和used charset
    • http body可能就是<body>标签内的正文,或者是整个网页?
  • 3.根据mutant得到发送的payload
  • 4.调用get_context_iter(body, payload)函数
    • 1). chunks = body.split(payload)
    • 2). data=''
    • 3). 遍历data从chunks[0]迭加到chunks[-1](倒数第2个)
    • 4). byte_chunk = ByteChunk(data)
      • ByteChunk数据成员如下
      • self.attributes=dict()
      • self.data = data
    • 5). 遍历get_contexts()
      • [HtmlAttrSingleQuote(), HtmlAttrDoubleQuote(), HtmlAttrBackticks(), HtmlAttr(), HtmlTag(), HtmlText(), HtmlComment(), ScriptMultiComment(), ScriptLineComment(),ScriptSingleQuote(), ScriptDoubleQuote(), ScriptText(),StyleText(), StyleComment(), StyleSingleQuote(),StyleDoubleQuote()],具体定义见下一节Context
    • 6). 判断context.match(byte_chunk)
      • 如果匹配,1.context.save(data);2.迭代返回context
  • 5. 如果context.is_executable()或者context.can_break()为True,则判定为XSS漏洞
  • 6._report_vuln()创建一个Vuln,并且存储到KB中
  • 7.注释:Context类族,match(), is_executable(), can_break()分析见下一节Context

5.Context

  • 数据成员name, data
  • 下面是类继承关系,大写字母开头的
  • HtmlContext
    • HtmlTag
      • can_break
        • 如果' ','>'在payload中,就判定存在xss漏洞
    • HtmlText
      • can_break
        • 如果'<'在payload中,就判定存在xss漏洞
    • HtmlComment
      • can_break
        • 如果'-','>','<'在payload中,就判定存在xss漏洞
    • HtmlAttr
      • HtmlAttrQuote
        • HtmlAttrSingleQuote
        • - HtmlAttrDoubleQuote
          • HtmlAttrDoubleQuote2Script
            • HtmlAttrDoubleQuote2ScriptText,它的父类还有一个ScriptText
        • HtmlAttrBackticks
        • 上面是HtmlAttrQuote的子类,下面是它的成员
        • self.quote_character
          • 有三个',",`(backtick,可能显示不出来), (但是没找到赋值的地方)
        • can_break()
          • 如果quote_character在payload中,就判定为xss漏洞
        • is_executable()
          • 该函数先将self.data变成小写,删除空格判断self.data是否以下面的字符串结尾,如果是,就返回True['href', 'src','onclick', 'ondblclick', 'onmousedown', 'onmousemove','onmouseout', 'onmouseover', 'onmouseup', 'onchange', 'onfocus', 'onblur', 'onscroll', 'onselect', 'onsubmit', 'onkeydown', 'onkeypress', 'onkeyup', 'onload', 'onunload'] +'=' +self.quote_character. 比如data的尾部是onclick=" ,则返回True
        • match(byte_chunk)
          • 有两个装饰器,其实是返回inside_html(not_html_comment(_match(byte_chunk)))
          • _match(byte_chunk)
            • data= byte_chunk.nhtml
              • - normalize_html(data)
                • (data.replace("\\'",'')).replace('\\"','')
                • data = StringIO(data)
                • 然后一个字符一个字符的处理data
                • 1.删除闭合的',",`
                • 2.处理标签<>,分别替换为&lt, &gt。注意不处理注释<!--
            • 如果data中含有<...>,则返回False
            • 接下来会判断',",`是否闭合
            • 函数的功能好像是判断'.",`,尖括号是否闭合
          • not_html_comment()功能:如果出现<!-->,即在注释中,返回False
          • inside_html()
            • 判断inside_js
              • 搜索<script>
            • 判断inside_style
              • 搜索<style>
            • 当inside_js和inside_style同时False,inside_html返回True
      • can_break
        • 如果' ','='在payload中,就判定存在xss漏洞
  • ScriptContext
    • ScriptMultiComment
      • can_break
        • 如果'/','*'在payload中,判定存在xss漏洞
    • ScriptLineComment\
    • ScriptQuote
    • ScriptSingleQuote
    • ScriptDoubleQuote
    • ScriptText
  • StyleContext
    • StyleText
      • can_break
        • 如果'<','/'在payload中,判定存在xss漏洞
    • StyleComment
    • StyleQuote
    • StyleSingleQuote
    • StyleDoubleQuote

三、W3AF扫描XSS漏洞实例

1.搭建一个有xss漏洞的网站

安装Appserv,快速配置网站,在www目录下创建一个xss文件夹,在xss目录下新建两个文件如下:

test.html

<html>
<head>
<title> XSS 测试  </title>
</head>
<body>
<form action="XSS.php" method="POST">
请输入名字:<br>
<input type="text" name="name" value=""></input>
<input type="submit" value="提交"></input>
</body>
</html>

xss.php

<?php
echo $_REQUEST[name];
?>

 2.在w3af_console下扫描xss漏洞

配置扫描目标URL、配置爬虫webSpider、加载xss插件,扫描过程及结果如下:

w3af>>> target set target http://localhost/xss/test.html
w3af>>> plugins
w3af/plugins>>> discovery webSpider
w3af/plugins>>> discovery config webSpider
w3af/plugins/discovery/config:webSpider>>> set onlyForward True
w3af/plugins/discovery/config:webSpider>>> back
w3af/plugins>>> audit xss
w3af/plugins>>> back
w3af>>> start
Auto-enabling plugin: grep.httpAuthDetect
New URL found by webSpider plugin: http://localhost/xss/XSS.php
New URL found by webSpider plugin: http://localhost/xss/
Found 3 URLs and 9 different points of injection.
The list of URLs is:
- http://localhost/xss/test.html
- http://localhost/xss/XSS.php
- http://localhost/xss/
The list of fuzzable requests is:
- http://localhost/xss/ | Method: GET
- http://localhost/xss/ | Method: GET | Parameters: (C="D", O="A")
- http://localhost/xss/ | Method: GET | Parameters: (C="M", O="A")
- http://localhost/xss/ | Method: GET | Parameters: (C="N", O="A")
- http://localhost/xss/ | Method: GET | Parameters: (C="N", O="D")
- http://localhost/xss/ | Method: GET | Parameters: (C="S", O="A")
- http://localhost/xss/XSS.php | Method: GET
- http://localhost/xss/XSS.php | Method: POST | Parameters: (name="")
- http://localhost/xss/test.html | Method: GET
Cross Site Scripting was found at: "http://localhost/xss/XSS.php", using HTTP me
thod POST. The sent post-data was: "name=<ScRIPT>a=/dmr6/%0Aalert(a.source)</SCR
iPT>". This vulnerability affects ALL browsers. This vulnerability was found in
the request with id 51.
Scan finished in 3 seconds.
w3af>>>

3.验证XSS漏洞

在IE浏览器下关闭XSS过滤,输入

http://localhost/xss/XSS.php?name=<ScRIPT>a=/dmr6/%0Aalert(a.source)</SCRiPT>

可以看到弹窗。

四、小结

本文总结了漏洞扫描相关的几个基本概念,梳理了w3af对xss漏洞检测扫描的基本过程,深入源码进行分析,明白了扫描原理,最后构造一个xss漏洞,使用w3af_console进行XSS扫描,了解了其运行步骤。

留下评论