sql注入報(bào)錯(cuò)之注入原理實(shí)例解析
前言
我相信很多小伙伴在玩sql注入報(bào)錯(cuò)注入時(shí)都會(huì)有一個(gè)疑問(wèn),為什么這么寫就會(huì)報(bào)錯(cuò)?曾經(jīng)我去查詢的時(shí)候,也沒(méi)有找到滿意的答案,時(shí)隔幾個(gè)月終于找到搞清楚原理,特此記錄,也希望后來(lái)的小伙伴能夠少走彎路
0x01
我們先來(lái)看一看現(xiàn)象,我這里有一個(gè)users表,里面有五條數(shù)據(jù):

然后用我們的報(bào)錯(cuò)語(yǔ)句查詢一下:
select count(*),(concat(floor(rand()*2),(select version())))x from users group by x

成功爆出了數(shù)據(jù)庫(kù)的版本號(hào)。
要理解這個(gè)錯(cuò)誤產(chǎn)生的原因,我們首先要知道group by語(yǔ)句都做了什么。我們用一個(gè)studetn表來(lái)看一下:

現(xiàn)在我們通過(guò)年齡對(duì)這個(gè)表中的數(shù)據(jù)進(jìn)行下分組:

形成了一個(gè)新的表是吧?你其實(shí)應(yīng)該能夠想到group by 語(yǔ)句的執(zhí)行流程了吧?最開(kāi)始我們看到的這張sage-count()表應(yīng)該時(shí)空的,但是在group by語(yǔ)句執(zhí)行過(guò)程中,一行一行的去掃描原始表的sage字段,如果sage在sage-count()不存在,那么就將他插入,并置count()置1,如果sage在sage-count()表中已經(jīng)存在,那么就在原來(lái)的count(*)基礎(chǔ)上加1,就這樣直到掃描完整個(gè)表,就得到我們看到的這個(gè)表了。
注:這里有特別重要的一點(diǎn),group by后面的字段時(shí)虛擬表的主鍵,也就是說(shuō)它是不能重復(fù)的,這是后面報(bào)錯(cuò)成功的關(guān)鍵點(diǎn),其實(shí)前面的報(bào)錯(cuò)語(yǔ)句我們已經(jīng)可以窺見(jiàn)點(diǎn)端倪了

0x02
正如我前面所說(shuō)的,報(bào)錯(cuò)的主要原因時(shí)虛擬表的主鍵重復(fù)了,那么我們就來(lái)看一下它到底是在哪里,什么時(shí)候重復(fù)的。這里rand()函數(shù)就登場(chǎng)了。
首先我們先來(lái)了解rand()函數(shù)的用法:
1.用來(lái)生成一個(gè)0~1的數(shù)
2.還可以給rand函數(shù)傳一個(gè)參數(shù)作為rand()的種子,然后rand函數(shù)會(huì)依據(jù)這個(gè)種子進(jìn)行隨機(jī)生成。
那他們的區(qū)別是什么呢?我們來(lái)看一下,這兩個(gè)語(yǔ)句的執(zhí)行效果:

可以看到rand()生成的數(shù)據(jù)毫無(wú)規(guī)律,而rand(0)生成的數(shù)據(jù)則有規(guī)律可循,是:
0110 0110
注:如果你覺(jué)得數(shù)據(jù)不夠,證明不了rand()的隨機(jī)性,你可以自己多插入幾條數(shù)據(jù)再查詢?cè)囈幌隆?/p>
0x03
現(xiàn)在我們弄清楚了group by語(yǔ)句的工作流程,以及rand()與rand(0)的區(qū)別,那么接下來(lái)就是重點(diǎn)了,mysql官方說(shuō),在執(zhí)行g(shù)roup by語(yǔ)句的時(shí)候,group by語(yǔ)句后面的字段會(huì)被運(yùn)算兩次。
**第一次:**我們之前不是說(shuō)了會(huì)把group by后面的字段值拿到虛擬表中去對(duì)比嗎,在對(duì)比之前肯定要知道group by后面字段的值,所以第一次的運(yùn)算就發(fā)生在這里。
**第二次:**現(xiàn)在假設(shè)我們下一次掃描的字段的值沒(méi)有在虛擬表中出現(xiàn),也就是group by后面的字段的值在虛擬表中還不存在,那么我們就需要把它插入到虛擬表中,這里在插入時(shí)會(huì)進(jìn)行第二次運(yùn)算,由于rand函數(shù)存在一定的隨機(jī)性,所以第二次運(yùn)算的結(jié)果可能與第一次運(yùn)算的結(jié)果不一致,但是這個(gè)運(yùn)算的結(jié)果可能在虛擬表中已經(jīng)存在了,那么這時(shí)的插入必然導(dǎo)致錯(cuò)誤!
所以我們現(xiàn)在通過(guò)一個(gè)例子來(lái)驗(yàn)證我們的理論,拿出我們最開(kāi)始的例子:
select count(*),(concat(floor(rand(0)*2),'@',(select version())))x from users group by x
聲明:users表就是本文第一個(gè)表,表中有五條數(shù)據(jù)
注意我這里用的是rand(0),不是rand(),rand(0)生成的有規(guī)律的序列:

我們跟著剛剛的思路走,最開(kāi)始的虛擬表是空的,就像下面一樣:
| count(*) | x |
|---|---|
當(dāng)我掃描原始表的第一項(xiàng)時(shí),第一次計(jì)算,floor(rand(0)*2)是0,然后和數(shù)據(jù)庫(kù)的版本號(hào)(假設(shè)就是5.7.19)拼接,到虛擬表里去尋找x有沒(méi)有x的值是x@5.7.19的數(shù)據(jù)項(xiàng),結(jié)果顯然是沒(méi)有,那么接下來(lái)就將它插入到上表中,但是還記得嗎,在插入之前會(huì)進(jìn)行第二次計(jì)算,這時(shí)x的值就變成了1@5.7.19,所以虛擬表變成了下面這樣:
| count(*) | x |
|---|---|
| 1 | 1@5.7.19 |
現(xiàn)在掃描原始表的第二項(xiàng),第一次計(jì)算x==’1@5.7.19‘,已經(jīng)存在,不需要進(jìn)行第二次計(jì)算,直接插入,得到下表:
| count(*) | x |
|---|---|
| 2 | 1@5.7.19 |
掃描原始表的第三項(xiàng),第一次計(jì)算x==‘0@5.7.19’,虛擬表中找不到,那么進(jìn)行第二次計(jì)算,這時(shí)x==‘1@5.7.19’,然后插入,但是插入的時(shí)候問(wèn)題就發(fā)生了,虛擬表中已經(jīng)存在以1@5.7.19為主鍵的數(shù)據(jù)項(xiàng)了,插入失敗,然后就報(bào)錯(cuò)了!
上面是使用rand(0)的情況,rand(0)是比較穩(wěn)定的,所以每次執(zhí)行都可以報(bào)錯(cuò),但是如果使用rand()的話,因?yàn)樗傻男蛄惺请S機(jī)的嘛,所以并不是每次執(zhí)行都會(huì)報(bào)錯(cuò),下面是我的測(cè)試結(jié)果:

執(zhí)行了五次,報(bào)錯(cuò)兩次,所以是看運(yùn)氣。
總結(jié)
總之,報(bào)錯(cuò)注入,rand(0),floor(),group by缺一不可
到此這篇關(guān)于sql注入報(bào)錯(cuò)之注入原理實(shí)例解析的文章就介紹到這了,更多相關(guān)sql注入報(bào)錯(cuò)注入原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Hive數(shù)據(jù)去重的兩種方式?(distinct和group?by)
數(shù)據(jù)庫(kù)中表存在重復(fù)數(shù)據(jù),需要清理重復(fù)數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Hive數(shù)據(jù)去重的兩種方式,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01
使用 Navicat 創(chuàng)建數(shù)據(jù)庫(kù)并用JDBC連接的操作方法
這篇文章主要介紹了使用 Navicat 創(chuàng)建數(shù)據(jù)庫(kù)并用JDBC連接的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Hadoop 2.x偽分布式環(huán)境搭建詳細(xì)步驟
這篇文章主要為大家詳細(xì)介紹了Hadoop 2.x偽分布式環(huán)境搭建詳細(xì)步驟,感興趣的朋友可以參考一下2016-05-05
數(shù)據(jù)庫(kù)查詢中遭遇特殊字符導(dǎo)致問(wèn)題的解決方法
數(shù)據(jù)庫(kù)查詢中遭遇特殊字符導(dǎo)致問(wèn)題的解決方法,我們提供的是asp的,但其它的數(shù)據(jù)庫(kù)與語(yǔ)言下的解決方法也大同小異。2007-12-12
WordPress導(dǎo)入數(shù)據(jù)庫(kù)出現(xiàn)”Unknown collation: ‘utf8mb4_unicode_ci”錯(cuò)誤的解
這篇文章主要介紹了WordPress導(dǎo)入數(shù)據(jù)庫(kù)出現(xiàn)”Unknown collation: ‘utf8mb4_unicode_ci”錯(cuò)誤的解決辦法的相關(guān)資料,需要的朋友可以參考下2015-10-10
數(shù)據(jù)庫(kù)安裝包和升級(jí)包腳本工具RedGate使用介紹
這篇文章主要介紹了數(shù)據(jù)庫(kù)安裝包和升級(jí)包腳本工具RedGate使用介紹,RedGate是一個(gè)SQL腳本生成工具,需要的朋友可以參考下2014-07-07
JDBC 數(shù)據(jù)庫(kù)常用連接 鏈接字符串
JDBC 數(shù)據(jù)庫(kù)常用連接 鏈接字符串,經(jīng)常用各種數(shù)據(jù)庫(kù)的朋友可以參考下。2009-07-07
數(shù)據(jù)庫(kù) 三范式最簡(jiǎn)單最易記的解釋
數(shù)據(jù)庫(kù) 三范式最簡(jiǎn)單最易記的解釋,整理一下方便大家記憶。2009-07-07

