当前位置:网站首页 > 黑客培训 > 正文

复活Navex:使用图查询进行代码分析

freebuffreebuf 2020-05-18 385 0

本文来源:斗象智能安全平台

从了解到修复 

dvwa/vulnerabilities/brute/source/low.php

?php  if( isset( $_GET[ 'Login' ] ) ) {     // 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          $avatar = $row["avatar"];          // Login successful         $html .= "p>Welcome to the password protected area {$user}/p>";         $html .= "img src=\"{$avatar}\" />";     }     else {         // Login failed         $html .= "pre>br />Username and/or password incorrect./pre>";     }      ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res); }  ?> 

虽说存在一些误报, 但是基本实现了漏洞分析查询的功能

漏报原因分析

  1. dvwa/vulnerabilities/sqli/source/medium.php
?php  ?php  if( 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 results     while( $row = mysqli_fetch_assoc( $result ) ) {         // Display values         $first = $row["first_name"];         $last  = $row["last_name"];          // Feedback for end user         $html .= "pre>ID: {$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"]); ?> 

Medium级别的代码利用mysql_real_escape_string函数对以下特殊符号进行转义

但是此处为数字型注入不需要单引号, 可以绕过

$query = "SELECT first_name, last_name FROM users WHERE user_id = $id;";

所以这里还有优化空间, 比如多一步判断注入类型, 然后忽略无效的过滤

  1. dvwa/vulnerabilities/sqli/source/high.php
?php  if( isset( $_SESSION [ 'id' ] ) ) {     // Get input     $id = $_SESSION[ 'id' ];      // Check database     $query  = "SELECT first_name, last_name FROM users WHERE user_id = '$id' LIMIT 1;";     $result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( 'pre>Something went wrong./pre>' );      // Get results     while( $row = mysqli_fetch_assoc( $result ) ) {         // Get values         $first = $row["first_name"];         $last  = $row["last_name"];          // Feedback for end user         $html .= "pre>ID: {$id}br />First name: {$first}br />Surname: {$last}/pre>";     }      ((is_null($___mysqli_res = mysqli_close($GLOBALS["___mysqli_ston"]))) ? false : $___mysqli_res);         }  ?> 

这里使用的是$_SESSION [ 'id' ]注入, 通过访问

dvwa/vulnerabilities/sqli/session-input.php

其实该点可控 $_SESSION[ 'id' ] = $_POST[ 'id' ];

?php  define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' ); require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';  dvwaPageStartup( array( 'authenticated', 'phpids' ) );  $page = dvwaPageNewGrab(); $page[ 'title' ] = 'SQL Injection Session Input' . $page[ 'title_separator' ].$page[ 'title' ];  if( isset( $_POST[ 'id' ] ) ) {     $_SESSION[ 'id' ] =  $_POST[ 'id' ];     //$page[ 'body' ] .= "Session ID set!br />br />br />";     $page[ 'body' ] .= "Session ID: {$_SESSION[ 'id' ]}br />br />br />";     $page[ 'body' ] .= "script>window.opener.location.reload(true);/script>"; }  $page[ 'body' ] .= " form action=\"#\" method=\"POST\">     input type=\"text\" size=\"15\" name=\"id\">     input type=\"submit\" name=\"Submit\" value=\"Submit\"> /form> hr /> br />  button onclick=\"self.close();\">Close/button>";  dvwaSourceHtmlEcho( $page );  ?> 

但是从单文件来看, 该输入点不可控, 所以产生了漏报, 如果优化需要解析 include等节点进行跨文件判断

  1. dvwa/vulnerabilities/sqli_blind/source/medium.php
?php  if( isset( $_POST[ 'Submit' ]  ) ) {     // Get input     $id = $_POST[ 'id' ];     $id = ((isset($GLOBALS["___mysqli_ston"])       // 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 errors     if( $num > 0 ) {         // Feedback for end user         $html .= 'pre>User ID exists in the database./pre>';     }     else {         // Feedback for end user         $html .= 'pre>User ID is MISSING from the database./pre>';     }      //mysql_close(); }  ?> 

这里也是数字型注入的问题, 不再赘述

总结

本文重点在于静态分析部分的修复, 动态分析部分其实相对简单一些, 也就是剪枝的过程, 后续也可以实现.

我的想法是:

  1. 静态分析使用JoernCodeql等工具来实现, 然后生成导航图
  2. exp使用固定poc+ 动态变异 fuzzing 的思想
  3. 动态爬虫使用论文中所使用的crawler4j 或者最近比较火的crawlergo
  4. 然后后端使用Baidu Raspprvd来实现监控是否执行成功

PS.也可以实现一种类似动态跃点的标记, 比如挖掘反序列化的利用链, 具有某些特性的的节点,

比如 $a=$this->$ppp; $a->arr($b);

那么这个点只是L1级别的信息, 但是配合unserialize, 配合其他的类的__call,

将这些L1的标记组合起来,就能组合成存在风险的L2级别的安全风险.

最近对自动化审计AEG这方面比较感兴趣, 欢迎讨论.

参考

https://github.com/UUUUnotfound/Navex_fixed

转载请注明来自网盾网络安全培训,本文标题:《复活Navex:使用图查询进行代码分析》

标签:代码分析Navex图查询

关于我

欢迎关注微信公众号

关于我们

网络安全培训,黑客培训,渗透培训,ctf,攻防

标签列表