网络攻防比赛PHP版本WAF

次去打HCTF决赛,用了这个自己写的WAF,web基本上没被打,被打的漏洞是文件包含漏洞,这个功能在本人这个waf里确实很是捉急,由于只是简单检测了..和php[35]{0,1},导致比赛由于文件包含漏洞web上失分了一次。不过现在不是很想去改进了。这个是比赛专用waf,商业价值几乎为0。

如果是框架写出的web就很好部署了,直接require在重写文件或者数据库文件中,如果是零散的php文件,那也有办法,如果是fastcgi(nginx,IIS比较常见)运行的php就在.user.ini加一句,具体百度一下.user.ini的后门,原理一样。其他情况也可以写个脚本强行在每个PHP前面加一句,脚本代码的样例也会放出来。(当然apache也可以.htaccess强行重写到waf再转回原页面,但是万一没重写环境呢)

具体代码如下

WAF

PHP
  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 ?>

 

Python
 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.html

转载于:https://www.cnblogs.com/nul1/p/8835264.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值