移動智能終端安全課件:SQLite數據泄露_第1頁
移動智能終端安全課件:SQLite數據泄露_第2頁
移動智能終端安全課件:SQLite數據泄露_第3頁
移動智能終端安全課件:SQLite數據泄露_第4頁
移動智能終端安全課件:SQLite數據泄露_第5頁
已閱讀5頁,還剩56頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

SQLite數據泄露12.1基礎知識12.2不安全的全文搜索特性12.3利用SQLiteload_extension進行攻擊小結

12.1基礎知識

12.1.1SQLite的基礎知識

SQLite是一個用小型C庫實現的關系型嵌入式數據庫管理系統,是目前嵌入式系統上最廣泛部署的SQL數據庫引擎。由于SQLite是一個嵌入式數據庫引擎,沒有分離的服務處理過程,因此可以直接讀寫磁盤文件。

SQLite是一個壓縮庫。該庫有250

KB左右,實際大小要考慮到編譯器編譯時的一些選項設置。如果將可選項全部忽略,則庫的大小可被減小為180

KB。SQLite在內存非常受限的設備(如無線設備、PDA、MP3)中是一個非常流行的數據庫引擎,可以運行在小的棧空間上(4

KB),也可以運行在小的堆空間上(100

KB)。SQLite在內存空間占用上和運行速度上比較折中,運行速度高于內存使用量大的數據庫,在較低內存的環境中的性能比較好。

SQLite的開發者繼續擴展功能,同時在保持與前期版本的語法、文件格式完全兼容的情況下提高可靠性和性能,并且源碼對每一個人絕對公開。

SQLite的體系結構主要包括接口、編譯器、虛擬機、B-tree、頁面高速緩存、OS

Interface等,這些內容在前面章節已述,在此不做描述。

SQLite實現了完備的、零配置的SQL數據庫引擎。主要特點有:

(1)事務處理。事務處理具有原子性、一致性、隔離性和持久性,即ACID。

(2)零配置。使用數據庫SQLite時無需安裝,直接運行可執行文件即可。

(3)零服務進程。使用數據庫時,無需通過TCP/IP等通信協議來把SQL語句提交到服務器端。

(4)單個數據文件。數據庫SQLite將用戶的數據存放在單個文件里面。也就是說,一個單獨的磁盤文件存儲一個完整的數據庫。只要用戶對此數據文件有讀/寫權限,即可進行讀/寫操作。

12.1.2SQLite的安全機制

為滿足嵌入式系統對數據庫本身輕便性和對數據存儲效率、訪問速度、內存占用率等性能要求,SQLite采取了不同于大型數據庫的實現機制,但也有潛在的安全隱患。SQLite不提供網絡訪問服務,而使用單一文件存儲數據庫的結構和內容,使得數據庫非常輕便,便于移植。數據庫沒有用戶管理、訪問控制和授權機制,可利用操作系統對文件的訪問控制能力實施文件級別的訪問控制,即凡是操作系統的合法用戶都對數據庫文件具有讀/寫權限,可直接訪問數據庫文件。開源SQLite數據庫不提供加密機制和數據級的保密性。

12.1.3數據庫泄露的基礎知識

下面主要介紹SQL注入攻擊。

SQL注入的原理是將SQL代碼注入或添加到應用(用戶)的輸入參數中進行入侵,并將被注入的參數傳送到后臺的SQL數據庫進行解析與執行。一般情況下,需要構造SQL語句的程序均有可能被入侵者攻擊,因為SQL語句的構造方法和其多樣性均為使用者提供了多種不同的編碼手段。

SQL注入的攻擊方式通常分為兩種。一種是直接將經過精心構造的代碼注入參數中,該參數通常被當作SQL命令并加以執行。另一種是非直接的攻擊方式,首先在特定字符串中插入惡意代碼,然后將帶有惡意代碼的字符串存儲到后臺數據庫的數據表中或者將其當作原數據,當把保存的字符串置入動態的SQL命令中時,惡意代碼會得到執行并對應用產生影響。

動態操縱后臺數據庫的過程,表明數據庫執行了本不該或者不允許被執行的操作。但是,上述示例并沒有完全展現SQL注入漏洞的有效性,僅利用它查看后臺數據庫中所有學生成績的信息,這完全可以通過合法的途徑來實現該功能。由于每個人查詢自己的成績時應該先登錄到校園網,如果該SQL注入發生在學生登錄界面,又會出現什么情況呢?下面再介紹學生登錄校園網頁面的例子,如圖12-1所示。

圖12-1學生登錄窗口

上述示例涉及應用邏輯的概念,應用邏輯是指通過輸入正確的驗證證書查詢后臺數據庫并得到返回記錄,轉而訪問被保護的邏輯層腳本。如果存在SQL注入漏洞,則應用邏輯有可能被破壞。在上述示例中,向URL中注入的字符串(OR'1'='1')被稱為SQL注入滲透測試用例,即payload。通過輸入payload可以檢測是否存在SQL注入漏洞并加以利用得到目標數據。

12.1.4SQL漏洞產生的原因

下面詳細分析造成SQL注入攻擊的原因。

1.構造動態字符串

構造動態字符串是開發人員應用的一種編程技術,允許程序在運行過程中動態地構造SQL查詢語句。開發人員通過構造動態的SQL代碼來創建靈活通用的應用。程序在運行過程中不僅會根據不同的查詢需求決定需要提取哪個字段(如update語句),而且會根據不同的條件來選擇不同的查詢對象。

2.不安全的數據庫配置

通過前面的介紹,了解了保證應用程序的代碼安全是首要任務,但同時數據庫本身的安全問題也值得重視。常用的數據庫在安裝的時候會自動添加默認內容。比如MySQL使用默認的用戶賬戶“root”和“anonymous”,Oracle在創建數據庫時會自動生成“SYSTEM”、“SYS”、“OUTLN”和“DBSNMP”賬戶,SQLServer默認的系統管理員賬戶為“sa”。其他賬戶也是按照默認的方法進行預設置的,口令則眾所周知。

3.回調函數

回調函數是通過函數指針調用的函數。如果把函數的指針(地址)作為參數傳遞給另一個函數,當該指針被用來調用其所指向的函數時,就稱之為回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用,用于對該事件或條件進行響應。

使用回調函數的過程如下:

(1)定義一個回調函數;

(2)提供函數實現的一方在初始化時,將回調函數的函數指針注冊給調用者;

(3)當特定的事件或條件發生時,調用者使用函數指針調用回調函數對事件進行處理。

回調函數的意義如下:因為可以把調用者與被調用者分開,所以調用者無需關心誰是被調用者。調用者只需知道存在一個具有特定原型和限制條件的被調用函數。簡而言之,回調函數就是允許用戶將需要調用的方法的指針作為參數傳遞給一個函數,以便該函數在處理相似事件的時候可以靈活使用不同方法。

回調函數在實際中究竟有什么作用呢?可假設有這樣一種情況:我們需要編寫一個庫,該庫提供某些排序算法的實現方法(如冒泡排序、快速排序、shell排序、shake排序等)。為了能讓庫更加通用且無需在函數中嵌入排序邏輯,而讓使用者來實現相應的邏輯,或者讓庫可用于多種數據類型(int、float、string),此時該怎么辦呢?可以使用函數指針,并進行回調。

回調可用于通知機制。例如,在A程序中設置一個計時器,每到一定時間,A程序會得到相應的通知,但通知機制的實現者對A程序一無所知,則需要一個具有特定原型的函數指針進行回調,通知A程序事件已經發生。實際上,API使用一個回調函數SetTimer()來通知計時器。如果沒有提供回調函數,則API會將一個消息發往程序的消息隊列。

另一個使用回調機制的API函數是EnumWindow(),該函數枚舉屏幕上所有頂層窗口,每個窗口可以通過它調用另一個程序提供的函數并傳遞給窗口的處理程序。EnumWindow()并不關心被調用者在何處,也不關心被調用者用它傳遞的處理程序做了什么,只關心返回值,因為該函數基于返回值選擇繼續執行或退出。

回調函數繼承自C語言。在C++?中,應只在與C代碼建立接口或與已有的回調接口打交道時,才使用回調函數。除了上述情況,在C++?中使用虛擬方法或仿函數都不是回調函數。

12.1.5ASLR的基礎知識

1.ASLR的概念

ASLR的英文全名為AddressSpaceLayoutRandomization,即地址空間布局隨機化。一些攻擊,比如ReturnOrientedProgramming(ROP)之類的代碼復用攻擊,會試圖得到被攻擊者的內存布局信息,以便利用獲取的代碼或者數據位置來定位并進行攻擊。比如可以找到ROP里面的gadget。而ASLR將內存區域隨機分布,以此來提升攻擊者的成功難度。

2.ASLR存在的問題及解決方案

在出現某些漏洞的情況下,比如內存信息泄露,攻擊者會得到部分內存信息,如某些代碼指針。傳統的ASLR只能隨機化整個segment,比如棧、堆或者代碼區。此時攻擊者可通過泄露的地址信息推導別的信息,如另外一個函數的地址等。整個segment的地址都可以推導出來,進而得到更多信息,增加了攻擊利用的成功率。在32位系統中,由于隨機的熵值不高,攻擊者容易通過窮舉法猜出地址。

主要的改進方法有兩種:一是防止內存信息泄露,二是增強ASLR本身。

隨機化的基本單位定義為隨機化粒度。

隨機化的方式可以改進。

隨機化的時間(timing)可以改進。

另外,可用編譯器來幫助定位要migrate的內存位置(指針),并且在每次有輸出時進行動態隨機化。該方法對于網絡應用(例如服務器),如I/O-intensive的應用,可能會導致隨機化間隔極短而性能開銷巨大。

12.2不安全的全文搜索特性

12.2.1SQLite全文搜索特性為支持全文檢索,SQLite提供了FTS(FullTextSearch)擴展的功能。通過在數據庫中創建虛擬表存儲全文索引,用戶可以使用MATCH'keyword'查詢而非LIKE'%keyword%'子串匹配的方式執行搜索,充分利用索引可使速度得到極大提升。如果讀者對搜索引擎原理有初步的了解,則知道在實現全文檢索中對原始內容的分詞是必須的。

自定義分詞器需要實現幾個回調函數(關于回調函數的知識請參看上一小節有關內容),其對應的生命周期如下:①xClose銷毀分詞游標;②xNext獲取下一個分詞結果;③xCreate初始化分詞器;④xDestroy銷毀分詞器;⑤xOpen初始化分詞游標。

分詞器的具體實現可以參考simple_tokenizer(非官方SQLite倉庫)的例子。完成分詞器的配置初始化之后,即可通過創建虛擬表的方式為數據庫建立全文索引,并使用MATCH語句執行更高效的檢索。由于搜索功能的具體細節與本文要討論的內容沒有太大關系,在此不做贅述。

12.2.2

危險的fts3_tokenizer

SQLite3中注冊自定義分詞器用到的函數是fts3_tokenizer,實現代碼是ext/fts3/fts3_

tokenizer.c的scalarFunc函數。支持以下兩種調用方式:

selectfts3_tokenizer(<tokenizer_name>);

selectfts3_tokenizer(<tokenizer_name>,<sqlite3_tokenizer_moduleptr>);

攻擊者僅需要構造一個合適的結構體并獲取其內存地址,使用SQL注入(關于SQL注入請參看上一小節有關內容)等手段讓目標注冊構造好“分詞器”,再通過SQL觸發特殊回調就可以實現對IP寄存器進行劫持,以此執行任意代碼。接下來進一步分析這個攻擊面是否可以被利用。

1.基地址泄露

如果name是已經注冊過的分詞器,只提供參數執行selectfts3_tokenizer(name),將會返回該分詞器對應的內存地址。在fts3.c中可以看到SQLite3默認注冊了內置分詞器simple和porter:

if(sqlite3Fts2HashInsert(pHash,"simple",7,(void*)pSimple)

||sqlite3Fts2HashInsert(pHash,"porter",7,(void*)pPorter)

獲得指針后,即可通過簡單計算獲得libsqlite3.so的基地址,從而繞過ASLR(關于ASLR的基本知識請參看上一小節),如圖12-2所示。

圖12-2獲得libsqlite3.so的基地址

2.任意代碼運行

通過觸發xCreate回調可執行任意代碼。運行64位的SQLite3控制臺,輸入如下查詢語句即可導致段錯誤:

新的問題是程序并非直接跳轉到傳入的地址,而是在該地址上獲取一個結構體的成員。要實現可控的跳轉,需要可以寫入指針的地址。既然已有libsqlite的基地址泄露,那么可以通過PRAGMA語句實現純SQL向其?.bss段寫入。使用此語句可以在數據庫打開的過程中修改全局的狀態,以及訪問數據庫元數據等。

3.

PoC

通過以上分析,該攻擊面可以通過如下方式觸發:

(1)通過SQL注入泄漏libsqlite3的地址,注意結果是大端序。

(2)通過selectsqlite_version()函數泄漏版本,針對具體版本調整偏移量。

(3)執行PRAGMAsoft_heap_limit語句布置需要call的目標指令地址。

(4)將libsqlite3的.bss段中的結構體地址轉成大端序的blob,然后注冊分詞器。

(5)創建虛擬表,觸發xCreate回調,執行代碼。

12.2.3多種場景下攻擊分析

利用以上知識可以在下列場景下進行相應攻擊。

1.

SQL注入Web應用遠程執行代碼

使用union或盲注可泄露libsqlite3的基地址。在使用mod_PHP方式執行PHP的服務器上,得到的地址可在多次請求中保持不變。通過計算可用的地址,可觸發代碼執行。因為PHP的SQLite3擴展中的exec方法支持使用分號分隔多個語句,因此可以使用注入的方式觸發任意代碼執行。

2.繞過PHP安全配置執行任意命令

就PHP而言,可利用任意代碼執行來繞過php.ini的open_basedir和disable_functions配置,以進一步提權。

劫持IP寄存器的POC已經給出,可獲得一次call任意地址的機會。但是只能執行一次任意代碼,也沒有合適的棧遷移指令來實現rop,實現系統shell還需要解決一些問題。在調用xCreate的上下文中存在多個可控參數,但單純靠libsqlite3找不到合適的gadget進行組合利用。在exploit中采用了迂回做法,使用另一處xOpen回調和PHP中一處調用了popen的gadget來實現任意命令執行。

為了讓xCreate正常返回,可將其設置為simple分詞器自帶的simpleCreate函數指針。但PRAGMA語句只能修改一個指針,而現在需要至少三個連續的QWORD可控。這可以通過堆噴射的方式實現,也可以再次尋找可以修改的.bss段。

在源代碼中搜索宏STD_PHP_INI_ENTRY,找到訪問標記PHP_INI_SYSTEM或者PHP_INI_ALL,用OnUpdateLong可獲取數值的配置。在32位系統上可以使用OnUpdateBool的選項,或直接調用assert_options函數直接修改assert模塊中連續的一塊內容。滿足要求的選項不少,如可以使用mysqlnd的net_cmd_buffer_size和log_mask。

3.

AndroidContentProvider

經過測試發現,無論是SQLiteDatabase的executeSQL方法還是query方法,都不支持使用分號分隔一次執行多個語句。然而觸發的關鍵語句(如“創建虛擬表”等)都不能通過子查詢進行構造,因此從ContentProvider的注入點上只能實現注冊,而不能觸發回調也不能使用PRAGMA。由于每個App都由Zygotefork而來,只需要讀取自身進程的maps就可以得到其他進程的內存布局。

4.

Webkit上的WebSQL

Webkit提供WebSQL數據庫,可在瀏覽器內創建供客戶端使用的關系數據庫存儲。雖然沒有被HTML

5標準采納,但該功能被保留了下來。在支持WebSQL的瀏覽器中,先使用window.openDatabase方法打開一個數據庫實例,再使用數據庫實例的transaction方法創建一個事務,便可以通過事務對象執行SQL查詢。

5.緩解和修補

濫用某些特性可能導致應用程序產生攻擊面,禁用某些特性可以起到緩解的效果。以上提到的AOSP、WebKit等開源項目對此設計了下列不同的緩解方案,具有很重要的參考價值。

(1)如果用不到全文檢索,可通過關閉SQLITE_ENABLE_FTS3/SQLITE_EN-ABLE_

FTS4/SQLITE_ENABLE_FTS5選項禁用之,或者使用Amalgamation版本編譯。

(2)如果需要使用MATCH檢索,但無需支持多國語言(即內置分詞器可以滿足要求),則在ext/fts3/fts3.c中注釋如下代碼關閉此函數,具體代碼如下:

&&SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,pHash,"fts3_tokenizer"))

(3)使用SQLite3的AuthorizationCallbacks設置訪問控制。

12.3利用SQLiteload_extension進行攻擊

SQLite從3.3.6版本開始提供支持擴展功能,通過SQLiteload_extensionAPI(或者load_extensionSQL語句),開發者可以在不改動SQLite源碼的情況下,通過動態加載的庫(so/dll/dylib)來擴展SQLite的功能,如圖12-3所示。圖12-3

SQLiteLoadAnExtension接口

便利的功能總是最先被黑客利用來實施攻擊。借助SQLite動態加載的特性,僅需要在可以預測的存儲路徑中預先放置一個覆蓋SQLite擴展規范的動態庫(Android平臺的so庫),通過SQL注入漏洞調用load_extension,即可很輕松地激活庫中的代碼,直接形成遠程代碼執行漏洞。國外黑客早就提出使用load_extension和SQL注入漏洞來進行遠程代碼執行攻擊的方法,如圖12-4所示。

圖12-4

load_extension結合SQL實現遠程代碼執行攻擊

SQLite官方(/cgi/src/info/4692319ccf28b0eb)在代碼中將load_extension的功能設置為“默認關閉”,需要在代碼中通過sqlite3_enable_load_extensionAPI顯式打開后方可使用,因此API無法在SQL語句中調用,斷絕了利用SQL注入打開的可能性,如圖12-5所示。

圖12-5

SQLite官方發布的load_extension有關聲明

1.?Android平臺下的SQLiteload_extension支持

出于功能和優化的目的,Google從Android4.1.2開始通過預編譯宏SQLITE_OMIT_LOAD_EXTENSION,從代碼上直接移除了SQLite動態加載擴展的功能,如圖12-6所示。

圖12-6預編譯宏SQLITE_OMIT_LOAD_EXTENSION

可通過adbshell來判斷Android系統是否默認支持load_extension,Android?4.0.3以下版本中sqlite3的.help命令如圖12-7所示。

2.?Android平臺下的SQLiteextension模塊編譯

SQLiteextension必須包含sqlite3ext.h頭文件,實現一個sqlite3_extension_init入口。圖12-8所示為一個SQLiteextension的基本框架。

圖12-8

SQLiteextension的基本框架

圖12-9所示為Android.mk文件。

圖12-9

Android.mk文件

可以利用SQLiteextension的基本框架實現加載時打印log輸出的SQLiteextension,如圖12-10所示。

圖12-10在

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論