HTB Drive Writeup
靶场渗透遇到问题的时候,很难分辨究竟是自己方向对了没有尽力,还是攻击的方向错了。生活也是一样的吧。
扫描探测
使用nmap进行端口扫描:
$nmap -n --min-rate 5000 -T4 10.129.27.104 |
目标开放了22和80端口。
80端口
直接访问80端口会跳转到drive.htb
,在BurpSuite中添加域名解析。
打开首页会有注册和登录页面。
注册页面的http://drive.htb/static/bootstrap/js/jqurey.js
加载慢得离谱。。。
HTB服务器切换到欧洲之后就OK了。
http://drive.htb/100/getFileDetail/
如下FileID响应包为未授权:79、98、99、101
http://drive.htb/79/block/
访问该URL可以查看到隐藏的管理员笔记:
I have created a user for martin on the server to make the workflow easier for you please use the password "Xk4@KjyrYv8t194L!".
martin@drive
登录之后没有找到user的flag,使用linpeas脚本进行系统信息收集。
/usr/local/bin/gitea web --config /etc/gitea/app.ini |
回过去看101的内容,发现有备份计划:
db.sqlite3文件里用户表信息为:
password last_login is_superuser username first_name last_name email |
使用chisel反向代理服务器,访问3000端口的Gitea服务,以martin登录,得到备份文件压缩密码是:H@ckThisP@ssW0rDIfY0uC@n:)
查看仓库变更记录,对密码加密方式进行了多轮修改:
使用hashcat破解密码(而不是john),不同数据库中tomHands的密码是:
sha1$Ri2bP6RVoZD5XYGzeYWr7c$4053cb928103b6a9798b2521c4100db88969525a:johnmayer7 |
使用用户名tom
和密码johnmayer7
可以本地切换至tom用户。
tom@drive
tom用户可以查看用户权限的flag。
用户目录存在特权文件,和配套的使用说明。
-rwSr-x--- 1 root tom 867K Sep 13 2023 doodleGrive-cli |
查看文件的字符串信息可以得到登录用户和密码,运行文件:
tom@drive:~$ ./doodleGrive-cli |
使用Ghidra反编译,能够有用户输入的功能函数只有activate_user_account
,其反编译代码如下:
void activate_user_account(void) |
有两个注意点:
sanitize_string
函数对输入用户名参数进行过滤,黑名单字符为"\\{/| '\n\0"
,可能还有;
(我没仔细看反编译代码)。username
参数的长度限制是40个字符(0x28)
起初我考虑能否实现系统命令的注入,前提是闭合-line
参数里的'
,由于过滤了\
和'
,这一步做不到(🤔)。所以无法实现系统层面的命令注入。
在PayloadsAllTheThings/SQL Injection/SQLite Injection.md里介绍了许多SQLite数据库攻击手法,解决靶场使用的是load_extension
这一个技巧。结合payload长度的限制,这可能是唯一的解法。
SQLite load_extension
解题过程中使用到了如下SQLite官方手册页面:
- Run-Time Loadable Extensions,这里给出了脚手架、编译说明
- Load An Extension,关于
load_extension
的说明 - Enable Or Disable Extension Loading,启用/禁用加载扩展功能
- Built-In Scalar SQL Functions,SQLite内置函数的说明,编写payload时用到
在命令行模式下,使用.dbconfig
查看数据库是否支持加载扩展程序,load_extension on
表示支持,官方手册说默认情况下该项是关闭的(🤔我实际看好像并不是)。
sqlite> .dbconfig |
根据上面链接的脚手架代码,可以简单编写出一个恶意代码:
代码只做了两处简单修改,见红框处:
- 增加了标准库的引用,避免编译时报错;
- 使用
system
命令查看root文件,这里需要注意的是命令参数需要使用绝对路径,例如使用/usr/bin/cat
而不是cat
编译成so文件:gcc -g -fPIC -shared evil.c -o evil.so
命令行模式下使用.load
加载:
kali@kali ~/D/H/M/D/sqlite_load_extension> sqlite3 |
上述命令记录,可以看出加载扩展时需要指定路径(绝对路径或相对路径),使用strace
对没有指定路径时的查找路径进行查看,记录如下:
close(3) = 0 |
为了绕过sanitize_string
函数对/
的过滤,可以使用unhex
或char
函数将16进制或者10进制数转换成字符串:
kali@kali ~/D/H/M/D/sqlite_load_extension> sqlite3 |
其中靶场环境里面SQLite版本低,不支持unhex
函数,只能使用char
函数。
在Opposite of HEX() in SQLite?中,介绍了使用X'43F4124307108902B7A919F4D4D0770D'
来实现hex解码的技巧,但必须要用单引号而单引号被过滤了,因此也无法使用。
sqlite> select X'2E2F61'; |
最终构造的payload是"+load_extension(char(46,47,97))+"
。
一次性传入多个参数的技巧
在本地运行doodleGrive-cli
程序过程中,每次都需要输入用户名和密码,很繁琐。
可使用如下方式快速传递参数:printf 'moriarty\nfindMeIfY0uC@nMr.Holmz!\n5\naaa"\x01\n6\n' | ./doodleGrive-cli