DVWA中學習PHP常見漏洞及修復方法
“安全是一個整體,保證安全不在於強大的地方有多強大 而在於真正薄弱的地方在哪裡”--劍心
從很多的滲透大型企業內網的案例來看,入侵者大多數是從Web上找到漏洞,從而利用漏洞進一步進行提權,滲透入侵。
WooYun: 搜弧某分站XFF注射&配置不當導致原始碼洩漏等重大漏洞
指令碼安全就像你家的防盜門,你家門都沒關,你家能安全嗎?
烏雲上最常見的指令碼漏洞莫過於SQL隱碼攻擊和XSS。
指令碼安全的本質就是指令碼接受了不安全的變數輸入,又沒得到有效的過濾,最後進入一些對敏感的函式就會對安全造成威脅。
比如出現在mysql_query()函式可能就會造成SQL隱碼攻擊漏洞,出現在eval()以及preg_replace()中可能導致程式碼的執行。
這裡我用DVWA演示SQL,XSS ,任意程式碼執行漏洞的原理
然後用各種修復方法進行修復,附帶講解一些修復方法的弊端。
DVWA下載地址: https://github.com/RandomStorm/DVWA/archive/v1.0.8.zip
DVWA sql呼叫的檔案/vulnerabilities/sqli/目錄下,分為low,medium,high三個等級
SQL隱碼攻擊原理
#!php
//Low.php
if(isset($_GET['Submit'])){
// Retrieve data
$id = $_GET['id'];
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";//這裡$id變數沒有經過任何的過濾,直接傳入了sql語句,造成字元型注入
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );//執行SQL
原SQL中
SELECT first_name, last_name FROM users WHERE user_id = '$id'
中的$id可被使用者控制,當駭客把$id變成
' union select user,password from users#
那麼這條語句就會變成
SELECT first_name, last_name FROM users WHERE user_id = '' union select user,password from users#
這樣導致了資料庫中其他資料被駭客查詢。 
#!php
//medium.php中
if (isset($_GET['Submit'])) {
// Retrieve data
$id = $_GET['id'];
$id = mysql_real_escape_string($id);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
雖然$id經過了mysql_real_escape_string轉義了’,可是因為後面的SQL語句$id沒有單引號保護,會被系統認為是數值型,導致數值型注入
構造SQL隱碼攻擊語句
1 union select user,password from users
SQL語句就變成了
SELECT first_name, last_name FROM users WHERE user_id = 1 union select user,password from users 
SQL隱碼攻擊修補方法
字元型注入漏洞修補方法:
PHP5.3之前版本在php.ini中設定
magic_quotes_gpc=On;
magic_quotes_quotes_gpc會對傳入的$_POST,$_GET,$_SERVER裡的 ‘,”,\進行轉義。
但是PHP5.4之後,magic_quotes_quotes_gpc就被廢除了。
還要使用mysql_real_escape_string()或addslashes()對傳入引數進行過濾,或者使用str_replace()對一些關鍵詞進行替換。
例:
#!php
if(isset($_GET['Submit'])){
// Retrieve data
$id = addslashes($_GET['id']);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = '$id'";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
修補後進行SQL隱碼攻擊
但是addslashes()和mysql_real_escape_string()在資料庫字符集設為GBK時是可能被繞過的。
PHP字元編碼繞過漏洞參考文http://huaidan.org/archives/2268.html
如果資料庫字符集是GBK的情況下,可以把
$mysqli->query('SET NAMES gbk');
修改為:
$mysqli->set_charset('gbk');
數值型注入:
數值型注入比較好修補,只需要判斷傳入的變數是否為數值型就可以了(或者強行改成字元型)
例:
#!php
$id = $_GET['id'];
$id = intval ($id);
$getid = "SELECT first_name, last_name FROM users WHERE user_id = $id";
$result = mysql_query($getid) or die('<pre>' . mysql_error() . '</pre>' );
$num = mysql_numrows($result);
修補後效果
XSS漏洞原理
駭客往Web頁面裡插入惡意html程式碼,當使用者瀏覽該頁之時,嵌入其中Web裡面的html程式碼會被執行,從而達到駭客的特殊目的,比如竊取使用者cookies.或者進行其他操作。 在
#!php
//low.php
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);//stripslashes() 函式刪除由 addslashes() 函式新增的反斜槓。
$message = mysql_real_escape_string($message);//mysql_real_escape_string() 函式轉義 SQL 語句中使用的字串中的特殊字元。
// Sanitize name input
$name = mysql_real_escape_string($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' ); }
?>
從上面程式可以看出,$message,$name兩個變數從$_POST傳入,只是經過一些特殊字元的轉換。並沒有對尖括號進行轉義,所以還是造成了XSS的產生。
直接插入XSS語句
<script>alert(1)<script>
就執行了
而medium.php中,雖然對$message進行了尖括號轉義,而且對<script>
進行了替換,但是$name沒有進行轉義,而且跨站指令碼可以用多種標籤,如<img />
,等…。Name的<input />
限制了maxlength=‘10’的長度,但是我們的防禦物件是精通技術的駭客。這種html下的長度限制是可以直接透過瀏覽器修改..然後透過大小寫成功繞過str_replace(),插入XSS.
<SCript>alert(1)</SCript>

#!php
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = trim(strip_tags(addslashes($message)));
$message = mysql_real_escape_string($message);
$message = htmlspecialchars($message);
// Sanitize name input
$name = str_replace('<script>', '', $name); //一個大小寫就可以繞過,或者<img />
$name = mysql_real_escape_string($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
}
?>
XSS漏洞修補方法
使用htmlspecialchars()在輸出時對輸出內容就行轉義。
瞌睡龍說:在輸出時進行轉義比輸入時進行轉義效果更好,因為可以確保資料在入庫時是完整的….不然丟失資料。
例:
#!php
<?php
if(isset($_POST['btnSign']))
{
$message = trim($_POST['mtxMessage']);
$name = trim($_POST['txtName']);
// Sanitize message input
$message = stripslashes($message);
$message = mysql_real_escape_string($message);
$message = htmlspecialchars($message);
// Sanitize name input
$name = stripslashes($name);
$name = mysql_real_escape_string($name);
$name = htmlspecialchars($name);
$query = "INSERT INTO guestbook (comment,name) VALUES ('$message','$name');";
$result = mysql_query($query) or die('<pre>' . mysql_error() . '</pre>' );
}
?>
修補後效果,可以看到尖括號已經被轉義了,html程式碼已經不執行
任意命令執行漏洞原理
任意命令執行可謂是web裡最高危的漏洞了,有可能可以直接寫下shell或者直接新增使用者。
任意命令執行漏洞的產生大多是因為變數可以被使用者輸入控制,而沒有經過任何的判斷和過濾處理就進入了高危的函式。
#!php
<?php
if( isset( $_POST[ 'submit' ] ) ) {
$target = $_REQUEST[ 'ip' ];
// Determine OS and execute the ping command.
if (stristr(php_uname('s'), 'Windows NT')) {
$cmd = shell_exec( 'ping ' . $target );
$html .= '<pre>'.$cmd.'</pre>';
} else {
$cmd = shell_exec( 'ping -c 3 ' . $target );
$html .= '
<pre>'.$cmd.'</pre>';
}
}
?>
由於$target沒有經過處理就進入shell_exec函式,導致駭客可以構造特殊的變數執行批處理命令。
我輸入可 0 | dir
那麼執行的命令的命令就是 ping -c 0 | dir
假如駭客在利用時輸入的是
0|net user hacker/add
那麼造成的後果將不堪設想
以下是可能會造成任意命令執行的函式
system|passthru|exec|popen|proc_open|move_uploaded_file|eval|copy|shell_exec|assert
任意命令執行漏洞修補辦法
在寫程式時儘量地使變數不能被使用者所控制!且注意變數初始化的問題。
使用str_replace對“%”,”|”,“>”進行替換
進入函式前判斷變數是否合法。
暴力破解漏洞
這個是漏洞?算是吧…
祭上神器Burp Suite,Burp suite執行後,Burp suite,Proxy 開起預設的8080 埠作為本地代理介面。
使用Burp suite透過置一個web 瀏覽器使用其代理伺服器,見下圖 
然後開啟你要暴力破解的後臺,隨便輸入一個賬號密碼…把抓到的包send to intruder  
Start attack~~~
然後就對面返回包的大小,知道密碼
暴力破解漏洞修補方法
加個google驗證碼,保證沒有程式能識別出來…
檔案包含漏洞
檔案包含漏洞分為兩種,一種是遠端包含,一種是本地包含。
伺服器透過php的特性(函式)去包含任意檔案時,由於要包含的這個檔案來源過濾不嚴,從而可去呼叫並執行一個文(木)件(馬),而我們可以構造這個文(木)件(馬)來達到邪惡的目的。
涉及到的危險函式,include(),require()和include_once(),require_once()
現在遠端包含的漏洞已經不多了,但是遠端包含的危害是最大,相當於一個命令執行。
而本地包含,有時配合一下解析漏洞往往可以getshell.
例:
#!php
<?php
$file = $_GET['page']; //The page we wish to display
?>
Include.php內容:
#!php
<?php
echo "hello world\n";
?>
總結
在編寫程式時,應有良好的程式碼習慣,如使用變數前初始化。
做安全的過濾在全域性裡做,或者寫在類裡。
不要相信資料,所有輸入在得到證明之前都是不可信的,所有從使用者上輸入的資料都應該加以判斷。
不返回過多錯誤的原因,如一個駭客進行sql注入。
多上wooyun看漏洞
相關文章
- Python中的10個常見安全漏洞及修復方法2020-03-07Python
- Linux常見漏洞修復教程!2024-03-06Linux
- 論PHP常見的漏洞2020-08-19PHP
- Android 常見安全漏洞修復理論與實踐2019-06-16Android
- 【小白必學】檔案上傳的漏洞介紹及常見防禦方法2023-04-06
- TomcatAJP檔案包含漏洞及線上修復漏洞2020-09-12Tomcat
- 常見的Web安全漏洞及測試方法介紹2019-08-09Web
- thinkcmf 網站最新漏洞修復方法2019-11-20網站
- 常見中介軟體漏洞復現(上)2022-03-18
- WordPress網站漏洞利用及漏洞修復解決方案2019-02-24網站
- 框架網站漏洞修復防護方法2019-11-12框架網站
- 修復 SSL Certificate Problem,如何定位及常見問題的處理策略2021-10-30
- 【漏洞修復通知】修復Apache Shiro認證繞過漏洞2022-11-24Apache
- PrestaShop網站漏洞修復如何修復2019-01-02REST網站
- 網站漏洞測試php程式碼修復詳情2020-03-02網站PHP
- 網站漏洞修復 上傳webshell漏洞修補2019-06-03網站Webshell
- 網站安全防護-PHP反序列化漏洞修復2020-08-11網站PHP
- 怎麼修復網站漏洞騎士cms的漏洞修復方案2019-01-03網站
- Python中的常見方法2024-06-17Python
- phpStudy poc漏洞復現以及漏洞修復辦法2019-09-27PHP
- 運維常見軟體問題排查與修復2023-11-09運維
- 【JAVA-WEB常見漏洞-XSS漏洞】2020-11-23JavaWeb
- 網站程式碼漏洞審計挖掘與修復方法2020-08-13網站
- 如何修復使用 Python ORM 工具 SQLAlchemy 時的常見陷阱2019-11-19PythonORMSQL
- 從零開始學習各種常見未授權訪問漏洞2020-12-09
- Linux 髒管道kernel提權漏洞復現及修復(CVE-2022-0847)2022-03-11Linux
- git 常見問題及操作方法2018-10-27Git
- Nacos 常見問題及解決方法2019-11-05
- 幾種常見取樣方法及原理2022-06-08
- 常見轉義符學習2024-08-15
- python常見漏洞總結2022-05-01Python
- Python開發常見漏洞2020-12-29Python
- struts2架構網站漏洞修復詳情與利用漏洞修復方案2018-12-03架構網站
- PHP 常見問題2018-11-24PHP
- Java命令學習系列(零)——常見命令及Java Dump介紹2018-11-10Java
- Log4j 漏洞修復和臨時補救方法2021-12-14
- weblogic T3 漏洞修復2020-08-14Web
- vue實踐中的常見知識漏洞0012019-03-04Vue