HGAME-WP

Computer cleaner

先查看端口占用,发现本地开启了80端口,但是页面里并没有什么信息

在网站目录下的upload日志文件中找到了攻击者使用一句话木马查看了~/Documents/flag_part3,里面是第三部分的flag

在攻击者上传的shell.php中找到了第一部分的flag

由于题目中说第二部分是需要对攻击者进行简单溯源,所以想到攻击者ip,在日志中找到攻击者的ip

访问找到第二部分的flag

1
hgame{y0u_hav3_cleaned_th3_c0mput3r!}

Level 24 Pacman

找到初始分数,直接就改成10000分

base64解码后是

1
haeu4epca_4trgm{_r_amnmse}

由于所有的字符都有,所以猜测栅栏密码

1
hgame{u_4re_pacman_m4ster}

Level 69 MysteryMessageBoard

打开猜测要爆破shallot的密码

爆破出密码888888

根据源码,用户访问/admin后admin会访问/也就是留言板

所以可以用xss攻击,让admin访问到/flag返回

在xss平台自定义执行代码

访问/admin目录让admin查看留言板

成功带着flag访问目标地址

1
hgame{W0w_y0u_5r4_9o0d_4t_xss}

Level 47 BandBomb

这题一开始以为是重命名文件能注入命令,做了好久没做出来,之后学长提示是ejs的模板注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
app.post('/rename', (req, res) => {
const { oldName, newName } = req.body;
const oldPath = path.join(__dirname, 'uploads', oldName);
const newPath = path.join(__dirname, 'uploads', newName);

if (!oldName || !newName) {
return res.status(400).json({ error: '请提供旧文件名和新文件名' });
}

fs.rename(oldPath, newPath, (err) => {
if (err) {
return res.status(500).json({ error: '重命名失败: ' + err.message });
}
res.json({ message: '文件重命名成功' });
});
});

漏洞来自于在重命名文件时没有检查./符号导致目录穿越漏洞

将mortis页面移动到public目录下,访问static目录下载

得到mortis.ejs,添加<%= Object.getOwnPropertyNames(this);%>查看当前对象的所有属性,看看有什么可以利用的函数

可以找到有process这个全局对象,由于ejs是运行在浏览器环境里,不能执行系统命令,所以选择查看系统变量

注入<%=JSON.stringify(process.env)%>查看所有环境变量

得到flag:

1
hgame{AVe_mUJIcA_hAS-6ROK3N_uP-but-W3-HavE_umlTaK116}

Computer cleaner plus

查看进程发现ps命令没有权限执行

由于这个文件所有者为root,为当前用户,所以直接添加可执行权限

添加完后执行ps发现报错,得到木马文件名字,也可知/bin/ps不是二进制文件,而是一个脚本

1
2
hgame{B4ck_D0_oR}

HoneyPot

分析代码,找到命令注入漏洞

1
2
3
4
5
6
7
8
9
command := fmt.Sprintf("/usr/local/bin/mysqldump -h %s -u %s -p%s %s |/usr/local/bin/mysql -h 127.0.0.1 -u %s -p%s %s",
config.RemoteHost,
config.RemoteUsername,
config.RemotePassword,
config.RemoteDatabase,
localConfig.Username,
localConfig.Password,
config.LocalDatabase,
)

这里直接拼接命令,导致命令注入

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
config.RemoteHost = sanitizeInput(config.RemoteHost)
config.RemoteUsername = sanitizeInput(config.RemoteUsername)
config.RemoteDatabase = sanitizeInput(config.RemoteDatabase)
config.LocalDatabase = sanitizeInput(config.LocalDatabase)

...

func validateImportConfig(config ImportConfig) error {
if config.RemoteHost == "" ||
config.RemoteUsername == "" ||
config.RemoteDatabase == "" ||
config.LocalDatabase == "" {
return fmt.Errorf("missing required fields")
}

if match, _ := regexp.MatchString(`^[a-zA-Z0-9\.\-]+$`, config.RemoteHost); !match {
return fmt.Errorf("invalid remote host")
}

if match, _ := regexp.MatchString(`^[a-zA-Z0-9_]+$`, config.RemoteUsername); !match {
return fmt.Errorf("invalid remote username")
}

if match, _ := regexp.MatchString(`^[a-zA-Z0-9_]+$`, config.RemoteDatabase); !match {
return fmt.Errorf("invalid remote database name")
}

if match, _ := regexp.MatchString(`^[a-zA-Z0-9_]+$`, config.LocalDatabase); !match {
return fmt.Errorf("invalid local database name")
}

return nil
}

这两处校验中都没有对RemotePassword处理,所以在RemotePassword处注入命令/writeflag,写入flag

访问/flag页面,即可得到flag

1
hgame{8b7c14d6-be92-66b2-97c2-ab20e9417d9c}