溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python代碼審計(jì)中的SQL和ORM注入是怎樣的

發(fā)布時(shí)間:2021-12-04 16:25:17 來(lái)源:億速云 閱讀:397 作者:柒染 欄目:安全技術(shù)

本篇文章為大家展示了Python代碼審計(jì)中的SQL和ORM注入是怎樣的,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

Python代碼審計(jì)方法多種多樣,但是總而言之是根據(jù)前人思路的遷移融合擴(kuò)展而形成。目前Python代碼審計(jì)思路,呈現(xiàn)分散和多樣的趨勢(shì)。Python微薄研發(fā)經(jīng)驗(yàn)以及結(jié)合實(shí)際遇到的思路和技巧進(jìn)行總結(jié)。

SQL注入和ORM注入

這兩者注入相似度較高,所以打算放在一起分析和總結(jié)。它們所用原理OWASP TOP TEN  中的描述非常合適,“將不受信任的數(shù)據(jù)作為命令或查詢(xún)的一部分發(fā)送到解析器時(shí),會(huì)產(chǎn)生諸如SQL注入、NoSQL注入、OS注入和LDAP注入的注入缺陷。攻擊者的惡意數(shù)據(jù)可以誘使解析器在沒(méi)有適當(dāng)授權(quán)的情況下執(zhí)行非預(yù)期命令或訪問(wèn)數(shù)據(jù)。”。

1. SQL注入

Python  中常見(jiàn)存在風(fēng)險(xiǎn)SQL語(yǔ)句,在id或者Name可控的情況下存在安全隱患??煽貐?shù)可以將咱么期望他執(zhí)行的代碼按照語(yǔ)法進(jìn)行拼接,從而執(zhí)行原本預(yù)期之外的代碼。

sql = "select id,name from user_table where id = %s and name = %s" % (id, name) cur.execute(sql)

然而在實(shí)際案例中,這種執(zhí)行SQL語(yǔ)句并不多,比較典型的案例。實(shí)例代碼如下:

import urllib import MySQLdb import SocketServer from SimpleHTTPServer import SimpleHTTPRequestHandler class MyHandler(SimpleHTTPRequestHandler):     def _set_headers(self):         self.send_response(200)         self.send_header('Content-type', 'text/html')         self.end_headers()     def do_GET(self):         print("got get request %s" % (self.path))         hql = urllib.splitquery(self.path)[1]         uri_c = str(hql)         print('cmd===%s' % (uri_c))         sql = "select id from user_table where id = %s" % uri_c         db = MySQLdb.connect("localhost", "testuser", "test123", "TESTDB", charset='utf8')         cursor = db.cursor()         cursor.execute(sql)         data = cursor.fetchone()         self.wfile.write(data) def start_server():     httpd = SocketServer.TCPServer(("127.0.0.1", 8090), MyHandler)     print('Starting httpd...')     httpd.serve_forever() if __name__ == "__main__":     start_server()

這是一個(gè)簡(jiǎn)單的HTTP服務(wù)器,目前在Python2中可以正常運(yùn)行。通過(guò)urllib.splitquery獲取GET請(qǐng)求的參數(shù),uri_c  里面為請(qǐng)求參數(shù)的值。用值傳遞到SQL語(yǔ)句中拼接,從而產(chǎn)生注入問(wèn)題。這是比較簡(jiǎn)單的一種,正常情況下調(diào)用鏈可能會(huì)比較長(zhǎng),長(zhǎng)短取決于平臺(tái)的設(shè)計(jì)架構(gòu)。

2. ORM注入

(1) sqlalchemy ORM注入(CNVD-2019-17301)

考慮到的理解上比較容易,用模塊進(jìn)行舉例,并不涉及到框架。ORM注入是SQL注入的一種特殊情況,ORM模塊將SQL語(yǔ)句進(jìn)行模板化,所以找SQL語(yǔ)句字符串的辦法不好用了。那么應(yīng)該怎么辦?根據(jù)模塊來(lái)找尋執(zhí)行方法,如果模塊存在問(wèn)題和未妥善過(guò)濾或轉(zhuǎn)義、存在可控變量則可能會(huì)產(chǎn)生問(wèn)題。如何去發(fā)現(xiàn)和查找Python  ORM模塊,展現(xiàn)朋友們搜索技能的時(shí)候到了,不再老生常談。下面進(jìn)入案例:

from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker import sqlalchemy print("sqlalchemy_version:",sqlalchemy.__version__) engine = create_engine('mysql://root:123456@192.168.56.101:3306/mysql?charset=utf8') DB_Session = sessionmaker(bind=engine) session = DB_Session() session.execute('use mysql;') print(         session.execute(             """                 select * from user where User='root' and 11=1;             """     ).fetchall() )

這個(gè)是使用sqlalchemy的ORM注入,它存在任意執(zhí)行SQL語(yǔ)句的接口。道理上講這個(gè)是功能,實(shí)際情況大多數(shù)程序員都會(huì)認(rèn)為ORM是能夠防御SQL注入,這個(gè)可能會(huì)成為漏洞。通過(guò)轉(zhuǎn)義可以更好的解決問(wèn)題,但是官方可能并不重視。另外還有sqlalchemy幾個(gè)問(wèn)題利用order_by注入、利用”limit”和”offset”關(guān)鍵詞向”select()”函數(shù)傳遞注入等等,方法一樣利用模塊過(guò)濾不嚴(yán),暫不多論。

(2) Django JSON SQL注入(CVE-2019-14234)

咱們繼續(xù)看來(lái) Django JSON  SQL注入,關(guān)于這個(gè)漏洞已經(jīng)有前人分析過(guò)了。這個(gè)分析有些難度需要咱們了解Django和PostgreSQL,如果感覺(jué)吃力不妨先去學(xué)習(xí)一番。了解在PostgreSQL之中關(guān)于JSON數(shù)據(jù)的查詢(xún)主要使用ArrayField、JSONField、HStoreField,通過(guò)Django如何進(jìn)行查詢(xún)PostgreSQL,Json.objects.filter()和QuerySet.filter()實(shí)現(xiàn),準(zhǔn)備工作就緒。

查詢(xún)使用方法如下:

# 查詢(xún)方法 # 查詢(xún)data數(shù)據(jù)下名稱(chēng)為test的內(nèi)容為'user'的整個(gè)字段 Json.objects.filter(data__test='user') or Json.objects.filter(**{"data__test":'user'})

通過(guò)補(bǔ)丁判斷實(shí)現(xiàn)方法使用了 self.key_name ,QuerySet.filter()的調(diào)用和self.key_name傳遞有關(guān)。

Python代碼審計(jì)中的SQL和ORM注入是怎樣的

緊接著發(fā)現(xiàn)類(lèi) KeyTransformFactory 調(diào)用了 KeyTransform 傳入了 self.key_name  ,后續(xù)是字符串拼接。這里不多詳細(xì)闡述感興趣的朋友跟下流程。

class KeyTextTransform(KeyTransform):     operator = '->>'     ...     # 字符串拼接     (%s %s %s)" % (lhs, self.operator, lookup)

結(jié)合注入的知識(shí)進(jìn)行實(shí)施測(cè)試,結(jié)果如下。

# 使用注入 # 拼接補(bǔ)全SQL語(yǔ)法 Json.objects.filter(**{"""data__breed'='"a"') OR 11=1 OR('d""":'x',})

ORM注入為兩個(gè)案例,分別是關(guān)于模塊和框架。

上述內(nèi)容就是Python代碼審計(jì)中的SQL和ORM注入是怎樣的,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI