次去打HCTF決賽,用了這個本身寫的WAF,web基本上沒被打,被打的漏洞是文件包含漏洞,這個功能在本人這個waf裏確實非常捉急,因爲只是簡單檢測了..和php[35]{0,1},致使比賽因爲文件包含漏洞web上失分了一次。不過如今不是很想去改進了。這個是比賽專用waf,商業價值幾乎爲0。php
若是是框架寫出的web就很好部署了,直接require在重寫文件或者數據庫文件中,若是是零散的php文件,那也有辦法,若是是fastcgi(nginx,IIS比較常見)運行的php就在.user.ini加一句,具體百度一下.user.ini的後門,原理同樣。其餘狀況也能夠寫個腳本強行在每一個PHP前面加一句,腳本代碼的樣例也會放出來。(固然apache也能夠.htaccess強行重寫到waf再轉回原頁面,可是萬一沒重寫環境呢)html
具體代碼以下nginx
WAFweb
1 <?php 2 //error_reporting(E_ALL); 3 //ini_set('display_errors', 1); 4 5 /* 6 ** 線下攻防php版本waf 7 ** 8 ** Author: 落 9 */ 10 11 /* 12 檢測請求方式,除了get和post以外攔截下來並寫日誌。 13 */ 14 if($_SERVER['REQUEST_METHOD'] != 'POST' && $_SERVER['REQUEST_METHOD'] != 'GET'){ 15 write_attack_log("method"); 16 } 17 18 $url = $_SERVER['REQUEST_URI']; //獲取uri來進行檢測 19 20 $data = file_get_contents('php://input'); //獲取post的data,不管是不是mutipart 21 22 $headers = get_all_headers(); //獲取header 23 24 filter_attack_keyword(filter_invisible(urldecode(filter_0x25($url)))); //對URL進行檢測,出現問題則攔截並記錄 25 filter_attack_keyword(filter_invisible(urldecode(filter_0x25($data)))); //對POST的內容進行檢測,出現問題攔截並記錄 26 27 /* 28 檢測過了則對輸入進行簡單過濾 29 */ 30 foreach ($_GET as $key => $value) { 31 $_GET[$key] = filter_dangerous_words($value); 32 } 33 foreach ($_POST as $key => $value) { 34 $_POST[$key] = filter_dangerous_words($value); 35 } 36 foreach ($headers as $key => $value) { 37 filter_attack_keyword(filter_invisible(urldecode(filter_0x25($value)))); //對http請求頭進行檢測,出現問題攔截並記錄 38 $_SERVER[$key] = filter_dangerous_words($value); //簡單過濾 39 } 40 41 /* 42 獲取http請求頭並寫入數組 43 */ 44 function get_all_headers() { 45 $headers = array(); 46 47 foreach($_SERVER as $key => $value) { 48 if(substr($key, 0, 5) === 'HTTP_') { 49 $headers[$key] = $value; 50 } 51 } 52 53 return $headers; 54 } 55 56 57 /* 58 檢測不可見字符形成的截斷和繞過效果,注意網站請求帶中文須要簡單修改 59 */ 60 function filter_invisible($str){ 61 for($i=0;$i<strlen($str);$i++){ 62 $ascii = ord($str[$i]); 63 if($ascii>126 || $ascii < 32){ //有中文這裏要修改 64 if(!in_array($ascii, array(9,10,13))){ 65 write_attack_log("interrupt"); 66 }else{ 67 $str = str_replace($ascii, " ", $str); 68 } 69 } 70 } 71 $str = str_replace(array("`","|",";",","), " ", $str); 72 return $str; 73 } 74 75 /* 76 檢測網站程序存在二次編碼繞過漏洞形成的%25繞過,此處是循環將%25替換成%,直至不存在%25 77 */ 78 function filter_0x25($str){ 79 if(strpos($str,"%25") !== false){ 80 $str = str_replace("%25", "%", $str); 81 return filter_0x25($str); 82 }else{ 83 return $str; 84 } 85 } 86 87 /* 88 攻擊關鍵字檢測,此處因爲以前將特殊字符替換成空格,即便存在繞過特性也繞不過正則的\b 89 */ 90 function filter_attack_keyword($str){ 91 if(preg_match("/select\b|insert\b|update\b|drop\b|delete\b|dumpfile\b|outfile\b|load_file|rename\b|floor\(|extractvalue|updatexml|name_const|multipoint\(/i", $str)){ 92 write_attack_log("sqli"); 93 } 94 95 //此處文件包含的檢測我真的不會寫了,求高人指點。。。 96 if(substr_count($str,$_SERVER['PHP_SELF']) < 2){ 97 $tmp = str_replace($_SERVER['PHP_SELF'], "", $str); 98 if(preg_match("/\.\.|.*\.php[35]{0,1}/i", $tmp)){ 99 write_attack_log("LFI/LFR");; 100 } 101 }else{ 102 write_attack_log("LFI/LFR"); 103 } 104 if(preg_match("/base64_decode|eval\(|assert\(/i", $str)){ 105 write_attack_log("EXEC"); 106 } 107 if(preg_match("/flag/i", $str)){ 108 write_attack_log("GETFLAG"); 109 } 110 111 } 112 113 /* 114 簡單將易出現問題的字符替換成中文 115 */ 116 function filter_dangerous_words($str){ 117 $str = str_replace("'", "‘", $str); 118 $str = str_replace("\"", "「", $str); 119 $str = str_replace("<", "《", $str); 120 $str = str_replace(">", "》", $str); 121 return $str; 122 } 123 124 /* 125 獲取http的請求包,意義在於獲取別人的攻擊payload 126 */ 127 function get_http_raw() { 128 $raw = ''; 129 130 $raw .= $_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI'].' '.$_SERVER['SERVER_PROTOCOL']."\r\n"; 131 132 foreach($_SERVER as $key => $value) { 133 if(substr($key, 0, 5) === 'HTTP_') { 134 $key = substr($key, 5); 135 $key = str_replace('_', '-', $key); 136 $raw .= $key.': '.$value."\r\n"; 137 } 138 } 139 $raw .= "\r\n"; 140 $raw .= file_get_contents('php://input'); 141 return $raw; 142 } 143 144 /* 145 這裏攔截並記錄攻擊payload 146 */ 147 function write_attack_log($alert){ 148 $data = date("Y/m/d H:i:s")." -- [".$alert."]"."\r\n".get_http_raw()."\r\n\r\n"; 149 $ffff = fopen('log_is_a_secret_file.txt', 'a'); //日誌路徑 150 fwrite($ffff, $data); 151 fclose($ffff); 152 if($alert == 'GETFLAG'){ 153 echo "HCTF{aaaa}"; //若是請求帶有flag關鍵字,顯示假的flag。(2333333) 154 }else{ 155 sleep(15); //攔截前延時15秒 156 } 157 exit(0); 158 } 159 160 ?>
1 import os 2 3 base_dir = '/Users/apple/Documents/data' #web路徑 4 5 def scandir(startdir) : 6 7 os.chdir(startdir) 8 for obj in os.listdir(os.curdir) : 9 path = os.getcwd() + os.sep + obj 10 if os.path.isfile(path) and '.php' in obj: 11 modifyip(path,'<?php','<?php\nrequire_once(\'waf.php\');') #強行加一句代碼 12 if os.path.isdir(obj) : 13 scandir(obj) 14 os.chdir(os.pardir) 15 16 def modifyip(tfile,sstr,rstr): 17 try: 18 lines=open(tfile,'r').readlines() 19 flen=len(lines)-1 20 for i in range(flen): 21 if sstr in lines[i]: 22 lines[i]=lines[i].replace(sstr,rstr) 23 open(tfile,'w').writelines(lines) 24 25 except Exception,e: 26 print e 27 28 29 scandir(base_dir)
祝你們之後攻防賽取得好成績.轉載自:http://www.hackblog.cn/post/75.htmlsql