pikachu靶场总结(二)

三、CSRF 跨站请求

原理:由于站点没有对用户修改敏感信息时提交内容的这个过程进行防护,导致攻击者可以轻易的去伪造用户的一个请求,然后“借用”用户的权限完成一次非法的数据请求,进而对用户造成危害!

利用:比如小红正在浏览某购物网站,这个时候小红是处于登陆状态的,然后小黑给小红发送了一段链接,这个链接是小黑通过抓包或者其他手段伪造的一个请求数据的链接,如果这个时候小红一旦点击了这个链接,那么就会以小红的身份去发送请求,进而修改小红的数据等,此时攻击就发生了。所以相对来说这个漏洞的利用条件还是比较苛刻的,一般这个漏洞的级别也不是很高!

区分:这个漏洞容易和XSS弄混淆,我们还是以上面那个例子来说的话,如果是XSS漏洞的话,那小黑就可以直接拿到小红的cookie登录小红的账号进行操作了,所以总结来说,XSS是直接“获取”权限,而CSRF是“借用”权限!所以这两个漏洞谁的含金量高也就不言而喻了!

1.get型

get型的一般比较相对好伪造一些,因为攻击者可以去有漏洞的网站上自己注册一个账号,然后通过抓包就可以知道请求是长什么样子的!进而进行伪造!

举个栗子:比如我们如果抓到一个站点修改信息的包如下:http://192.168.6.141/pikachu/vul/csrf/csrfget/csrf_get_edit.php?sex=111&phonenum=122&add=武汉&email=111&submit=submit HTTP/1.1
那我们就可以修改里面的参数然后发送给受害人,如果此时受害人正好以登录的情况浏览这个站点,那么他的信息就会被篡改!

2.post型

这个利用起来会稍微有点麻烦,我们需要构造一个钓鱼网站,里面把我们需要提交的post请求以表单的方式构造好,然后诱使受害者进行点击,然后从我们的站点将post请求发给目标站点,然后以此来达成我们的攻击目的!

3.token

token是一个随机生成的一长串数值,在后台生成然后发送到前端,在前端提交post请求时一并发送到后端进行验证,如果token不一致的话请求就不会生效,这样就防止了别人通过伪造请求对我们的站点进行csrf攻击!

4.防csrf的方法:

1.增加token就是一个很好的方法!

2.会话管理:
    设置会话过期机制比如会话过期时间要尽可能设置的短一些
    不会将一些敏感信息保存在客户端

3.访问控制安全管理:
    修改信息时进行二次身份验证,比如输入原密码等
    提交敏感信息时使用post方法不用get方法
    通过http头部的referer来限制原页面

5.referer:
也算是一个验证机制,可以验证我们的请求是从哪里过来的,如果不是我们要求的地方是不可以访问我的,这样其实可以有效地去防止钓鱼,比如上面我们说的post那种情况!我们用我们自己搭建的站点向目标站点提交表单信息如果referer不对就会被拦截!

四、sql注入漏洞

1.原理:

主要是开发人员在构建代码的时候没有对输入边界进行安全考虑,导致攻击者可以通过合法的输入点提交一些精心构造的语句,从而欺骗后台数据库对其进行执行,导致数据库信息泄露!

2.攻击流程

1.1注入点探测
    
    自动方式:使用web漏洞扫描工具,自动进行注入点发现
    手动方式:手工注入sqli测试语句进行注入点发现
1.2信息获取

    环境信息:比如数据库的类型,数据库的版本,操作系统的类型和版本等信息
    数据库信息:比如数据库名称,表名,字段名等

1.3获取权限

    一旦数据库的权限足够高或者满足一定条件的时候攻击者可以通过执行shell脚本,上传木马的等方式进行权    限控制从而导致我们的操作系统彻底沦陷!

3.数字型注入

select 字段1,字段2 from 表名 where id=1 如果后台是这样查询数据的话

那么我们输入 select 字段1,字段2 from 表名 where id=1 or 1=1 这个payload,就会把数据库中全部的数据查出来,那么我们就基本可以判定这里存在字符型sql注入漏洞!

4.字符型注入

其实和数字型差不多,只是他查询的变量是以字符串的形式拼接到sql语句中去的,就像这样:

select 字段1,字段2 from 表名 where id=‘hahaha’

那么我们其实就要像xss那样通过闭合的方式进行注入!比如上面这个我们可以这样构造payload:

select 字段1,字段2 from 表名 where id=‘       haha’or 1=1#        ’     

引号中间的就是我们的payload了,后面的#是为了注释掉后面多余的那个单引号!这种的我们就叫做字符型注入!

5.搜索型注入

其实还是类似,我们首先要知道他最原始的语句是怎么样的:

select 字段1,字段2 from 表名 where id like‘#参数#’,然后他会在数据库中对参数进行模糊查询!

那我们想一下,如果要在这种情况下进行注入应该怎么做呢?其实结合前面的数字型和字符型开看的话,我们只需要想办法构造闭合然后再拼接上我们的查询语句就可以了!

构造payload:‘#        1#’or 1=1 #        #’

6.xx型注入

这里其实就是想告诉我们,不论是以上哪种注入其实本质上都是将其进行闭合,然后在后面拼接语句测试是否会发生注入,至于如何进行闭合就需要我们不断进行尝试了!如果是白盒的话那我们在知道代码的情况会更容易些!          

查找字段个数  order by 数字

查找显示位 union select 1,2,3.....(字段个数是多少个就写到几)

爆库名 database()

爆表名 union select 1, group_concat(table_name) from information_schema.tables where table_schema='database()'

爆列名 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='表名'

爆信息 union select 1,2,group_concat(concat_ws('-',参数1,参数2)) from '表名'

7.基于函数报错的sql注入

条件:开发者没有屏蔽数据库的报错信息,或者说没有做一个标准化处理,这个时候发生语法错误进行报错以后会直接把信息返回给前端,这个时候攻击者就可以通过精心构造的payload进行注入攻击! 主要有三个函数 :1.updatexml()函数 2.extractvalue()函数 3.floor()函数

7.1.updatexml()报错

mysql中对xml文档进行修改和查询的函数;语法:UPDATEXML(xml_document,XPathstring,new_value())
第一个参数试文件名,string类型;第二个参数是文件路径(正常情况下,这个参数必须是正确的!);第三个参数是要替换的值,也就是用第三个参数替换掉第二个参数所在位置的第一个参数所对应的值!

利用:当我们输入一些特殊符号时发现给我们返回了报错信息,那么这种情况就很有可能存在报错注入,updatexml函数的关键点在于第二个参数是拼接表达式的,并且可以执行我们传入的表达式,当执行后发现不是一个正确的路径时会返回一个报错,报错信息中会包含表达式执行的结果!

payload:

1'and updatexml(1,concat(0x7e,version()),0)#        

concat(0x7e,version())是为了拼接后返回,保证将我们要得到的信息完整的回显出来!所以 version()这里就可以随便替换我们想要执行的表达式了!

payload:

获取表名:

1'and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#

limit(0,1)是限制从第零行开始输出一行,由于报错只显示一行,故做这样的处理!下面的也是一样的道理!

获取列名:

1'and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='users' limit 0,1)),0)#

获取数据:

1'and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#

1'and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#

7.2.insert()/update()报错

这两个一般出现在新建什么东西啊之类的这种会用到insert()函数,然后比如像修改啊这一类的可能一般会用到update()这个函数,这个时候我们就不用select()了,改用这两种:

原语句:

insert into 表名 (参数1,参数2)values('值1','值2') 一般通过or来进行闭合!

payload:  1' or updatexml(1,concat(0x7e,version()),0) or '   替换掉值1,也是相当于是想办法闭合!version()和可以换成上面的即可获取更多数据库信息!

update()的原理和payload都和上述一样!

7.3.delete()注入

原理还是一样的,当我们往数据库中插入一条恶意的sql语句后,执行删除操作时,后台会调用delete()函数,如果在删除数据时没有对传入的参数进行一定的防护,那么我们插入在那条恶意语句就会在删除数据时被带入到sql语句中执行,从而造成攻击!payload构造方法和上面也还是一样!这里举个例子就好!

7.4.floor()函数

kobe'and (select 2 from (select count(*),concat(versionn(),floor(rand(0)*2))x from information_schema.tables group by x)a)#

7.5.extractvalue()函数

......

8.http header 注入

他并不是一种新的注入形式,而是一种新的注入场景,有些时候后台开发人员为了验证客户端头信息,比如cookie或者通过http header头信息获取客户端的一些信息,比如useragent,accept字段等等。

这个时候会对客户端的http头信息进行获取并进行sql处理,如果这一过程中没有足够的安全考虑那就可能会形成漏洞!

payload的构造方法跟上面一样需要根据情况采取闭合或者通过报错的方式进行利用!

9.盲注

9.1基于真假的盲注

原理:前面我们的两种注入其实都有大前提,比如最开始我们说的那些,都是在前端会回显数据库信息的大前提下;后面的报错注入是在会回显数据库报错信息的大前提下,但是如果不满足这些前提的情况,就不存在sql注入了吗?或者说我们该如何进行注入呢?

基于真假的意思就是他不会显示出具体的报错信息,只是错误和正确会有不同的显示,可以理解为只有两种固定的显示,一种是输入正确会给一种显示,一种是输入错误的一种显示,那么在这种情况下相当于我们只知道一个信息,就是我们输入的是正确的还是错误的。其实这样也是可以通过注入获取信息的,只是比较麻烦一些而已!

我们可以通过substr(),以及ASCII()函数对字符串进行拆分并转换成阿斯克码值,然后通过比较大小的方式对字符进行挨个拆解,这样我们就能够一个一个的试出来了相当于,当然这种情况通过手工注入是不现实的,我们需要借助自动化测试工具来进行!

总而言之就是将一切信息转换为对与错也就是0和1,毕竟有人说过:世界就是0和1组成的嘛,在这里得到了完美的诠释!

这里其实没有什么payload一说,就是我们根据正确和错误两种提示,然后测试一些语句看到底有没有把我们的sql语句拼接进去,如果本身提示的正确与错误信息相同,又能够进行注入,那么我就可以判定为这是一个基于真假的sql注入漏洞!

9.2基于时间的盲注

前面我们说了如果他连真假的提示都没有,或者说我们没有办法根据提示进行真假的判断,甚至他连提示都没有,那么我们就可以尝试是不是可以进行基于时间的注入了!

payload:关键就是sleep()这个函数,我们构造闭合拼接进去之后如果页面“休息”了,那我们就可以认为很有可能存在着基于时间的注入漏洞!

盲注常用函数:

if()
功能:条件判断。
语法格式:if(expr1,expr2,expr3):expr1为true则返回expr2,expr1为false则返回expr3。
注:仅MySQL支持if(expr1,expr2,expr3)。

left()
功能:截取具有指定长度的字符串的左边部分。
语法格式:left(strlength),如果str或length参数为NULL,则返回NULL值。
参数说明
str:要提取子串的字符串。
length:正整数,指定将从左边返回的字符数。length为0或为负,则LEFT返回一个空字符串
length大于str字符串的长度,则leftO返回整个str字符串。

length()
功能:返回字符串的长度,以字节为单位。
语法格式:length(str)

substr()、substring()
功能:从指定的位置开始,截取字符串指定长度的子串。
语法格式:substr(str,pos)或substr(str,pos,len),substring(str,pos)substring(str,pos,len)
参数说明
str:要提取子串的字符串。
pos:提取子串的开始位置
len:指定要提取的子串的长度

ascii()、ord()
功能:返回字符串最左边字符的ASCII码值
语法格式:ascii(str),ord(str)

cast()、convert()
功能:获取一个类型的值,并产生另一个类型的值。
>语法格式:cast(value as type),convert(value,type)

可转换的值类型
二进制,同带binary前缀的效果:BINARY
字符型,可带参数:CHARO
日期:DATE
时间:TIME
日期时间型:DATETIME
浮点数:DECIMAL
整数:SIGNED
无符号整数:UNSIGNED

延时函数sleep()
功能:让语句延退执行一段时间,执行成功后返回0。
语法格式:sleep(N),即延退执行N秒。

延时函数benchmark()
功能:让某语句执行一定的次数,执行成功后返回0。
语法格式:benchmark(coun,texpr),即让expr执行count次
注:仅MySQL支持该函数。

10.通过sql注入进行远控

当我们知道对方web站点下的文件目录路径时,我们可以通过sql注入写入文件,上传一句话木马,然后通过蚁剑,菜刀等工具进行远程连接对方的服务器,从而达到控制对方主机的一个操作!

一句话木马:不同的语言有不同的写法,可以到网上搜索,好好了解一下!

11.暴力破解

如果我们没有information_schema这个表的权限,或者说对方使用的不是mysql而是其他数据库,他并没有提供给我们查询的接口,那么这种情况下我们话可以实现注入吗?其实这个也是可以的,就像我们之前基于时间或者对错一样,只是比较麻烦一些,我们可以通过暴力破解的工具,直接将我们需要的信息爆破出来也可以达到获取数据的目的,只是比较麻烦而已!

12.sql注入防护措施

代码层面:

对前端的输入进行转义或者过滤,我们可以通过比如mysql中的转义函数对输入的一些特殊符号进行转义,或者直接通过黑名单的处理对特殊字符进行过滤,但是这样的做法通常是不稳妥的,因为有可能随着数据库特性的升级导致转移或者过滤最终还是有可能出现疏忽!

进行预处理+参数化,比如PHP的PDO就是在向数据库传递参数查询时,不直接将我们输入的内容拼接进去,而是先将sql语句进行编译和解析,这样我们无论怎么“精心构造”,输入的东西最终都会被作为一个整体传给数据库,这样就不会像我们前面那样将输入的内容直接拼接到sql语句中去了,更不存在闭合这一说了,因为无论怎么样输入的都是一个整体嘛!这样的防护是比较稳妥可靠的!也是我们比较推荐的做法!

网络层面防护:

比如我们在web服务前面加一层防火墙,WAF(web application firewall),它里面面有一个大的特征库,可以识别攻击者发送的一些恶意代码,也就是我们前面用的那些payload,然后拦截和过滤掉从而保护我们的web应用!但是他也不是绝对安全的,我们不能仅仅依靠防火墙,也应该从开发者角度让我们的应用做到完美,即使攻击者能够绕过防火墙也无法对我们进行攻击!

也就是在部署WAF的同时,推进我们的代码安全工作,这样才能更好的进行防护!

云端的服务器也有云WAF!

13.宽字节注入

What is 宽字节?

  字符大小为一个字节时为窄字节

  字符大小为两个及以上的字节为宽字节

  英文26个字符所以1个字节就够用了,而汉字字符数太多,一个字节显然不够用,汉字是三个字节!

原理:前面我们说过,防止sql注入的一种方法是对特殊字符进行转义,通常情况下是用 \ 来进行转义,结合我们前面的学习,以前我们都是想办法构造闭合,然后让我们输入的语句跳出闭合符号,从而被后台的数据库执行!那么现在当在我们面前的不只是闭合了,还有转义符,那我们就要想办法绕过转义符,这个过程就是我们所说的宽字节注入!

使用GB系列的编码并且通过对我们传入的参数采取转义的形式进行过滤的话,有可能会会产生宽字节注入漏洞!

因为一般情况下会在我们输入的特殊字符前面加\,我们在前面加一个%df的话就成了%df+\的GB编码了,这样一来就变成了三个字节的汉字了!然后我们就可以绕过这个转义机制了!

payload还和我们之前的一样,只是在前面需要加一个%df即可!


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值