前置知識(shí)

GraphQL查詢方式

GraphQL是一種用于API的查詢語(yǔ)言,首先我們就需要知道GraphQL有哪些查詢方式。

主要有:

其中最為常見的是Query、Mutation、Subscription這三種,Query用于向服務(wù)端查詢指定數(shù)據(jù)、Mutation用于在服務(wù)端修改或添加數(shù)據(jù),具體可參考官方文檔進(jìn)行了解:https://graphql.org/learn/

GraphQL內(nèi)省查詢

簡(jiǎn)單來說就是,GraphQL內(nèi)查機(jī)制,通常是內(nèi)部可用,通過內(nèi)省的方法獲得相關(guān)信息,如對(duì)象定義、接口參數(shù)等信息。一般查詢前面帶有雙下劃線的就表示內(nèi)省的一部分,比如:__Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive等,官方文檔:https://graphql.org/learn/introspection/

GraphQL API發(fā)現(xiàn) 

當(dāng)我們?cè)跍y(cè)試時(shí),如何發(fā)現(xiàn)GraphQL API?下面介紹幾種有效的方法。


常見的GraphQL路徑判定

GraphQL API與Restful API不同,一般來說它的URL比較固定,這也是它的特性之一,從單個(gè)請(qǐng)求中獲取應(yīng)用程序所需的所有數(shù)據(jù)。

常見的GraphQL路徑如下:

/graphql
/graphiql
/v1/graphql
/v2/graphql
/v3/graphql
/v1/graphiql
/v2/graphiql
/v3/graphiql
/api/graphql
/api/graphiql
/graphql/api
/graphql/console
/console
/playground
/gql
/query
/graphql-devtools
/graphql-explorer
/graphql-playground
/graphql.php
/index.php?graphql
......

通用查詢探測(cè)

由于GraphQL API中存在一個(gè)__typename 的保留字段,該字段會(huì)以字符串形式返回查詢對(duì)象的類型,所以我們可以向未知API發(fā)送query{__typename},如果響應(yīng)中返回{“data”: {“__typename”: “query”}},那么就可以確定該API為GraphQL API。

內(nèi)省查詢

向未知API發(fā)送__schema字段使用自省來發(fā)現(xiàn)架構(gòu)信息,該字段在所有查詢的根類型上都可用。

query {__schema{types{name,fields{name,args{name,description,type{name,kind,ofType{name, kind}}}}}}}

可以查詢到所有類型、字段、參數(shù)以及參數(shù)類型。

改變請(qǐng)求方法/報(bào)錯(cuò)信息判斷

利用不同的請(qǐng)求方法(GET、POST)發(fā)起請(qǐng)求也能夠進(jìn)行GraphQL API的辨別,因?yàn)閷?duì)于一些僅允許某種請(qǐng)求方法的GraphQL API而言,不同的請(qǐng)求方法返回的格式和內(nèi)容也不同。除此之外,根據(jù)報(bào)錯(cuò)信息可以判斷是否為GraphQL API,主要特征是Syntax Error: Expected Name, found。

GraphQL API攻擊面 


內(nèi)省查詢攻擊

通過了解GraphQL的內(nèi)省查詢機(jī)制,其實(shí)我們可以發(fā)現(xiàn)在相關(guān)系統(tǒng)沒修改默認(rèn)配置的情況下,我們可以通過__schema 或者 __type 等來進(jìn)行系統(tǒng)級(jí)別的查詢,以獲取服務(wù)器上定義的所有類型、字段、敏感信息等。通過內(nèi)省查詢,我們獲取到系統(tǒng)所有相關(guān)字段及信息,如下圖:

然后利用voyager工具將查詢結(jié)果可視化。

獲取數(shù)據(jù)結(jié)構(gòu)以便進(jìn)一步利用。

拒絕服務(wù)

GraphQL支持請(qǐng)求批處理,并且會(huì)對(duì)請(qǐng)求一個(gè)一個(gè)處理,這就導(dǎo)致可以利用批量查詢來實(shí)施Dos攻擊。

示例:

請(qǐng)求body:
{"query":"query {\n systemUpdate\n}","variables":[]},
{"query": "query {\n systemUpdate\n}","variables":[]},
{"query":"query {\n systemUpdate\n}","variables":[]}

當(dāng)查詢類型相互引用時(shí),通過構(gòu)建一個(gè)循環(huán)查詢,來實(shí)現(xiàn)Dos攻擊。

query { 
Pastes {
Owner {
Pastes {
Owner {
Pastes {
Owner
{
Pastes {
Owner {
Pastes {
Owner {
Pastes {
Owner {
name
}
}
}
} }
}
}
}
}
}
}
}
}

隨著查詢呈指數(shù)級(jí)增長(zhǎng),最終導(dǎo)致服務(wù)器崩潰。

由于GraphQL API不會(huì)對(duì)重讀字段進(jìn)行去重處理,所以還可以通過查詢重復(fù)字段進(jìn)行Dos攻擊。

query {
pastes {
owner {
pastes {
ipAddr # 1
ipAddr # 2
ipAddr # 3
ipAddr # 4
......
ipAddr # 1000
}
}
}
}

越權(quán)查詢/信息泄露

通過內(nèi)審查詢獲取到相關(guān)信息后,可以進(jìn)一步利用,GraphQL API作為單路由API接口在查詢過程中往往會(huì)忽略一些鑒權(quán)問題,這可能導(dǎo)致越權(quán)漏洞的出現(xiàn),并且泄露敏感信息。

例如在查詢到存在id參數(shù)。

通過修改id參數(shù)進(jìn)行水平越權(quán),獲取想要的敏感信息。

命令執(zhí)行

由于GraphQL API沒有充分驗(yàn)證輸入或者沒有嚴(yán)格過濾,導(dǎo)致在一些查詢中可以通過鏈接的形式拼接 UNIX 命令,達(dá)到命令執(zhí)行的目的。

或者是通過systemDiagnostics接受某些 UNIX 二進(jìn)制文件作為調(diào)試目的的參數(shù),例如 whoami、ps等,在獲取相關(guān)憑證或者權(quán)限之后,可以進(jìn)行拼接來達(dá)到命令執(zhí)行的目的。

SQL注入

GraphQL API同樣會(huì)可能存在SQL注入漏洞,可以對(duì)查詢結(jié)構(gòu)體中的一些參數(shù)進(jìn)行SQL注入嘗試。

這里對(duì)“test”參數(shù)進(jìn)行SQL注入嘗試。

加上單引號(hào)后返回報(bào)錯(cuò)信息。

后續(xù)直接利用sqlmap進(jìn)行后續(xù)操作。

graphql注入

類似于SQL注入拼接字符串,在GraphQL API進(jìn)行相關(guān)查詢時(shí),可以通過拼接的方式進(jìn)行注入來獲取數(shù)據(jù)或者改變查詢邏輯。

正常查詢:

mutation {
create(content: "test", id: 1) {
name
password
title
}
}

graphql注入:

mutation {
editPaste(content: "test", id: 1) {
name
title
}
changePassword(password: "admin123") {
name
password
title
}
}

XSS

GraphQL API同樣也會(huì)遭受xss攻擊,其實(shí)針對(duì)任何存在系統(tǒng)而言,如果沒有相應(yīng)的防御手段,沒有對(duì)輸入性參數(shù)進(jìn)行過濾都可能遭受一些輸入型漏洞攻擊。

攻擊載荷成功解析,此外也可以利用上傳功能上傳HTML腳本進(jìn)行攻擊測(cè)試。

SSRF

如果在GraphQL相關(guān)查詢操作允許本地主機(jī)或其他服務(wù)器不限制輸入,就可能遭受服務(wù)端請(qǐng)求偽造攻擊

漏洞案例:

保護(hù)機(jī)制繞過

在GrapQL API中如果存在相關(guān)惡意輸入保護(hù)機(jī)制,可以利用修改請(qǐng)求頭參數(shù)進(jìn)行繞過。

例如下面使用IDE時(shí),進(jìn)行命令執(zhí)行時(shí),存在保護(hù)機(jī)制。

發(fā)現(xiàn)Cookie中存在明顯的disable字段。

修改disable為enable。

成功繞過保護(hù)機(jī)制。

登陸爆破

GraphQL API通過可以實(shí)現(xiàn)弱密碼爆破來碰碰運(yùn)氣,不過還得分無登陸次數(shù)限制和有登陸次數(shù)限制兩種情況。

如果無登陸次數(shù)的限制,直接可進(jìn)行弱密碼爆破。

如果一些網(wǎng)站存在登陸次數(shù)的限制,比如下面在爆破過程中。

GraphQL對(duì)象不能夠包含多個(gè)同名的屬性,所以我們可以利用別名來實(shí)現(xiàn)多個(gè)同屬性的操作,這樣如果系統(tǒng)只限制了API請(qǐng)求速率,那么也可以通過別名查詢來實(shí)現(xiàn)登陸爆破。

JWT令牌偽造

可以通過相關(guān)工具獲取GraphQL API的數(shù)據(jù)結(jié)構(gòu),這里我們就發(fā)現(xiàn)了存在新建用戶的操作。

發(fā)現(xiàn)登陸操作。

利用新建用戶成功查詢到accessToken。

發(fā)現(xiàn)可以利用token進(jìn)行管理員敏感信息查詢。

嘗試用剛才的token進(jìn)行嘗試,發(fā)現(xiàn)還是新建用戶的信息。

偽造JWT,把新用戶的token解析后,修改為admin。

成功查詢到管理賬號(hào)密碼。

目錄穿越/任意文件寫入

在GraphQL API中相關(guān)文件上傳/下載操作也可能存在目錄穿越、任意文件讀取、任意文件寫入等漏洞。

例如通過目錄穿越成功任意文件寫入。

成功上傳至tmp目錄。

工具

除了傳統(tǒng)的滲透測(cè)試工具以外,使用GraphQL API的工具也變得十分重要。

文章轉(zhuǎn)自微信公眾號(hào)@sec0nd安全

上一篇:

10個(gè)人工智能驅(qū)動(dòng)的API安全工具

下一篇:

WebHDFS Rest API 企業(yè)實(shí)戰(zhàn):大佬手把手帶你堵住漏洞,企業(yè)實(shí)例解析
#你可能也喜歡這些API文章!

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)