SEED实验系列:Collabtive系统SQL注入实验
??本課程原文鏈接為:https://www.shiyanlou.com/courses/291,實驗樓已經為此課程的實踐提供了在線實驗環境,想要嘗試體驗的,可以直接前往實驗樓進行實踐操作。
? ?你能夠喜歡我們的課程,讓我們感到異常高興,我們也非常歡迎你將本課程分享給更多的人,我們唯一的要求就是請保留我們的課程原文鏈接。
一、實驗描述
SQL注入漏洞的代碼注入技術,利用web應用程序和數據庫服務器之間的接口。通過把SQL命令插入到Web表單提交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。
二、實驗背景
在這個實驗中,我們利用的web應用程序稱為Collabtive,禁用Collabtive的若干對策。這樣我們就創建了一個容易受到SQL注入攻擊的Collabtive版本。經過我們的人工修改,可以捕捉許多web開發人員的常見錯誤。在本實驗室學生的目標是找到方法來利用SQL注入漏洞,證明可以通過攻擊的傷害,和掌握的技術,可以幫助抵御這類攻擊。
三、預備知識
1、SQL語言
結構化查詢語言(Structured Query Language)簡稱SQL:是一種特殊目的的編程語言,是一種數據庫查詢和程序設計語言,用于存取數據以及查詢、更新和管理關系數據庫系統;同時也是數據庫腳本文件的擴展名
常見SQL語句
2、SQL注入
SQL注入:SQL注入能使攻擊者繞過認證機制,完全控制遠程服務器上的數據庫。SQL是結構化查詢語言的簡稱,它是訪問數據庫的事實標準。目前,大多數Web應用都使用SQL數據庫來存放應用程序的數據。幾乎所有的Web應用在后臺都使用某種SQL數據庫。跟大多數語言一樣,SQL語法允許數據庫命令和用戶數據混雜在一起的。如果開發人員不細心的話,用戶數據就有可能被解釋成命令,這樣的話,遠程用戶就不僅能向Web應用輸入數據,而且還可以在數據庫上執行任意命令了。
sql注入原理講解
3、SQL注入危害
非法讀取、篡改、添加、刪除數據庫中的數據。
盜取用戶的各類敏感信息,獲取利益。
通過修改數據庫來修改網頁上的內容。
私自添加或刪除賬號。
注入木馬等等。
4、環境搭建
啟動mysql:
sudo mysqld_safe
啟動Apache:
sudo service apache2 start密碼:dees
配置DNS:
sudo vim /etc/hosts
按i進入編輯模式,編輯文件
編輯完成后按Esc退出編輯
完成后使用 :wq 保存并退出
配置網站文件:
sudo vim /etc/apache2/conf.d/lab.confsudo service apache2 restart 重啟服務
訪問測試:http://www.sqllabcollabtive.com
用戶名:admin;密碼:admin
關閉php配置策略:
sudo vim /etc/php5/apache2/php.ini
把magic_quotes_gpc=On?改為?magic_quotes_gpc = Off
關于magic_quotes_off函數:
對于magic_quotes_gpc=on的情況, 我們可以不對輸入和輸出數據庫的字符串數據作addslashes()和stripslashes()的操作,數據也會正常顯示;
如果此時你對輸入的數據作了addslashes()處理,那么在輸出的時候就必須使用stripslashes()去掉多余的反斜杠。
對于PHP?magic_quotes_gpc=off?的情況
必須使用addslashes()對輸入數據進行處理,但并不需要使用stripslashes()格式化輸出,因為addslashes()并未將反斜杠一起寫入數據庫,只是幫助mysql完成了sql語句的執行。
科普
四、實驗內容
1、lab1 select語句的sql注入
訪問:www.sqllabcollabtive.com;當我們知道用戶而不知道到密碼的時候,我們可以怎么登陸?
查看登陸驗證文件:
sudo vim /var/www/SQL/Collabtive/include/class.user.php
設置行號 :set number
查找 :/keyword
找到其中第375行
$sel1 = mysql_query ("SELECT ID, name, locale, lastlogin, gender, FROM user WHERE (name = '$user' OR email = '$user') AND pass = '$pass'");
這一句就是我們登錄時,后臺的sql語句;我們可以構造一個語句,在不知道密碼的情況下登陸;
$sel1 = mysql_query ("SELECT ID, name, locale, lastlogin, gender, FROM user WHERE (name = '$user ') #' OR email = '$user') AND pass = '$pass'");
修改完后重啟一下服務器:
sudo sudo service apache2 restart
我們在$user后面加上) #?這樣就會只驗證用戶名,后面的會被#注釋
點擊登陸以后,我們就可以繞過密碼直接登錄:
思考:
你是否可以找到一個方法來修改數據庫(仍然使用上述SQL查詢)?
例如,你能添加一個新的登陸用戶,或刪除現有的用戶?顯然,上述的SQL語句是一個查詢只陳述,并且不能更新數據庫。但是,使用SQL注入,你可以把上面的語句分割為兩個語句,后面是更新語句。
請試試這個方法,看看是否可以成功地更新數據庫?
答案:
說實話,我們都無法達到更新的目標。這是因為在MySQL中實現的特定的防御機制。在報告中,你應該告訴我們你有什么企圖以修改數據庫。你應該找出原因的攻擊失敗,是什么機制在MySQL中阻止這種攻擊。
登陸用戶名:
admin') union update user set name='test' #
登陸密碼:隨意的字符
登陸失敗
2、原因解釋
MySQL機制:update不支持union語法。
3、lab2 update語句的sql注入
Collabtive平臺中可以更新用戶信息,我們要實現通過自己的用戶去修改別人的用戶信息;
訪問用戶編輯鏈接:http://www.sqllabcollabtive.com/manageuser.php?action=editform&id=1
在Collabtive web應用程序中,如果用戶想更新他們的個人資料,他們可以去我的帳戶,單擊編輯鏈接,然后填寫表格以更新資料信息。在用戶發送更新請求到服務器,一個UPDATE SQL語句將建造在include/class.user.php。這句話的目的是修改用戶表中的當前用戶的配置信息。 有一個在這個SQL語句中的SQL注入漏洞;
sudo vim /var/www/SQL/Collabtive/include/class.user.php
我們可以找到如下的代碼
function edit($id, $name, $realname, $email, $tel1, $tel2, $company,$zip, $gender, $url, $address1, $address2, $state,$country, $tags, $locale, $avatar = "", $rate = 0.0){$name = mysql_real_escape_string($name);$realname = mysql_real_escape_string($realname);//modified for SQL Lab//$company = mysql_real_escape_string($company);$email = mysql_real_escape_string($email);// further escaped parameters removed for brevity...$rate = (float) $rate;$id = (int) $id;if ($avatar != ""){$upd = mysql_query("UPDATE user SET name='$name', email='$email',tel1='$tel1', tel2='$tel2', company='$company',zip='$zip', gender='$gender', url='$url',adress='$address1', adress2='$address2',state='$state', country='$country',tags='$tags', locale='$locale',avatar='$avatar', rate='$rate' WHERE ID = $id");}else{// same query as above minus setting avatar; removed for// brevity}if ($upd){$this->mylog->add($name, 'user', 2, 0);return true;}else{return false;}}
我們會發現sql語句為:SELECT ID WHERE name='$user',并且company的位置是存在注入漏洞,原理同lab1。
這樣我們就可以越權來修改其他用戶的信息及密碼;我們使用任意用戶,如: bob bob 進行登錄;
在編輯用戶的位置:user 填 ted 用戶; Company 處填:
', `pass` = '9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684' WHERE ID = 4 # '注:這里的 9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684 就是pass的md5值;
點擊修改,然后我們退出當前用戶,使用ted用戶登錄,這個時候ted用戶的密碼應該是pass;
五、防御策略
SQL注入漏洞的根本問題是數據與代碼的分離失敗,因此我們可以針對這個原因進行防御
1、防御策略1
防御轉義特殊字符使用,默認開啟magic_quotes_gpc,將magic_quotes_gpc值設為On。
sudo vim /etc/php5/apache2/php.inisudo service apache2 restart
科普:magic_quotes_gpc防注入方法
2、防御策略2--避免使用特殊字符
MySQL提供一個函數 mysql_real_escape_string(),這個函數可以用來過濾一些特殊字符;如\x00, \n, \r, \, ', " and \x1a;
科普:mysql_real_escape_string()
代碼防御示例:
sudo vim /var/www/SQL/Collabtive/include/class.user.php
修改為如下:
// This code was provided by the lab's author Wenliang Du, of Syracuse// University under the GNU Free Documentation Licensefunction login($user, $pass){if (!$user){return false;}// modification fixed$user = mysql_real_escape_string($user);$pass = mysql_real_escape_string($pass);$pass = sha1($pass);$sel1 = mysql_query("SELECT ID, name, locale, lastlogin, genderFROM user WHERE (name = '$user' ORemail = '$user') AND pass = '$pass'");$chk = mysql_fetch_array($sel1);if ($chk["ID"] != ""){// New user session object and cookie creation code// removed for brevityreturn true;}else{return false;}}
以及編輯用戶代碼:
function edit($id, $name, $realname, $email, $tel1, $tel2, $company,$zip, $gender, $url, $address1, $address2, $state,$country, $tags, $locale, $avatar = "", $rate = 0.0){$name = mysql_real_escape_string($name);$realname = mysql_real_escape_string($realname);// modification fixed$company = mysql_real_escape_string($company);$email = mysql_real_escape_string($email);// further escaped parameters removed for brevity...$rate = (float) $rate;$id = (int) $id;if ($avatar != ""){$upd = mysql_query("UPDATE user SET name='$name', email='$email',tel1='$tel1', tel2='$tel2', company='$company',zip='$zip', gender='$gender', url='$url',adress='$address1', adress2='$address2',state='$state', country='$country',tags='$tags', locale='$locale',avatar='$avatar', rate='$rate' WHERE ID = $id");}else{// same query as above minus setting avatar; removed for// brevity}if ($upd){$this->mylog->add($name, 'user', 2, 0);return true;}else{return false;}}
3、防御策略3--數據與sql語句的分離
通過SQL邏輯分離來告訴數據庫到底是哪部分是數據部分,哪一部分是SQL語句部分;
提供以新的new mysqli()函數, 將這個函數寫入config/standary/config.php文件:
sudo vim /var/www/SQL/Collabtive/include/class.user.php
修改代碼如下:
// This code was provided by the lab's author Wenliang Du, of Syracuse// University under the GNU Free Documentation Licensefunction login($user, $pass){if (!$user){return false;}// using prepared statements// note that $conn is instantiated in the datenbank class found in// ./class.datenbank.php. this may need to be passed in, but we// will assume we have access to it for the sake of brevity$stmt = $conn->prepare("SELECT ID,name,locale,lastlogin,gender FROM userWHERE (name=? OR email=?) AND pass=?");$stmt->bind_param("sss", $user, $user, sha1($pass));$stmt->execute();$stmt->bind_result($bind_ID, $bind_name, $bind_locale, $bind_lastlogin,$bind_gender);$chk = $stmt->fetch();if ($bind_ID != ""){// New user session object and cookie creation code// removed for brevityreturn true;}else{return false;}}
以及編輯用戶處的代碼:
// This code was provided by the lab's author Wenliang Du, of Syracuse// University under the GNU Free Documentation Licensefunction edit($id, $name, $realname, $email, $tel1, $tel2, $company, $zip,$gender, $url, $address1, $address2, $state, $country, $tags,$locale, $avatar = "", $rate = 0.0){// the bind_param() function wants a double, not float, though// they are the same internally$rate = (double) $rate;$id = (int) $id;if ($avatar != ""){// again, $conn is instantiated in the datenbank class, and// may need to be passed, but we are assuming we have// access to it for the sake of brevity// note that the app uses zip as a string, does not use// realname although it is passed, and the columns adress// and adress2 are misspelled$stmt = $conn->prepare("UPDATE user SET name=?, email=?, tel1=?,tel2=?, company=?, zip=?, gender=?, url=?,adress=?, adress2=?, state=?, country=?,tags=?, locale=?, avatar=? rate=?WHERE ID = ?");$stmt->bind_param("sssssssssssssssdi", $name, $email, $tel1, $tel2,$company, $zip, $gender, $url, $address1,$address2, $state, $country, $tags, $locale,$avatar, $rate, $id);$upd = $stmt->execute();}else{$stmt = $conn->prepare("UPDATE user SET name=?, email=?, tel1=?,tel2=?, company=?, zip=?, gender=?, url=?,adress=?, adress2=?, state=?, country=?,tags=?, locale=?, rate=? WHERE ID = ?");$stmt->bind_param("ssssssssssssssdi", $name, $email, $tel1, $tel2,$company, $zip, $gender, $url, $address1,$address2, $state, $country, $tags, $locale,$rate, $id);$upd = $stmt->execute();}if ($upd){$this->mylog->add($name, 'user', 2, 0);return true;}else{return false;}}
4、調試
下面的代碼可以讓服務器端php程序變量輸出到一個文件中,以此來對php代碼進行調試
$myFile = "/tmp/mylog.txt";$fh = fopen($myFile, ’a’) or die("can’t open file");$Data = "a string";fwrite($fh, $Data . "\n");fclose($fh);
5、火狐插件Tamper Data
TamperData使用
六、作業
你需要提交一份詳細的實驗報告,描述你所做的和你所觀察到的。
請提供使用的LiveHTTPHeaders的截圖,并且提供詳細的操作過程資料。
您還可以提供有趣或者令人驚訝的發現。
license
本實驗所涉及的實驗環境來自Syracuse SEED labs,并在此基礎上為適配實驗室我那工作環境進行修改,修改后的實驗文檔仍然遵循GUN Free Documentation License 附Syracuse SEED labs版權說明:
Copyright c 2006 - 2011 Wenliang Du, Syracuse University. The development of this document is/was funded by three grants from the US National Science Foundation: Awards No. 0231122 and 0618680 from TUES/CCLI and Award No. 1017771 from Trustworthy Computing. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation. A copy of the license can be found athttp://www.gnu.org/licenses/fdl.html.
轉載請注明實驗樓課程原文鏈接:https://www.shiyanlou.com/courses/291
總結
以上是生活随笔為你收集整理的SEED实验系列:Collabtive系统SQL注入实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SEED实验系列:ShellShock
- 下一篇: Linux学习路径(小白必看)