enterprisedb是基於postgresql的企業級數據庫(即PPAS)。



 

PPAS(Postgres Plus Advanced Server) 提供了SQL注入攻擊保護,按下面講
a 概述
b 配置
c 通常維護操作
d 備份/恢復sql注入保護數據庫


 

SQL注入攻擊是駭客對數據庫進行攻擊的常用手段之一。隨著B/S模式應用開發的發展,使用這種模式編寫應用程式的程式員也越來越多。但是由於程式員的水準及經驗也參差不齊,相當大一部分程式員在編寫代碼的時候,沒有對用戶輸入數據的合法性進行判斷,使應用程式存在安全隱患。用戶可以提交一段數據庫查詢代碼,根據程式返回的結果,獲得某些他想得知的數據,這就是所謂的SQL Injection,即SQL注入。SQL注入是從正常的WWW埠訪問,而且表面看起來跟一般的Web頁面訪問沒什麼區別,所以目前市面的防火牆都不會對SQL注入發出警報,如果管理員沒查看IIS日誌的習慣,可能被入侵很長時間都不會發覺。但是,SQL注入的手法相當靈活,在注入的時候會碰到很多意外的情況,需要構造巧妙的SQL語句,從而成功獲取想要的數據。

 

PPAS提供SQL注入攻擊保護。SQL注入攻擊保護一般是應用開發人員的責任,數據庫管理員則無能為力。PPAS通過檢查傳入的SQL提供SQL注入攻擊保護。
SQL保護提供給數據庫管理員反饋潛在的危險查詢和阻塞這些查詢。

 

1
概述
這屆介紹各種不同種類的SQL注入攻擊和SQL注入攻擊保護是怎麼防止攻擊的。

 

1.1
SQL注入攻擊類型
有多種不同技術的SQL注入攻擊,每種技術都有某種signature。SQL注入攻擊檢查查詢中是否有下列signature:
a Unauthorized Relations/未授權的關系
PPAS允許管理員對關系的訪問進行控制,但很多管理員不做這些乏味的工作。
SQL注入攻擊保護(SQL/Protect)提供了一個學習模型對用戶訪問的關系進修跟蹤。
這也許管理員確認應用程式的負載,並且,SQL/Protect也學習哪些用戶會訪問哪些關系。
當SQL/Protect被切到被動或主動模式時,會對傳入的查詢檢查要學習的關系。

 

b Utility Commands/工具命令
在SQL注入攻擊中經常會用到一些常用命令,像典型的DDL語句。例如創建用戶定義函數以訪問系統其他資源。
SQL/Protect能夠阻塞這些在應用程式中通常不使用的SQL命令的運行。

 

c SQL Tautology/ 同意的SQL
在SQL注入攻擊中使用最頻繁的技術是在WHERE子句中增加部分內容,例如WHERE password = 'x' OR 'x'='x',
攻擊者通常以這種方式尋找安全薄弱環節,SQL/Protect能夠阻塞這類查詢。

 

具體的攻擊方法可以參見我轉載的《SQL注入攻擊》
1.1.1
受保護的角色
監控SQL注入攻擊涉及到分析受保護的角色的session裏的SQL語句。
受保護的角色是PPAS數據庫管理員選擇的要監控的數據庫角色。(PPAS裏,用戶和組統稱為角色)
每個受保護的角色可定制要監控的SQL注入攻擊類型(1.1節中討論的),從而提供不同程度的保護,並顯著地降低了DBA維護用戶的工作量。

 

注意:
超級用戶不能作為受保護的角色。如果受保護的角色後來成了超級用戶,該角色的某些行為
將被顯示:
a 當這個受保護的superuser的每一個sql命令被SQL/Protect拋一個警告資訊。
b 受保護的superuser執行每一個命令,都會在統計資訊視圖edb_sql_protect_stats中
的superusers列都會加1.
c 當SQL/Protect是active模式時,所有受保護superuser用戶執行的命令被禁止運行。

 

1.1.2
攻擊統計:
受保護用戶的每一個命令被SQL/Protect當作攻擊而記錄。這些條件能通過試圖訪問以
識別攻擊的開始。
如果受保護用戶連接了多個數據庫,這個用戶的攻擊統計資訊分別存放在連接的數據庫裏。
注意:
數據庫運行時SQL/Protect統計資訊維護在內存裏。數據庫停止運行後,這些資訊存放在
data/global裏面的二進制檔edb_sqlprotect.stat裏。

 

2
配置SQL/Protect
在PPAS的lib目錄裏必須安裝了其程式庫檔(linux上是sqlprotect.so,windows上是sqlprotect.dll)SQL/Protect才能運行。
還必須在share/contrib檔夾裏有sqlprotect.sql腳本。

 

必須配置數據庫服務器使用SQL/Protect,並且配置每一個要監控的數據庫。
a 必須配置postgresql.conf相關參數
b 必須在要監控的數據庫裏安裝SQL/Protect要用的數據庫對象。

 

配置步驟1:
修改postgresql.conf裏的如下參數:
shared_preload_libraries: 增加$libdir/sqlprotect
custom_variable_classes: 增加edb_sql_protect
edb_sql_protect.enabled: 是否啟動SQL/Protect,默認是off,最後設這個。
edb_sql_protect.level: 設置當SQL命令執行時SQL/Protect採取的行為。
缺省是passive。初始時設置為learn。
edb_sql_protect.max_protected_roles: 設置保護的最大用戶數。默認是64個
edb_sql_protect.max_protected_relations: 設置每個用戶保護的最大關系數。默認是1024個。

 

例如:
shared_preload_libraries = '$libdir/dbms_pipe,$libdir/edb_gen,$libdir/plugins/plugin_debugger,$libdir/plugins/plugin_spl_debugger,$libdir/sqlprotect'
# (change requires restart)
custom_variable_classes = 'dbms_pipe, dbms_alert, edb_sql_protect' # list of custom variable class names
edb_sql_protect.enabled = off
edb_sql_protect.level = learn
edb_sql_protect.max_protected_roles = 64
edb_sql_protect.max_protected_relations = 1024

 

配置步驟2:
重啟數據庫

 

配置步驟3:
以superuser連接到每個受保護的數據庫並運行share/contrib裏的sqlprotect.sql腳本。
這個腳本創建了模式sqlprotect並在裏面創建數據庫對象。
下面的例子顯示了在數據庫edb裏
$ /opt/PostgresPlus/9.1AS/bin/psql -d edb -U enterprisedb
Password for user enterprisedb:
psql (9.1.1.0)
Type "help" for help.
edb=# \i /opt/PostgresPlus/9.1AS/share/contrib/sqlprotect.sql
CREATE SCHEMA
GRANT
SET
CREATE TABLE
GRANT
。。。

 

2.1
選擇受保護的角色
現在受保護的角色和保護級別。

 

2.1.1
設置受保護角色清單
對於每一個受保護的數據庫,確定要監控的角色/用戶增加到該數據庫的受保護角色清單。
步驟一:
連接到數據庫
$ /opt/PostgresPlus/9.1AS/bin/psql -d edb -U enterprisedb
Password for user enterprisedb:
psql (9.1.1.0)
Type "help" for help.
edb=#

 

步驟二:
把模式sqlprotect設置到查詢路徑
edb=# SET search_path TO sqlprotect;
SET

 

--增加-- create user appuser password 'appuser';

 

步驟三:
受保護的角色維護在表edb_sql_protect裏,用函數protect_role('rolename')增加角色。
增加角色appuser
--ERROR: SQLPROTECT: Protected user hash not initialized
edb=# SELECT protect_role('appuser');
protect_role
--------------
(1 row)
從表中驗證結果:
edb=# SELECT * FROM edb_sql_protect;
dbid | roleid | protect_relations | allow_utility_cmds | allow_tautology | allow_empty_dml
-------+--------+-------------------+--------------------+-----------------+-----------------
13917 | 16671 | t | f | f | f
(1 row)

 

從視圖中驗證結果:
edb=# \x
Expanded display is on.
edb=# SELECT * FROM list_protected_users;
-[ RECORD 1 ]------+--------
dbname | edb
username | appuser
protect_relations | t
allow_utility_cmds | f
allow_tautology | f
allow_empty_dml | f

 

2.1.2
設置保護級別
edb_sql_protect.level設置保護級別,其決定受保護用戶執行sql語句時SQL/Protect的行為。
其定義的級別決定的行為應用到該數據庫服務器上所有數據庫中受保護的用戶上。

 

edb_sql_protect.level看設置的值為:
learn: 跟蹤受保護用戶的行為和記錄其用到的表。初始時設置。
passive: 如果受保護的角色違反了定義的規則,拋一個警告,但不中斷然後sql的執行。
這是SQL/Protect學習了保護角色的期望行為後要設置這個。
active:為受保護角色停止執行所有無效語句。就像sql防火牆一樣不讓危險語句執行。
默認為passive,如果第一次用SQL/Protect,設置edb_sql_protect.level為learn
2.2
監控受保護的角色
一旦配置了SQL/Protect、受保護用戶、保護級別,就可以運行應用程式了。
接著應該確定受保護的角色應該可以訪問哪些關系。learn模式允許SQL/Protect記錄
受保護用戶訪問過的關系到該角色的受保護關系列表 edb_sql_protect_rel裏。

 

當SQL/Protect運行於passive或active模式時保護免受攻擊的監控就開始了。
在passive或active模式時,角色允許訪問受保護關系列表裏的關系。

 

但是,如果角色嘗試訪問其受保護關系列表裏的關系之外的關系,SQL/Protect會返回
一個warnning或error。該sql語句是否被執行依賴於模式是passive還是active。

 

2.2.1
learn模式

 

步驟1:
在postgresql.conf裏配置如下參數:
edb_sql_protect.enabled = on
edb_sql_protect.level = learn

 

步驟2:
加載postgresql.conf檔
以超級用戶連接到數據庫,執行下面的函數pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)
步驟3:
允許受保護用戶運行其應用
以受保護角色appuser在psql裏運行下面的sql。
edb=> SELECT * FROM dept;
NOTICE: SQLPROTECT: Learned relation: 16384
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
(4 rows)
edb=> SELECT empno, ename, job FROM emp WHERE deptno = 10;
NOTICE: SQLPROTECT: Learned relation: 16391
empno | ename | job
-------+--------+-----------
7782 | CLARK | MANAGER
7839 | KING | PRESIDENT
7934 | MILLER | CLERK
(3 rows)
上面的NOTICE指明關系增加到了該用戶的受保護關系列表裏。

 

在learn模式裏,不阻止懷疑sql的運行,但或給一個notice提醒
edb=> CREATE TABLE appuser_tab (f1 INTEGER);
NOTICE: SQLPROTECT: This command type is illegal for this user
CREATE TABLE
edb=> DELETE FROM appuser_tab;
NOTICE: SQLPROTECT: Learned relation: 16672
NOTICE: SQLPROTECT: Illegal Query: empty DML
DELETE 0

 

步驟4:
以受保護用戶運行的應用,會查詢受保護的表以觀察/發現增加到該角色的受保護關系列表裏的關系。
以超級用戶連接到監控的數據庫並設置查詢路徑包含模式sqlprotect
edb=# SET search_path TO sqlprotect;
SET

 

在表edb_sql_protect_rel裏查看增加到受保護關系列表裏的關系:
edb=# SELECT * FROM edb_sql_protect_rel;
dbid | roleid | relid
-------+--------+-------
13917 | 16671 | 16384
13917 | 16671 | 16391
13917 | 16671 | 16672
(3 rows)
在試圖list_protected_rels裏查看更易於理解的資訊
edb=# SELECT * FROM list_protected_rels;
Database | Protected User | Schema | Name | Type | Owner
----------+----------------+--------+-------------+-------+--------------
edb | appuser | public | dept | Table | enterprisedb
edb | appuser | public | emp | Table | enterprisedb
edb | appuser | public | appuser_tab | Table | appuser
(3 rows)

 

2.2.2
passive模式

 

用到確定受保護角色的應用已經訪問了其要用到的所有關系,就可以改變保護級別
以加快傳入的SQL語句而防止sql注入攻擊。

 

passive模式是兩個保護模式passive和active裏不嚴格的。

 

步驟1
在postgresql.conf裏配置如下參數,啟動SQL/Protect為passive模式
edb_sql_protect.enabled = on
edb_sql_protect.level = passive

 

步驟2
加載postgresql.conf檔
以超級用戶連接到數據庫,執行下面的函數pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

 

以appuser運行下面的語句,沒有問題,因為已經學習了dept和emp。
edb=> SELECT * FROM dept;
deptno | dname | loc
--------+------------+----------
10 | ACCOUNTING | NEW YORK
20 | RESEARCH | DALLAS
30 | SALES | CHICAGO
40 | OPERATIONS | BOSTON
(4 rows)
edb=> SELECT empno, ename, job FROM emp WHERE deptno = 10;
empno | ename | job
-------+--------+-----------
7782 | CLARK | MANAGER
7839 | KING | PRESIDENT
7934 | MILLER | CLERK
(3 rows)

 

運行sql訪問不在受保護清單裏的關系或有危險的sql語句,不會阻止sql運行,但會給一個warning。
edb=> CREATE TABLE appuser_tab_2 (f1 INTEGER);
WARNING: SQLPROTECT: This command type is illegal for this user
CREATE TABLE
edb=> INSERT INTO appuser_tab_2 VALUES (1);
WARNING: SQLPROTECT: Illegal Query: relations
INSERT 0 1
edb=> INSERT INTO appuser_tab_2 VALUES (2);
WARNING: SQLPROTECT: Illegal Query: relations
INSERT 0 1
edb=> SELECT * FROM appuser_tab_2 WHERE 'x' = 'x';
WARNING: SQLPROTECT: Illegal Query: relations
WARNING: SQLPROTECT: Illegal Query: tautology
f1
----
1
2
(2 rows)

 

步驟3
監控可疑行為的統計資訊

 

通過查詢視圖edb_sql_protect_stats,可以查看訪問不在受保護清單裏的關系
和有危險的sql的次數。
視圖edb_sql_protect_stats列如下:
username:受保護角色的名字
superusers:當受保護角色是超級用戶時執行的sql語句數。
relations:訪問量受保護關系列表裏沒有的關系的sql語句的數量
commands: 受保護角色運行的DDL語句的數
tautology: 受保護角色運行的包含同意條件的sql語句數
dml: 受保護角色運行的不包含where子句的update和delete語句數

 

查一個看看
edb=# SET search_path TO sqlprotect;
SET
edb=# SELECT * FROM edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 3 | 1 | 1 | 0
(1 row)

 

2.2.3
active模式
active模式裏,不允許sql語句執行,而且,或拋一個error代替warning。

 

步驟1

 

在postgresql.conf裏配置如下參數,啟動SQL/Protect為passive模式
edb_sql_protect.enabled = on
edb_sql_protect.level = active

 

步驟2
加載postgresql.conf檔
以超級用戶連接到數據庫,執行下面的函數pg_reload_conf().
edb=# SELECT pg_reload_conf();
pg_reload_conf
----------------
t
(1 row)

 

以appuser執行sql語句:
edb=> CREATE TABLE appuser_tab_3 (f1 INTEGER);
ERROR: SQLPROTECT: This command type is illegal for this user
edb=> INSERT INTO appuser_tab_2 VALUES (1);
ERROR: SQLPROTECT: Illegal Query: relations
edb=> SELECT * FROM appuser_tab_2 WHERE 'x' = 'x';
ERROR: SQLPROTECT: Illegal Query: relations

 

查詢統計資訊
edb=# SELECT * FROM sqlprotect.edb_sql_protect_stats;
username | superusers | relations | commands | tautology | dml
----------+------------+-----------+----------+-----------+-----
appuser | 0 | 5 | 2 | 1 | 0
(1 row)
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()