[心得]2008八月份 SA@Tainan PHP 程式設計 – 初階資訊安全(8/30)

今天從嘉義跑到台南聽 酷!學園 舉辦的 2008八月份 SA@Tainan PHP 程式設計 – 初階資訊安全(8/30) ,今天一大早就起床了,差點沒趕上火車,到了台南地點在社區大學,其實蠻近的,大概騎車5分鐘就到了喔,其實不會很趕,到了現場,第一次看到梁楓大大阿,感覺很有威勢,我看現場年齡層分佈好像很廣,有很多都是長輩了,不過大部分還是學生為主,然後我想大概有很多是工作人員,其實我都不太認識,我大概只知道梁楓大大,因為在酷!學園也一段時間了,哈哈,今天講的主題,我非常的有興趣,我看投影片還蠻多的,可是都是跳著講,然後一些實做的部份,然後最後一小時是在解如何拿到 Linux 的主機 /etc/passwd 的資訊。 今天聽完,大概整理一下,比較注重 php security 部份,包含 SQL injection (資料隱碼),還有跳脫字元攻擊,一些等等,還有上傳檔案該注意事項,現場有些實做部份,包含 SQL injection 攻擊,如何破解一個網站 首先是 shell_exec,利用這個來達成取得 /etc/passwd 的檔案內容,因為如果網頁 text 欄位可以輸入 UNIX 指令,當然如果你沒有過濾的話,基本上要拿到非常容易,利用 ; 號就可以拿到了喔,哈哈,當然防禦方法也有啦,因為在 Linux 裡面 ; 代表後面指令會繼續執行,所以你只要在 text 欄位填入:
; cat /etc/passwd
這樣就可以拿到 passwd 的內容了,當然拿到這個,就可以 ……. 這是第一種介紹,解決方法就是在跑 Unix 指令的時候加入 escapeshellcmd 就可以了,上面的指令就會變成
\; cat /etc/passwd
接下來是 SQL injection 這算是比較常見的攻擊手法,但是也是很多剛開始 PHP 比較不會去注意的,剛開始學習,大家都是這樣寫 SQL
#
# 大概這樣 
#
$sql = "SELECT * FROM user_table where user_id = '".$_POST['user_id']."' and password = '".$_POST['password']."'"
嗯嗯 那我只要在 user_id 這個欄位打入
admin’ or 1 = 1 —
這樣你的 SQL 語法會變成下面這樣
#
# -- 代表註解
#
SELECT * FROM user_table where user_id = 'admin' or 1 = 1 -- ' and password = ''
看到了吧,很恐怖吧,當然防禦方法很容易,那就是利用 mysql_escape_string
	if( is_array($_POST) )
	{
		while( list($k, $v) = each($_POST) )
		{
			if( is_array($_POST[$k]) )
			{
				while( list($k2, $v2) = each($_POST[$k]) )
				{
					$_POST[$k][$k2] = mysql_escape_string($v2);
				}
				@reset($_POST[$k]);
			}
			else
			{
				$_POST[$k] = mysql_escape_string($v);
			}
		}
		@reset($_POST);
	}
再來呢?講上傳檔案這部份,其實聽完,我的實做方式跟梁楓大大講的差不多,重點就是底下幾點: 1. 檔案上傳的時候,務必檢查副檔名,然後改掉檔名存成數字檔案,或者是亂碼檔案 2. 把真正的檔名存在資料庫,跟檔案大小還有副檔名資訊 3. 存放路徑不要是在 web 可以存取的第放,必如說 /var/www/html/ 不要存在這底下 看是要存在 /home/data 4. 檔案下載利用 header 當方式讀取 readfile 可以參考我這一篇:[PHP] header下載檔案 搭配資料庫 下載檔案如果大致上遵守上面那些,大概就沒啥問題了喔~今天內容大概是這樣 最後有一個小小測試,就是一個網頁提供一個上傳檔案,然後要直接取出 /etc/passwd 的內容,那大概就是上傳一個 php 檔案,裡面寫:
$output
"; ?> 然後猜出檔案路徑,那大概就是到跟目錄底下,看看有沒有鎖 apache Index 的設定,哈哈,這樣就猜到了,然後執行他,就可以拿出結果,相當容易。^^ 聽完感覺不錯,可是好像沒有講到比較深入的部份,哈哈~我比較想聽深入的部份啦,XDDDDD,不過感謝老師,講的很清楚。
  • ant

    請問 darkhero 有說明為何要把上傳檔案做這些處理嗎?
    1. 改成亂碼檔名
    2. 檔案不要放在 web 可以存取之處
    3. 用 header 處理

    ^_^

  • chrisliu

    回覆 ant
    1. 怕被猜檔名,或是省去處理中文字。
    2. 猜到網址就可以直接下載了。
    3. 用 header 處理只是要把檔案內容從 web 讀不到的地方讓 web 讀到而已吧。

  • 阿,這場是 梁楓大大 的課程喔,不是 darkhero 兄喔,您搞混了喔
    幫忙補充三:
    用 header 方式下載,可以避免檔案上傳是 php副檔名 檔案,這樣只能夠讓大家達到下載功能
    避免去執行php這隻檔案。^^