• PHP代码审计入门-DVWA靶场命令注入篇


    0x00  写在前面

    从零学习php,最终目的实现代码审计入门,软件采用sublime text,环境使用phpstudy搭建,数据库是navicat,需要有基本的前端基础、简单的php+mysql后端基础、渗透知识和漏洞原理,文章跟随流沙前辈学习记录,看看曾经遥不可及的代码审计能不能慢慢啃下来。

    本章为代码审计入门第六篇-DVWA靶场篇,对DVWA靶场漏洞进行代码审计。

    0x01  常用的命令连接符

    Windows下常用的命令连接符

    &,以test、whoami、dir命令测试

    1.前面为假,执行后面命令

    2.前面为真,前后命令都执行

    通俗解释: 前面命令执行后接着去执行后面命令

     &&,以test、whoami、dir命令测试

    1.前面为假,前后都不执行命令

    2.前面为真,前后都执行命令

    通俗解释:前面命令执行成功了才会去执行后面命令。

     | 和 || ,以ping和whoami为例

    | ,浅浅的讲:直接执行后面命令

    || ,前面为假才执行后面命令

    Linux下常用的命令连接符和windows一致,唯一区别的是 ;  的使用,;的作用连接多条命令,每条命令都执行这里以vps为例。

    常用的命令连接符就差不多了,还有一个常用的但不是命令连接符的东东,基本就这么多。

    >      写入并覆盖

    >>   追加

    0x02  Command Injection

    命令注入模块,注释写在代码里,尽量用详细的语言描述代码含义。

    level-low

    命令执行,但没有作任何限制

    1. low.php
    2. if( isset( $_POST[ 'Submit' ] ) ) { //isset函数检测变量非空
    3. // 判断post过来的数据是否被提交过来
    4. // Get input
    5. $target = $_REQUEST[ 'ip' ];
    6. // 得到接收的'ip'赋值给变量$target
    7. // Determine OS and execute the ping command.
    8. if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    9. // php_uname 返回运行 PHP 的系统的有关信息 (mode:'s') 返回操作系统
    10. $cmd = shell_exec( 'ping ' . $target );
    11. // Windows 系统 ,用 shell_exec 运行拼接命令 ping.$target,例如ping 127.0.0.1
    12. }
    13. else {
    14. // *nix
    15. $cmd = shell_exec( 'ping -c 4 ' . $target );
    16. // Linux系统,shell_exec 运行拼接命令 ping -c 4.$target,原因是linux下如果不指定ping次数会一直ping下去
    17. }
    18. // Feedback for the end user
    19. // 输出操作命令后的结果
    20. $html .= "
      {$cmd}
      "
      ;
    21. }
    22. ?>

    level-medium

    相比于low,增加一个黑名单机制

    1. medium.php
    2. if( isset( $_POST[ 'Submit' ] ) ) {
    3. // Get input
    4. $target = $_REQUEST[ 'ip' ];
    5. // Set blacklist
    6. $substitutions = array(
    7. '&&' => '',
    8. ';' => '',
    9. );
    10. //可以理解为把 && 和 ; 设为一个黑名单
    11. // Remove any of the charactars in the array (blacklist).
    12. $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    13. // 用str_replace对变量 $target 过滤,匹配到黑名单里的 && 和 ; 会过滤
    14. // Determine OS and execute the ping command.
    15. if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    16. // Windows
    17. $cmd = shell_exec( 'ping ' . $target );
    18. }
    19. else {
    20. // *nix
    21. $cmd = shell_exec( 'ping -c 4 ' . $target );
    22. }
    23. // Feedback for the end user
    24. $html .= "
      {$cmd}
      "
      ;
    25. }
    26. ?>

    level-high

    相比于medium,黑名单内容增加

    1. high.php
    2. if( isset( $_POST[ 'Submit' ] ) ) {
    3. // Get input
    4. $target = trim($_REQUEST[ 'ip' ]);
    5. // Set blacklist
    6. $substitutions = array(
    7. '&' => '',
    8. ';' => '',
    9. '| ' => '', //注意此处过滤有空格,过滤的是|空格
    10. '-' => '',
    11. '$' => '',
    12. '(' => '',
    13. ')' => '',
    14. '`' => '',
    15. '||' => '',
    16. );
    17. //设置黑名单 & ; | - $ ( ) ` ||
    18. // Remove any of the charactars in the array (blacklist).
    19. $target = str_replace( array_keys( $substitutions ), $substitutions, $target );
    20. // Determine OS and execute the ping command.
    21. if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    22. // Windows
    23. $cmd = shell_exec( 'ping ' . $target );
    24. }
    25. else {
    26. // *nix
    27. $cmd = shell_exec( 'ping -c 4 ' . $target );
    28. }
    29. // Feedback for the end user
    30. $html .= "
      {$cmd}
      "
      ;
    31. }
    32. ?>

    level-impossible

    既然是impossibale,那以咱水平肯定绕不过去,直接看代码。这里先把 $target 输出,看看代码是如何防止命令注入的。

    1. impossiable.php
    2. if( isset( $_POST[ 'Submit' ] ) ) {
    3. // Check Anti-CSRF token
    4. checkToken( $_REQUEST[ 'user_token' ], $_SESSION[ 'session_token' ], 'index.php' );
    5. //检测token
    6. // Get input
    7. $target = $_REQUEST[ 'ip' ];
    8. $target = stripslashes( $target );
    9. //接收数据,使用stripslashes防注入
    10. // Split the IP into 4 octects
    11. $octet = explode( ".", $target );
    12. var_dump($octet); // --调试--
    13. exit();
    14. // explode() 函数使用一个字符串分割另一个字符串,并返回由字符串组成的数组。
    15. // Check IF each octet is an integer
    16. if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) {
    17. // If all 4 octets are int's put the IP back together.
    18. // 先拆为数组,分别为0、1、2、3、4,is_numeric检测是否为数字,也就是说在这里数组0、1、2、3、4都必须为数字
    19. $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3];
    20. // Determine OS and execute the ping command.
    21. if( stristr( php_uname( 's' ), 'Windows NT' ) ) {
    22. // Windows
    23. $cmd = shell_exec( 'ping ' . $target );
    24. }
    25. else {
    26. // *nix
    27. $cmd = shell_exec( 'ping -c 4 ' . $target );
    28. }
    29. // Feedback for the end user
    30. $html .= "
      {$cmd}
      "
      ;
    31. }
    32. else {
    33. // Ops. Let the user name theres a mistake
    34. $html .= '
      ERROR: You have entered an invalid IP.
      '
      ;
    35. }
    36. }
    37. // Generate Anti-CSRF token
    38. generateSessionToken();
    39. ?>

    调试也可以看出上面代码的数组分组

    这里虽然没用禁用所谓的危险函数shell_exec,但对于用户的输入内容过滤严格从而避免命令注入漏洞。

    0x03  总结

    沙雕考试暂且结束,暂获一周躺平权。

  • 相关阅读:
    Ubuntu18.04添加内核模块(字符设备)
    Linux基础
    【云原生&微服务九】SpringCloud之Feign实现声明式客户端负载均衡详细案例
    复杂查询方法-视图、子查询、函数等
    HTML5+CSS3+移动web 前端开发入门笔记(二)HTML标签详解
    LeetCode(力扣)860. 柠檬水找零Python
    算法:堆排序
    挠场的科学丨一、特斯拉的特异功能与电力产业的兴起
    半监督学习介绍(为什么半监督学习是机器学习的未来)
    【机器学习】无监督学习中的基于内容过滤算法
  • 原文地址:https://blog.csdn.net/m0_60988110/article/details/127838119