前記
這次寫的主要是關於服務器的安全配置及加固,部分例子會以比賽時的環境進行講解,對一些常見的漏洞進行加固講解,以及一些安全配置思路的分享。疫情過後開學事情就會比較多,所以之後更新的速度可能會很慢。剛好實驗室的學弟們也要開始學習混戰攻防,看到了就當我親手教過了吧哈哈哈。
分組混戰
首先從比賽時的環境進行分析,在我比賽的三年中,我接觸到關於linux的靶機環境有很多個,現在主要講解的是2017國賽那一臺,因爲漏洞比較有講解意義。
首先當我們拿到一臺靶機,第一件事情應該做的就是修改root密碼,第一臺靶機的root是弱口令123456,毋庸置疑我們需要修改密碼,一個linux的root用戶如果被掌握,那後果很嚴重,其他隊伍完全可以對你的靶機進行進行關機且不能重啓會不斷觸犯所有違規操作。比賽環境佈置違規操作閥值一般爲3,會掃描該服務三次,如果均未掃描到服務開啓則會觸犯違規,一般會去扣除三次。當然也有那種直接給你不斷扣的負數的另當別論。
對於服務器賬號安全是非常重要的,我們也應該檢查/etc/passwd下是否存在其他危險用戶,比如admin以及guest等,查看其權限,刪除用戶或者修改危險用戶密碼。其次應該觀察目錄下是否存在木馬文件,比如一些奇怪命名的文件,之前的一個漏洞就是在/root/目錄下存在多個序號命名的文件,如果掃描端口我們會發現這些文件名正是所開啓的一些端口的序號。通過netcat連接端口可以致使命令執行,且因運行在root用戶下所以權限爲system。
再就是web安全,在linux中我們可以查看web目錄下的站點,首先需要檢查是否存在木馬文件,其次檢查功能性頁面是否存在web漏洞,比如文件上傳,命令執行,SQL注入,目錄穿越等,以上這幾個漏洞很巧的第一臺靶機中都有,所以接下來我們會單獨進行講解加固方案。
當然存在站點的地方自然就會有數據庫,數據庫我們主要是需要防範數據庫用戶密碼,這是必要的。因爲如果獲取到的是數據庫的管理員用戶後果也非常嚴重,像sql server的SA以及mysql的root這些都是必須設置爲強密碼的。
再就是修改配置文件,禁用危險函數,比如Apache的httpd.conf以及php.ini這些都是需要我們去檢查配置的。
接下來我們講解一些重要的漏洞加固方法
危險端口
以靶機爲例,我們首先需要刪除這些危險文件,如果直殺進程,端口仍然有可能重啓。
使用命令netstat -ntlp查看所有開放的服務以及端口情況。
然後使用pkill -9 "autorunp*"刪除即可,服務名根據具體環境而定。
還有一些服務本身在特定的版本中就是危險的,比如vsftp 2.3.4這是一個比較危險的版本,在利用後攻擊者可獲取root權限,在利用時因爲其用戶名提交爲任意名稱後添加:)被稱爲笑臉漏洞,即可開啓一個6200端口獲取root權限。
還有像Windows中445,135,3389等一些端口在不必要時也是可以關閉的,像17-010,0708,在服務器特定版本時沒有打補丁開啓相關端口是非常危險的
數據庫加固
其實數據庫的加固還是比較簡易的,首先撇開web不說,我們這裏只需要檢查一些用戶修改密碼即可,
使用select user();命令查看數據庫用戶。修改用戶密碼命令爲:
select user();
use mysql;
update user from password=password("更改後的密碼") where user="指定要修改的用戶名";
flush privileges;
注意一定要刷新權限,不然我們修改的密碼是不能生效的。
當然如果暴力刪除用戶也是可以的。
drop user xxx //用戶名
配置文件規範
在我們對配置文件存在錯誤的配置時也會有一些安全隱患,下面我們主要對http.conf以及php.ini進行講解。
首先我們來看http.conf中對於Apche的用戶的配置,這裏是apache,但是如果被錯誤的配置爲root那麼在web上執行的命令同樣具有超級管理員權限。即使如此,哪怕獲得apache的shell權限配合其他的一些操作仍可以對服務器造成十分嚴重的危害,在我的<Web木馬提權滲透>一文中就有對web提權至root的講解,以及fork炸彈之流,更是可以不依靠root去權限即可對服務器進行資源耗盡攻擊,僅僅幾秒鐘服務器就會處理不了大量後臺進程而死機其語句僅僅只需要一行代碼。
:() { :|:& };:
對於目錄瀏覽我們同樣需要提防,如果hack可以對你的web服務器進行目錄瀏覽那真的是太好了,省去了hack對你的站點目錄掃描了。所以我們也需要對其進行配置,這裏apache默認是可以任意瀏覽的。這裏我們需要修改本段。
Options Indexes FollowSymLinks修改爲 Options FollowSymLinks
同樣我們也不能輸出錯誤回顯,因爲錯誤回顯某些時候會泄漏關於服務器的一些重要信息。
php_flag display_errors off
php_value error_reporting 2047
對於上傳目錄我們也需要進行禁止腳本執行,杜絕文件上傳執行shell。
配置中增加如下內容:
<Directory "上傳目錄">
<Files ~ ".php">
Order allow,deny
Deny from all
</Files>
</Directory>
接下來進行講解php配置文件
對於php.ini文件,首先我們應該進行限制危險函數,例如system,eval等函數在不必要的情況下可以禁用。
同樣的在上面的open_basedir我們也可以進行配置,限制php訪問的目錄,這樣可以防護對於文件包含造成的影響。
同理我們也可以進行配置GPC對一些特殊符號進行過濾,以及開啓安全模式防護服務器安全。
magic_quotes_gpc=On
safe_mode=on
也可以對上傳的一些信息進行限制,比如限制禁用上傳功能或者限制上傳文件大小。
Web安全
對於web安全我們主要講解三個比較常見的漏洞,SQL注入、文件上傳、命令執行。
首先來講解SQL注入,衆所周知SQL注入是由於外部提交的數據未經過濾直接拼接到了SQL語句中並被數據庫執行。SQL也成文OWASP top 10的榜首,其危害不言而喻。
<?php
$SELF_PAGE = substr($_SERVER['PHP_SELF'],strrpos($_SERVER['PHP_SELF'],'/')+1);
if ($SELF_PAGE = "sqli_id.php"){
$ACTIVE = array('','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','active open','','active','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','','',);
}
$PIKA_ROOT_DIR = "../../";
include_once $PIKA_ROOT_DIR . 'header.php';
include_once $PIKA_ROOT_DIR."inc/config.inc.php";
include_once $PIKA_ROOT_DIR."inc/function.php";
include_once $PIKA_ROOT_DIR."inc/mysql.inc.php";
$link=connect();
$html='';
if(isset($_POST['submit']) && $_POST['id']!=null){
//這裏沒有做任何處理,直接拼到select裏面去了,形成Sql注入
$id=$_POST['id'];
$query="select username,email from member where id=$id";
$result=execute($link, $query);
if(mysqli_num_rows($result)>=1){
while($data=mysqli_fetch_assoc($result)){
$username=$data['username'];
$email=$data['email'];
$html.="<p class='notice'>hello,{$username} <br />your email is: {$email}</p>";
}
}else{
$html.="<p class='notice'>您輸入的user id不存在,請重新輸入!</p>";
}
}
?>
以上即是一段典型的數字型注入的代碼。
對於SQL注入我們從代碼層次來看,可以進行危險字符過濾,或者預編譯的方式進行數據庫操作,這裏推薦的是預編譯,不僅可以預防SQL注入也可以提高執行效率,當然如果您預編譯仍然使用了SQL語句拼接的方式那依舊是沒用,我們需要把參數處以佔位符表示,將SQL語句提前預設好,使用set進行替換佔位符表示的參數,這樣SQL編譯器就不會認爲提交上來的是一段SQL語句而只是參數了。
以上兩段代碼即是預編譯存在注入的案例對比。
這裏講一個不少程序員都會出現的問題
這裏大家可以看到關於zx這張表中的內容,看似id爲6以及7的deepName是不是一樣呢?答案是否的,接下來我們看一下
這裏我們來看一下這個表的結構,我們可以看到deepName爲varchar類型並且長度限制爲8。
這裏我們假設程序員管理員登錄的SQL語句爲:
select count(*) from zx where deepName="$name" and password="$passwd";
這裏我們假設爲管理員用戶名爲admin,密碼爲123456。我們來執行下這段語句。
我們發現count爲1,這時一般的程序邏輯在判斷可以查詢出數據後一般就直接跳過登錄了。但是我們再添加一個用戶
這時我們又創建了一個用戶,但是注意他的語句。我們在admin的後面輸入了4個空格,結合admin本身5個字符達到9個已經越界了。
insert into zx values(9,"admin ","123");
下圖我們可得,越界的字符被自動刪除了。id爲6的字段長度爲5,id爲9的則長度爲8。
我們下面來看一下正章
這裏我們可以看到用戶通過用戶名admin (三個空格),指定密碼爲123456卻成功返回了count值,在實際站點中這樣已經造成越權登陸。
你是不是若有所思了呢?
文件上傳防護
對於文件上傳來講,最重要莫過於代碼執行了,如果上傳到一個服務器後但是卻沒有辦法解析執行,那麼這樣的文件上傳是沒有意義的。所以我們需要有針對性的進行加固,對於代碼層來講,應該多重驗證,對於後綴名、MIME、文件大小、文件內容等均需要進行驗證,驗證後綴以及MIME需使用白名單策略,相比黑名單更加安全一些,畢竟黑名單總是可能會存在漏掉的一些文件類型。假設我們要求上傳的是圖片類型。那麼有一個php中的函數getimagesize()函數可以對圖片信息進行驗證,防止假圖片,雖然這個函數可以被繞過但是仍是提高了攻擊門檻,畢竟在現今互聯網中真正對網絡造成危害的仍是那些不懂編程的"腳本小子"。
命令執行
命令執行漏洞危險其實挺大了也很普遍,在一些CMS中我們總是能看到目標後臺對服務器進行ping操作,這時如果開發人員未對命令進行規範編碼則有可能存在任意命令執行。
<?php
$arg=$_SERVER["REMOTE_ADDR"];
if($arg){
system("ping".$arg);
}
?>
這是一個最經典的命令執行漏洞,我們可以通過僞造ip地址進行命令執行,抓包設置
X-Forwarded-For進行代碼執行,構建payload:X-Forwarded-For:127.0.0.1|ls
網上也有一些案例講解,但是我覺得比較離譜就貼了這個了,像一些直接從外部獲取參數的,其實程序員一般來講並不會那麼做。所以爲了貼合真實我還是以僞造ip這種方式進行講解,可能對初學者不友好,這點見諒。
除了|以外還有&、&&、||可以作爲管道符進行連接,但是觸發條件不同,這個大家可以自己百度學習。對於命令執行的加固,在代碼層我們可以過濾這一類管道符,PHP提供了兩個函數escapeshellcmd以及escapeshellarg分別是過濾整條命令以及參數的。對於這些漏洞其實完全是可以杜絕的。
後記
本次就講這麼多,通過上面的解析相信大家對於服務器加固已經有了一個初步的認識,當然一切的學習仍是需要與實踐相結合,所以對於加固這一塊仍是需要多研究多實踐。對於一個服務器的整體安全來講,不能單單隻靠一個地方的防護,缺少這個意識也正是當今仍有許多服務器存在漏洞隱患等。網絡安全是一個整體,並不存在一勞永逸,上面大家可能會發現在服務器配置與代碼層有一些防護是重疊的,這是不是說我們可以不配置重疊的呢?答案我認爲是否的,依然是上面那句話,網絡安全是一個整體,有一個安全理念叫做縱深防禦,不同方面相互構成一個整體,像我們通過web可以系統命令執行,數據庫可以寫入文件一個道理,不同服務之間是可以相互影響的。在道哥的<<白帽子講Web安全>>中我的安全世界觀一章中令我印象深刻,他說:一個水桶能夠裝多少水不是取決於最長的那塊木板,而是最短的那一塊,我認爲這很形象的說明了當今網絡安全的問題。像SQL注入真的出現有許多年了,預編譯技術出現也有許多年,但是爲什麼至今仍有一些網站存在SQL注入呢?我認爲更多的是一部分程序員並沒有接受新的開發技術,在前幾年我學習WEB開發時,我在培訓學習到的是預編譯,但是在回來看網上的一些教程時,仍然是那些拼接語句,直接連接數據庫的方法,所以這也與學習資源有關,許多安全的開發技術並沒有普及開來,在我學習時對於學習資源這一點真的非常感慨,畢竟自學始終有限。
**就說到這裏吧,希望大家能夠美夢成真!
最近在等遠方傳來的消息,希望我也能美夢成真吧!
**