我們需要一種工具。許多安全機構和人員提出了不少對付這種攻擊的方法。今天我們看一個不錯的工具GreenSQL,可以說它是一個MySQL數據庫防火墻,可以過濾SQL注入攻擊。
【51CTO.com 獨家特稿】SQL注入攻擊的危害早已為人所熟知,這種攻擊準許攻擊者在你的數據庫上執(zhí)行任意的SQL命令。要對付這種攻擊,我們對于Web用戶 所提供的任何數據,不管是通過HTTP方式,還是通過CGI參數方式提供的,都要經過驗證,以確保其不包含非法信息。
這是解決問題的根本之道。我們需要一種工具。許多安全機構和人員提出了不少對付這種攻擊的方法。今天我們看一個不錯的工具GreenSQL,可以說它是一個MySQL數據庫防火墻,可以過濾SQL注入攻擊。
它位于網站和MySQL數據庫之間,可以決定哪些SQL語句可以執(zhí)行,哪些不應當執(zhí)行。再加上其Web界面,使得 用戶可以通過瀏覽器來管理GreenSQL。GreenSQL的設計目的就是用作MySQL數據庫的一個代理服務器。它不是將用戶的請求直接連接到MySQL數據庫,而是連接到GreenSQL。 GreenSQL將合法的SQL提交給MySQL數據庫并返回結果。
如果GreenSQL檢測到一條不屬于白名單并包含惡意SQL的語句,它將阻止此SQL 并返回一個空結果,不與MySQL數據庫發(fā)生聯(lián)系。筆者完成此文時,Fedora、openSUSE、 Ubuntu 等Linux發(fā)行版本并沒有包含GreenSQL。
在本文中,筆者將在一臺64位的Fedora 9計 算機上從源代碼安裝greensql-fw 0.8.4。安裝過程并沒有使用自動化的工具,所以必須手動設置一些東西,如配置文件、系統(tǒng)用戶、MySQL配置、日志文件、/etc/init.d等。 這些過程在install.txt文件中有明確說明,所以并不太費力。當然,通過執(zhí)行腳本字典中的幾個腳本外殼,你也可以完成安裝的不 少內容。為編譯應用程序,可以簡單地執(zhí)行“make”,如下所示:
$ tar xzf /.../greensql-fw-0.8.4.tar.gz
$ cd greensql-fw-0.8.4/
$ make
...
connection.hpp:29: error: field 'proxy_event' has incomplete type
connection.hpp:30: error: field 'client_event' has incomplete type
|
可以看出,在編譯開始后,我們收到了幾個錯誤,這是由于在Fedora 9上安裝時,筆者并沒有安裝libevent-devel。在安裝好libevent-devel后,又發(fā)現需要修改/usr/include/event.h,為編譯事件代碼,需要將sys/types.h包括進去。
vi /usr/include/event.h ... #include #include #include #include
|
在使用“make -k”命令時,有幾個文件又出現了差錯,這些文件調用了字符串函數,如“strcasecmp”,這是由于沒有包括 string.h頭文件所致。對讀者來說,根據所使用的gcc的版本的不同,在編譯GreenSQL時,可能會出現類似或不類似于下面的一些問 題:
$ cd src $ vi mysql/mysql_con.cpp ... // License: GPL v2 (http://www.gnu.org/licenses/gpl.html) // #include
#include "mysql_con.hpp" ... $ vi config.hpp ... #ifndef GREEN_SQL_CONFIG_HPP #define
GREEN_SQL_CONFIG_HPP #include ... $ vi ../src/parser/expression.hpp ... #ifndef _SQL_EXPRESSION_HPP_
#define _SQL_EXPRESSION_HPP_ #include ...
|
如果你在一個64位的發(fā)行版本上編譯GreenSQL,可能還需要稍稍修改Makefile,這樣編譯生成程序才能檢查lib64而不是lib目錄,如 下所示:
$ vi src/Makefile ... LIBS:=-L/usr/local/lib -L/usr/local/lib/mysql -L/usr/lib64/mysql -lmysqlclient -levent -lpcre
greensql-fw: $(OBJS) ... $ make
|
編譯完成,下面顯示的完成安裝的命令:
greensql-fw-0.8.4]# cd ./scripts/ # ./setup_user.sh done... # ./greensql-create-db.sh -----------------------------
---------------- The following settings will be used: MySQL admin user: [root] MySQL admin password: [] MySQL server
address: [127.0.0.1] GreenSQL configuration DB name: [greendb] DB user to create: [green] Password to set: [pwd] Do
you want to change anything? [y/N] y MySQL admin user [root]: MySQL admin password []: XXxxXXxxXXxx-FIXME MySQL
server address (you can use ip:port string) [127.0.0.1]: GreenSQL config db name [greendb]: GreenSQL DB user name
[green]: greendb GreenSQL DB user password [pwd]: greendbpass --------------------------------------------- The
following settings will be used: Do you want to change anything? [y/N] Creating MySQL database... Adding MySQL user... Creating MySQL tables... GreenSQL configuration file is not writable!!! Check that [database] section
contains the following settings in /etc/greensql/greensql.conf [database] dbhost=127.0.0.1 dbname=greendb
dbuser=greendb dbpass=greendbpass # dbport=3306 ... # ./setup_conf.sh done... # ./setup_log.sh done... #
./setup_binary.sh done... # vi /etc/greensql/greensql.conf ... [database] dbhost=127.0.0.1 dbname=greendb
dbuser=greendb dbpass=greendbpass ... # chkconfig --add greensql service greensql does not support chkconfig #
/etc/init.d/greensql start
|
軟件包的install.txt文件描述了手動安裝方法,與腳本所使用的命令相同。使用腳本可能更好一些,因為這樣可以提高安裝速度, 而安裝程序基本相同。安裝指南推薦在/etc/greensql目錄之前設置MySQL數據庫,不過如果你這樣做的話,有可能無法找到配置文件 ,所以你必須手動更改/etc/greensql/greensql.conf文件。你對greensql.conf作出的唯一主要更改是獲取MySQL數據庫參數。為測試需要,筆者創(chuàng)建了一個稱為“test”的數據庫,并允許用戶“ben”自由訪問,命令如下:
# mysql -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> GRANT ALL ON test.* TO ben@"%";
mysql> FLUSH PRIVILEGES;
|
默認情況下,GreenSQL運行在3305端口上,小于MySQL的默認端口(3306)。如果你使用mysql控制臺客戶端并連接到GreenSQL的3305 端口上,你將無法創(chuàng)建新表。如果你直接通過3306端口連接到MySQL,就可以創(chuàng)建新表。
$ mysql --verbose -h 127.0.0.1 -P 3305 test
mysql> create table foo ( id int );
--------------
create table foo ( id int )
--------------
Query OK, 0 rows affected (0.01 sec)
mysql> insert into foo values ( 55 );
--------------
insert into foo values ( 55 )
--------------
ERROR 1146 (42S02): Table 'test.foo' doesn't exist
$ mysql --verbose -h 127.0.0.1 -P 3306 test
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> create table foo ( id int );
--------------
create table foo ( id int )
--------------
Query OK, 0 rows affected (0.01 sec)
mysql> insert into foo values ( 55 );
--------------
insert into foo values ( 55 )
--------------
Query OK, 1 row affected (0.00 sec)
mysql> insert into foo values ( 131 );
--------------
insert into foo values ( 131 )
--------------
Query OK, 1 row affected (0.00 sec)
mysql> select * from foo;
--------------
select * from foo
--------------
+------+
| id |
+------+
| 55 |
| 131 |
+------+
2 rows in set (0.00 sec)
|
如果使用默認配置,你將無法通過GreenSQL防火墻丟棄數據表。這倒無妨,因為表結構不太可能經常改變,更不可能通過Web界面改 變。
$ mysql --verbose -h 127.0.0.1 -P 3305 test
Welcome to the MySQL monitor. Commands end with ; or \g.
mysql> select * from foo;
--------------
select * from foo
--------------
+------+
| id |
+------+
| 55 |
| 131 |
+------+
2 rows in set (0.00 sec)
mysql> drop table foo;
--------------
drop table foo
--------------
Query OK, 0 rows affected (0.00 sec)
mysql> select * from foo;
--------------
select * from foo
--------------
+------+
| id |
+------+
| 55 |
| 131 |
+------+
2 rows in set (0.01 sec)
|
注入測試看來沒有如所期望的那樣正常工作。第一次測試是在條件一直為真時刪除表。這會清除表內的所有數據,留下一個空表。默 認地此查詢會通過防火墻進行:
$ mysql --verbose -h 127.0.0.1 -P 3305 test
mysql> delete from foo where 1=1;
--------------
delete from foo where 1=1
--------------
Query OK, 2 rows affected (0.00 sec)
mysql> select * from foo;
--------------
select * from foo
--------------
Empty set (0.00 sec)
|
對于上面的SQL刪除命令來說,/var/log/greensql.log文件包含了下面的信息:
SQL_DEBUG: QUERY command[]: delete from foo where 1=1
SQL_DEBUG: AFTER NORM : delete from foo where ?=?
SQL_DEBUG: RISK : 0
|
/etc/greensql/greensql.conf文件準許你設置某些內容的風險程度。例如,你可以將10指定給union關鍵字使用,或者在查詢中使用 直接的變量比較(如同1=2之類的東西)。這些變量包括“block_level = 30”,所以RISK大于30的任何查詢都不轉發(fā)給MySQL服務器 。為了讓GreenSQL標記出上面的查詢,筆者將risk_var_cmp_var 和 risk_always_true從默認的30增加至150。但很不幸,這次查詢 看起來仍是風險為零。
SQL_DEBUG: QUERY command[]: delete from foo where id=181 or 1=1
SQL_DEBUG: AFTER NORM : delete from foo where id=? or ?=?
SQL_DEBUG: RISK : 0
SQL_DEBUG: QUERY command[]: delete from s where comment = 'whatever' or '1'='1'
SQL_DEBUG: AFTER NORM : delete from s where comment = ? or ?=?
SQL_DEBUG: RISK : 0
|
筆者做了許多嘗試,結果都是一樣的,即GreenSQL都將前面的不懷好意的查詢的風險看成是零,筆者又試用了一下SELECT查詢。這竟然 是使GreenSQL工作的一個關鍵,即可以阻止惡意查詢,如日志文件的一個片斷部分所示:
SQL_DEBUG: QUERY command[]: select * from folks where name='sam' or '1'='1'
SQL_DEBUG: AFTER NORM : select * from folks where name=? or ?=?
DEBUG: Query has 'or' token
DEBUG: Variable comparison only
SQL_DEBUG: RISK : 35
|
由于select語句中的SQL注入允許用戶在沒有口令的情況可以登錄進入一個站點,讓GreenSQL檢查一下你的select未嘗不是一個好主 意。不過,筆者希望GreenSQL的未來版本可以將保護擴展到delete語句,因為它可以清除整個數據表。
【51CTO.COM 獨家特稿,轉載請注明出處及作者!】
【編輯推薦】
- 基于IE的MIME sniffing功能的跨站點腳本攻擊
- 惡意軟件反檢測技術簡介:模擬器超限技術
- 安全專家詳談:對付惡意軟件的策略及方法