一、配置管理与潜在威胁
| 测试编号 | 测试项 | 本次是否测试 | 测试定性 |
| Web_01 | 明文信息传输漏洞 | √是□否 | 中危 |
| Web_02 | 敏感信息泄露 | √是□否 | 中危 |
| Web_03 | 默认或可猜解用户账户 | √是□否 | 中危 |
| Web_04 | 会话重放攻击测试 | √是□否 | 低危 |
| Web_05 | 验证码缺陷 | √是□否 | 中危 |
| Web_06 | http方法测试 | √是□否 | 低危 |
-
- 明文传输漏洞 高危
漏洞描述:
数据传输过程中的账号、密码、身份证等敏感信息明文传输。
产生原因:
<1>密码等敏感信息没有经过加密,明文传输。

漏洞危害:明文传输的危害在于所有经过网关的流量都可以被黑客通过嗅探(ARP欺骗)的方式抓取到。
防护建议:
<1>启用SSL机制
<2>对系统内所以涉及到密码等敏感数据传输地方做加密处理,从而在一定的程度上避免这些敏感的数据受到威胁。确保所有登录请求都以加密方式发送到服务器。确保敏感信息,例如:姓名、身份证号码、社会保险号码、信用卡号码、驾照号码、电子邮件地址、电话号码、邮政编码等信息一律以加密方式传给服务器。
<3>确保使用了合适、强大的标准算法和强大的密钥,不要使用md5、base64编码、url编码等易被破解的加密方式,可以添加一个随机salt值做加密处理。并且密钥的管理要到位。
1.2明文存储漏洞 中危
漏洞描述:
查看系统是否存在鉴别数据、重要业务数据未加密存储,如页面源码、配置文件、缓存、前端cookie、localstorage、服务器、数据库、日志中是否存在敏感信息明文存储。
产生原因:
密码等敏感信息没有经过加密,明文存储。
漏洞危害:攻击者能够轻易获取到存储的敏感信息,通过这些有效信息进行进一步的攻击。
防护建议:
敏感信息脱敏处理后再进行存储,建议使用AES算法。
1.3弱口令或空口令 中危
漏洞描述:
查看系统是否采用了简单数字组合、常规等简单易猜解或空账户口令,如应用系统、中间件、数据库登录口令、服务器远程管理账户口令、guest账户、Axis2弱口令。
测试方法:
对常见的端口、服务、管理后台等进行弱口令测试。
漏洞危害:
弱口令非常容易被攻击者猜解或通过弱口令扫描工具扫描到,导致攻击者通过弱口令可轻松登录系统中,从而进行下一步的攻击,如上传webshell,获取敏感数据,另外攻击者利用弱口令登录网站管理后台,可任意增删改等操作,从而造成负面影响。
防护建议:
设置合理的密码复杂度。
1.4不安全的加密算法 高危
漏洞描述:
测试系统是否采用了弱加密算法,如md5、base64、DES、escape、urlencode。
产生原因:
密码等敏感信息使用弱加密算法进行数据传输。
漏洞危害:敏感信息的数据加密采用比较简单的算法或编码,一旦被人获取足够的“样本”,将有可能被反向推测出解密算法,从而泄露重要数据。
防护建议:
<1>涉及密码等相关操作的业务场景,如登录、修改密码、用户注册等采用散列加盐或RSA非对称加密方式进行加密
·散列加盐(要求密码注册和下发过程做同样的散列加盐处理,数据库中存储的即为散列后的值,无法逆向破解)
用户注册
1、用户注册时,注册页面输入账号和密码,以及其他信息
2、前端将salt值与用户密码连接在一起(salt值为与服务端共同约定的一个固定也唯一的值uid,可选择用户手机号或用户名,保证每个用户的salt值唯一且不同)
3、对连接后的值进行散列(md5或SHA1),得到hash1值
4、服务端接收到注册请求后发送注册成功响应,并将hash1值存放到数据库中
用户登录
1、用户登录时,在登录页面输入用户名和密码
2、系统通过用户名找到与之对应的约定好的salt值,即uid
3、将salt值与用户输入的密码连接在一起,对连接好的值进行散列,得到hash2
4、比较hash1和hash2是否相等,相等则表示密码正确,否则表示密码错误
修改密码
1、修改密码时,在修改密码页面输入旧密码和确认密码
2、系统找到与之对应的约定好的salt值,即uid
3、将旧密码和确认密码分别拼接salt值,对连接好的值进行散列,得到hash3和hash4
4、比较hash3和hash4是否相等,相等则更新password字段,将hash4取代hash1存入数据库,并返回密码修改成功响应
图示

·非对称加密
用户注册
1、用户通过浏览器点击进入注册用户页面
2、web服务器生成RSA公钥和私钥(一个会话周期内有效,会话更新重新生成),并把公钥publickey发送到浏览器
3、在注册页面输入用户名和密码,用步骤2返回请求中的公钥publickey对口令进行加密encryptpass=RSA.encrypt(pass,publickey),将username+encryptpass POST给服务端
4、服务端接收到步骤3的请求后,用私钥privatekey对口令进行解密,还原成明文pass=RSA.decrypt(encryptpass,privatekey)。
5、依据项目需求,对敏感数据password作脱敏处理,调用统一的加密算法(用户口令建议使用hash算法)存入数据库,并将注册结果返回给客户端
用户登录
1、用户通过浏览器点击进入登录页面
2、web服务端生成RSA公钥和私钥(一个会话周期内有效,会话更新后重新生成),把公钥publickey发送给浏览器
3、在登录页面输入用户名和密码,用步骤二返回请求中的公钥publickey对密码进行加密encryptpass=RSA.encrypt(pass,publickey),并将username+encryptpass POST给服务端
4、web服务器接收到步骤3的请求后,用私钥privatekey对口令进行解密,还原成明文pass=RSA.decrypt(encryptpass,privatekey)
5、服务端对明文口令做业务规定的加密算法(与数据存储加密算法一致),并与数据库中存入的口令密文作对比,若一致则登录成功,不一致则登录失败。并将登录结果返回给客户端
修改密码
1、用户通过浏览器点击进入修改密码页面
2、web服务端生成RSA公钥和私钥(一个会话周期内有效,会话更新后重新生成),把公钥publickey发送给浏览器
3、在修改密码页面输入旧密码和新密码,用步骤二返回请求中的公钥publickey对旧密码和新密码分别进行加密,encryptoldpass=RSA.encrypt(oldpass,publickey)、encryptnewpass=RSA.encrypt(newpass,publickey),并将加密后的encryptoldpass\encryptnewpass POST给服务端
4、服务端接收步骤3的请求后,用私钥privatekey对旧密码和新密码进行解密,还原成明文oldpass=RSA.decrypt(encryptoldpass,privatekey)和newpass=RSA.decrypt(encryptnewpass,privatekey)
5、服务端对明文口令分别做业务规定的加密算法(与数据库存储加密算法一致),将加密后的old password与数据库中存储的口令密文作对比,若一致则将数据库中passord字段更新,将加密后的new password替换原来的,并返回密码修改成功响应

<2>表单提交,对敏感信息做加密处理解决项目上因特殊原因不能使用ssl,但表单中需要提交身份证号、家庭住址等敏感信息,采用混合加密(对称加密+非对称加密)采用混合的方式是因为非对称加密会影响性能,对于大数据量加密时应用对称加密,速度快,效率优,同时为了防止对称加密的密钥容易泄露的问题,又使用了一层非对称加密来保护密钥
1、客户端生成一次有效密钥key,用于对称加密(防止本地js泄露导致key值泄露,一次有效保证了即使获取本地js,但不能破解其他客户端或其他请求的加密数据,因为key变了)
2、服务端生成有效密钥对(公私钥,一个会话周期内有效,若重新登录或会话更新,则密钥对随之更新),并将publickey返回给客户端
3、客户端使用AES对称加密算法以及密钥key对敏感字段加密,encryptdata=AES.encrypt(data,key)
4、客户端使用RSA非对称加密算法以及公钥publickey对密钥key加密,encryptkey=RSA.encrypt(key,publickey)
5、将加密后的data和key通过post请求方式发送到服务端,encryptdata+encryptkey
6、服务端接收到客户端发送的表单请求后,使用RSA以及自己保存的私钥privatekey对encryptkey进行解密,得到key=RSA.decrypt(encryptkey,privatekey)
7、服务端用步骤6得到的key,使用AES算法对encryptdata进行解密得到原始敏感数据,data=AES.decrypt(encryptdata,key)
8、依据项目需求,对敏感数据data作脱敏处理,调用统一的加解密算法存入数据库
<3>服务端返回含敏感信息字段的请求给客户端,与上述表单提交业务场景一致,上面为存,这个是取
1、服务端接收到客户端请求后,将请求的敏感数据从数据库取出
2、服务端对数据库中的数据作解密得到原始数据data(数据存入数据库时根据业务需求调用了统一的加解密算法)
3、服务端使用AES算法对data进行对称加密并发送到客户端,key值与客户端约定为一个固定且唯一的值uid(保证了每个用户的key值均不同,只有自己能解密自己的响应请求数据)encryptdata=AES.encrypt(data,key=uid)
4、客户端接收到服务端的响应后,使用约定好的key=uid进行解密,获取原始数据回显在客户端,data=AES.decrypt(encryptdata,key)
1.4安全配置不当 中危
组件或中间件配置不当引起的安全漏洞。
<1>tomcat配置不当
<2>http方法配置不当
<3>跨域安全配置不当
<4>安全相关响应头配置不当
1.4.1 tomcat安全配置漏洞
漏洞描述: 在前端或通过其他方式可获得系统中间件版本、服务器信息等,造成敏感信息泄露。
漏洞危害:攻击者可以利用收集的敏感信息有针对性的指定计划对系统进行攻击。
防护建议:
<1>tomcat版本泄露,错误信息泄露了包名、开发框架等

<2>tomcat管理目录泄露

<3>tomcat样例目录泄露

修复
<1>tomcat版本控制
检查目前使用的Tomcat版本是否存在安全漏洞,如果存在安全漏洞,则需升级到新的安全版本。如果要从低版本升级到高版本,应先在测试环境中测试通过后再进行升级,以避免由于兼容性带来的问题。
<2>tomcat版本号隐藏
1、进入tomcat的lib目录找到catalina.jar文件
2、用压缩软件打开catalina.jar,进入org/apache/catalina/util目录下
3、编辑配置文件serverinfo.properties,修改server.info、server.number参数值,隐藏tomcat版本信息
<3>无关目录删除和隐藏
进入tomcat的webapps根目录下,删除docs、examples、host-manager、manager目录及其下的所有文件,ROOT目录下只保留自定义的error.html页面即可。以避免造成不必要的信息泄露或其他漏洞。
<4>封装程序异常报错信息
1、对于tomcat的中间件敏感信息泄露的问题,常用修复方式为修改tomcat根目录下conf文件夹下的web.xml文件,配置一个统一的静态页面,将400、403、404、500等常见报错重定向到该静态页面,而不是抛出异常(报错信息导致代码信息泄漏)
<!-- 400错误 -->
<error-page>
<error-code>400</error-code>
<location>/error.html</location>
</error-page>
<!-- 404 页面不存在错误 -->
<error-page>
<error-code>404</error-code>
<location>/error.html</location>
</error-page>
<!-- 500 服务器内部错误 -->
<error-page>
<error-code>500</error-code>
<location>/error.html</location>
</error-page>
<!-- java.lang.Exception异常错误,此标记可定义多个类似错误提示 -->
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.html</location>
</error-page>
<!-- java.lang.NullPointerException异常错误,此标记可定义多个类似错误提示 -->
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error.html</location>
</error-page>
2、编写error.html页面,并放入ROOT目录下
<5>加入异常捕获过程中预定义的错误编码
对于常用的jsp语言开发的网站,可在业务流程中加入异常捕获过程中预定义的错误编码,将异常输出到错误日志中,并在前台页面返回相应的错误编码,以便应用系统运维人员进行异常排查。
try {
//某业务处理流程
……
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
resultMessage = getText("业务处理发生异常,错误编码A-04221!");
return "errorJsp";
}
<6>修改服务器默认端口设置和指令
server.xml默认有下面一行:
<Server port="8005" shutdown="SHUTDOWN">
这样允许任何人只要telnet到服务器的8005端口,输入"SHUTDOWN",然后回车,服务器立即就被关掉了。从安全的角度上考虑,我们需要把这个shutdown指令改成一个别人不容易猜测的字符串,可以同时把端口也改了。
<Server port="6695" shutdown="molly1122hello">
<7>关闭war自动部署
默认 Tomcat 是开启了对war包的热部署的。为了防止被植入木马等恶意程序,因此我们要关闭自动部署。
<Host name="localhost" appBase="" unpackWARs="false" autoDeploy="false">
<8>解决“slow http denial of service attack”漏洞
slow http denial of service attack漏洞是利用http post的时候,指定一个非常大的content-length,然后以很低的速度发包,比如10-100s发一个字节,让这种连接不断开,这样当客户端连接多了后,占用了webserver的所有可用连接,从而导制DOS,属于一种打拒绝服务攻击。
解决方法:
打开server.xml找到
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
将其中的connectionTimeout="20000"改为1000,其单位为ms。
1.4.2 http方法安全配置漏洞
漏洞描述:Web服务器默认情况下开放了一些不必要的HTTP方法(如DELETE、PUT、TRACE、MOVE、COPY),增加了受攻击的几率。
漏洞危害:Web服务器启用了不安全的HTTP方法,很可能会在 Web服务器上上传、修改或者删除 Web页面、脚本和文件,可能允许未授权的用户对其进行利用。
测试方法:
<1>打开fiddler-composer,构造option方法,并执行Execute

<2>使用fiddler抓包,查看构造请求得到的响应


防护建议:禁用不必要的HTTP方法
1、对于修改应用程序的Web.xml文件的协议,具体如下所示:
<?xml version="1.0" encoding=“UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
2、在应用程序的Web.xml中添加如下代码即可:
<security-constraint>
<web-resource-collection>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
<http-method>DELETE</http-method>
<http-method>HEAD</http-method>
<http-method>OPTIONS</http-method>
<http-method>TRACE</http-method>
</web-resource-collection>
<auth-constraint>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
</login-config>
1.4.3 CORS跨域安全配置漏洞
漏洞描述:前后端分离的项目,为了保证正常访问,需设置跨域,由于配置不当:<1>CORS服务端的 Access-Control-Allow-Origin 设置为了 *,并且 Access-Control-Allow-Credentials 设置为false
<2>有一些网站的Access-Control-Allow-Origin他的设置并不是固定的,而是根据用户跨域请求数据的Origin来定的。这时,不管Access-Control-Allow-Credentials 设置为了 true 还是 false。任何网站都可以发起请求,并读取对这些请求的响应。
上述两种情况任何一个网站都可以发送跨域请求来获得CORS服务端上的数据,从而造成跨域漏洞。
漏洞危害:所有的网站都可以对其进行跨站资源请求。
测试方法:
打开fiddler,抓取数据包并设置截断,修改origin为任意源地址,如图,修改Origin参数值为baidu.com,网站返回成功。
原因:Access-Control-Allow-Origin设置为*,或设置并不是固定的,而是根据用户跨域请求数据的Origin来定的。
这时,不管Access-Control-Allow-Credentials 设置为了 true 还是 false。任何网站都可以发起请求,并读取对这些请求的响应。CORS的配置不正确。

防护建议:
<1>配置白名单,仅允许指定的源(http://example.com)来跨域请求服务器端的资源,并且服务器会响应。
Access-Control-Allow-Origin: Example Domain
<2>@CrossOrigin 注解解决跨域问题,在需要允许跨域访问的接口或者类加上该注解就可以,如果用@RequestMapping,则要指定get,或post等才有起效。
@CrossOrigin(origins="http://localhost:4000")
1.4.4 安全相关响应头配置漏洞
<1>Content-Security-Policy(CSP)CSP 通过指定允许加载哪些资源的形式,来防止跨站脚本注入。
Content-Security-Policy: default-src 'self';
img-src 'self' https://i.imgur.com;
object-src 'none';
script-src 'self';
style-src 'self';
frame-ancestors 'self';
base-uri 'self';
form-action 'self';
<2>Strict-Transport-Security(HSTS)该响应报头告诉浏览器,只能通过 HTTPS 访问网站——如果网站启用过 HTTPS,它将会一直生效。如果使用子域名,还建议在任何使用过的子域名对此加以强制。
Strict-Transport-Security: max-age=3600; includeSubDomains
<3>X-Content-Type-Options该响应报头确保浏览器遵守应用程序设置的 MIME 类型。这有助于防止某些类型的跨站脚本注入攻击。
X-Content-Type-Options: nosniff
<4>Cache-Control(缓存控制)任何具有敏感数据的页面,如用户页面或客户结算页面,都应该设置成无缓存。防止共享计算机上的某个人按回退按钮或浏览历史记录又能查看到个人信息。
# 默认情况不使用缓存
Header set Cache-Control no-cache
对于像静态资产(图像、CSS 文件和 JS 文件)等很少变更的页面,很适合使用缓存。既可以通过逐页设置的方式来实现,也可以通过在服务端配置使用正则表达式的方式来实现
# 静态资产设置成缓存 1 天
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
Header set Cache-Control "max-age=86400, public"
</filesMatch>
<5>Expires(过期时间)该响应报头能设置当前请求缓存的过期时间。如果设置了 Cache-Control 的 max-age 响应报头,它将会被忽略,因此,在不考虑使用 Cache-Control 而进行本地缓存测试时,才设置它。Expires: 0
<6>X-Frame-Options该响应报头用来表明站点是否允许在 iFrame 中展示
网站可以通过设置X-Frame-Options阻止站点内的页面被其他页面嵌入从而防止点击劫持。
测试方法:
HTTP响应头信息中的X-Frame-Options,可以指示浏览器是否应该加载一个iframe中的页面。如果服务器响应头信息中没有X-Frame-Options,则该网站存在ClickJacking攻击风险。
将如下的代码中iframe中的链接换成待测网站的,保存为.html文件,本地打开。如果打开的页面中显示了待测网站,则说明没有设置,反之设置了。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8" >
<title>点击劫持测试</title>
</head>
<body>
<iframe src="http://www.xxx.com/" width="500" height="500" frameborder="10"> </iframe>
</body>
</html>
防护建议:
网站可以通过设置X-Frame-Options阻止站点内的页面被其他页面嵌入从而防止点击劫持。
修改web服务器配置,添加X-Frame-Options响应头。赋值有如下三种:
- DENY:不能被嵌入到任何iframe或者frame中
- SAMEORIGIN:页面只能被本站页面嵌入到iframe或者frame中。
- ALLOW-FROM uri:只能被嵌入到指定域名的框架中。
在服务端设置的方式如下:
Java代码:
response.addHeader("x-frame-options","SAMEORIGIN");
Nginx配置:
add_header X-Frame-Options SAMEORIGIN
Apache配置:
Header always append X-Frame-Options SAMEORIGIN
加之前
加之后

<7>Access-Control-Allow-Origin通过该响应报头可以告诉浏览器,允许哪些其他站点的前端 JavaScript 代码对页面发出请求
Access-Control-Allow-Origin: https://example.com
<8>Set-Cookie确保 cookie 仅能通过 HTTPS(加密)传送,并且不能通过 JavaScript 访问
Set-Cookie: <cookie-name>=<cookie-value>;
Domain=<domain-value>; Secure; HttpOnly
<9>X-XSS-Protection该响应报头用来指示浏览器停止执行跨站脚本攻击检测
X-XSS-Protection: 1; mode=block
1.5敏感信息泄露 中危
漏洞描述: 在前端或通过其他方式可获得系统中间件版本、服务器信息等,造成敏感信息泄露。
产生原因:
1、敏感信息传输,在业务流程中,许多敏感信息需要从客户端提交到服务端,或者从服务端传回到客户端,如果没有采取合理的加密措施,在传输过程中可能被第三方截获,从而产生敏感信息泄露
<1>session信息在URL中被直接明文传输

<2>帮助控件返回json格式的user表所有字段,包括用户名,身份证号,手机等。

2、敏感信息显示,通常情况下应用敏感信息在客户端显示时需要进行脱敏,密码等部分用户信息是不应该在客户端显示的,如果程序设计时在这部分没有进行很好的处理,就会产生敏感信息泄露漏洞。
系统帮助页面暴露服务器和数据库版本信息等

3、客户端代码及注释有可能泄露系统敏感信息,对一些核心代码进行技术注释也有可能会帮助攻击者解读代码,为攻击者提供便利,通常要求客户端代码不能包含注释,尤其是不能包含核心代码的技术注释。
<1>公共文件绝对路径泄露,暴露了服务器ip和端口信息

<2>暴露第三方服务器文件的绝对地址

应保证前端调用本系统的页面,本系统页面调用本系统接口,服务端调用第三方系统接口,返回的数据通过接口返回至本系统页面
4、错误处理测试,不安全的错误处理方法可能泄露系统或应用的敏感信息,手工测试的过程中应留意各类错误信息,如果发现错误信息中包含系统或应用敏感信息,则进行记录。
某平台sqlserver没有对错误进行正确的处理,将详细的错误信息展示出来,暴露出数据库列名。

防护建议:
1.应根据业务特点定义出系统存储的敏感信息。
2.敏感信息在存储、传输、显示时应进行安全处理,可采用的处理方式为加密或脱敏。
3.敏感信息不应使用GET方式提交到服务器。
4.用户密码为最高级别的敏感信息,在存储、传输、显示时都必须加密。
5.需要选择可靠的加密算法,优先选择非对称加密算法,不得使用BASE64等编码方式进行“加密”
6.对于一些系统默认报错页面应重新进行设计自定义报错页面,以免暴露系统敏感信息。
1.6用户名枚举漏洞 中危
漏洞描述:系统下发了统一的密码,通过枚举用户名的方式,可以获取用户登录信息。
防护建议:
<1>根据业务需求,不同用户下发不同的初始密码
<2>系统下发相同初始密码后,用户首次使用初始密码登录系统时,应强制用户修改初始密码再访问系统内业务操作(确认用户身份)
1.7会话重放攻击 高危
漏洞描述:重放攻击(ReplayAttacks)又称重播攻击、回放攻击或新鲜性攻击,是指
攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程,破坏认证的正确性。
漏洞产生原因:重放攻击会不断恶意或欺诈性地重复一个有效的数据传输,重放攻击可以由发起者,也可以由拦截并重发该数据的敌方进行。攻击者利用网络监听或者其他方式盗取认证凭据,之后再把它重新发给认证服务器。
漏洞危害:
请求被攻击者获取,并重新发送给认证服务器,从而达到认证通过的目的。
会话重放可能导致无限制的向数据库中插入海量数据,或无限制的上传文件到系统中以及越权的修改密码等。
攻击实例:
1、登录
<1>前端web页面用户输入账号、密码,点击登录。
<2>请求提交之前,web端首先通过客户端脚本对密码原文进行md5加密。
<3>提交账号、md5之后的密码
<4>请求提交后端,验证账号密码是否与数据库一致,一致认为成功,反之失败。
上述流程看似安全,传输过程中的密码是md5之后的,即使被监听截取到,由于md5的不可逆性,密码明文也不会泄露。其实不然,监听者无需解密出密码明文即可登录。监听者只需将监听到的url(如:http://****/login.do?method=login&password=md5之后的密码&userid=登录账号) 重放一下,即可冒充你的身份登录系统。
2、新建数据插入到数据库中,系统中的post请求数据包未针对单个请求设置有效的验证参数,导致会话请求数据包可以重放,无限制的插入多条请求到数据库。


综合解决方案:
<1>时间戳验证
请求时加上客户端当前时间戳,同时签名(签名是为了防止会话被劫持,时间戳被修改),服务端对请求时间戳进行判断,如超过5分钟,认定为重放攻击,请求无效。
时间戳无法完全防止重放攻击。
<2>序号
在客户端和服务端通讯时,先定义一个初始序号,每次递增。这样,服务端就可以知道是否是重复发送的请求。
<3>挑战与应答的方式
我们一般采用这种方式来防御重放攻击。
客户端请求服务器时,服务器会首先生成一个随机数,然后返回给客户端,客户端带上这个随机数,访问服务器,服务器比对客户端的这个参数,若相同,说明正确,不是重放攻击。
这种方式下,客户端每次请求时,服务端都会先生成一个挑战码,客户端带上应答码访问,服务端进行比对,若挑战码和应答码不对应,视为重放攻击。
<4>Https防重放攻击
对于https,每个socket连接都会验证证书,交换密钥。攻击者截获请求,重新发送,因为socket不同,密钥也不同,后台解密后是一堆乱码,所以https本身就是防止重放攻击的,除非能复制socket,或者进行中间人攻击。
时间戳解决方案:
1、用户访问客户端页面,增删改请求发送前向服务端请求当前系统时间
2、服务端返回当前系统时间timestamp_server给客户端
3、客户端生成仅一次有效的随机字符串nonce_client
4、客户端读取uid(与服务端约定好,与当前用户相关,唯一且固定的值)
5、客户端调用签名算法,sign_client=md5(timestamp_server+nonce_client+uid),并将sign_client、timestamp_server、nonce_client值拼接到url中随请求发送到服务端(注意uid字段不随请求发送)(http://mollytest/demo/save?data=data×tamp=timestamp_server&nonce=nonce_client&sign=sign_client
该请求中sign值可作为防CSRF的参数值,因为每次请求提交的sign值都不一样,且不可被篡改的(若篡改,与服务端校验不一致),故无法构造CSRF请求,可防止CSRF攻击)
6、服务端收到请求后,读取请求中的参数值timestamp_server、nonce_client、sign_client
7、验证timestamp_server参数,服务端当前时间timestamp_now-timestamp_server是否大于60s。若大于,则请求无效;若小于,则进行步骤8
8、验证nonce_client参数,nonce_client在服务端是否存在(一般存在redis或者服务端map中),如果存在,则请求无效,视为重放攻击;若不存在,则进行步骤9,并将nonce_client记录在redis或map中(键值对数据格式),格式为("nonce"+uid+"_"+nonce),失效时间为60s
9、验证sign_client参数,服务端从数据库中读取该用户的uid参数,并记录前端传回的timestamp_server、nonce_client参数,调用签名生成算法,得到sign_server=md5(timestamp_server+nonce_client+uid),验证sign_server是否等于sign_client,若一致,说明参数未被篡改,请求有效;若不一致,说明参数被篡改,将请求丢弃。
1.8暴力破解缺陷 高危
漏洞描述:在登录的时候有以下情况,则存在暴力破解缺陷
<1>登录页面未使用验证码,且未使用登录失败处理功能。
<2>登录页面使用验证码,但仅在前端校验。
<3>登录页面使用验证码,且前后端均校验,但将页面验证码和用户名、密码分开进行了验证。如果验证码正确,进行第二个请求验证帐号和密码,如果验证码错误,直接对用户名和密码就不再进行验证。
漏洞利用和危害:
针对以上三种情况,均可做暴力破解攻击
<1>直接对登录会话进行重放,进行系统登录账户、口令的暴力破解,一旦破解可成功拥有系统相关用户权限。
<2>通过burpsuite/fiddler工具可绕过验证码前端校验机制,从而进行固定用户名尝试破解密码或者通过密码尝试破解用户名
<3>通过burpsuite/fiddler工具可绕过验证码机制,只对用户名和密码请求进行重放,直接对用户名和密码验证的请求进行爆破,就可以实现扫号、暴力破解的目的。
防护建议:
登录页面采用有效的验证码机制。

二、会话管理与潜在威胁
| 测试编号 | 测试项 | 本次是否测试 | 测试定性 |
| Web_Sess_01 | 不安全的cookie传输 | √是□否 | 中危 |
| Web_Sess_02 | CSRF漏洞测试 | √是□否 | 中危 |
| Web_Sess_03 | 会话设计缺陷 | √是□否 | 中危 |
| Web_Sess_04 | 会话定置测试 | √是□否 | 低危 |
| Web_Sess_05 | 会话复杂度测试 | √是□否 | 低危 |
| Web_Sess_06 | 会话预测缺陷 | √是□否 | 低危 |
| Web_Sess_07 | 会话注销测试 | √是□否 | 低危 |
2.1不安全的cookie传输 低危
漏洞描述:
<1>在cookie中存储了明文的用户名和密码,或加密的密码但能被解密。
<2>查看cookie属性(浏览器F12查看),是否设置httponly和secure属性
设置Httponly属性可以使得此cookie不被js读取,而只能用于http请求,使得攻击者即使控制了页面,也无法读取敏感cookie,极大增加攻击难度。
Cookie中有一个secure属性,若设置则cookie只会在https下发送出去,https的传输是加密的,减少敏感cookie在http明文传输时泄露的可能性。

漏洞危害:
- 用户名密码保存在cookie中,易被窃取;
- 会话cookie不包含“httponly”属性,因此注入站点的恶意脚本可能访问此cookie,并窃取它的值。任何存储在会话令牌中的信息都可能被窃取,并在后续用于身份盗窃或用户伪装。
防护建议:
<1>若cookie不需要被前端js操作,而只被后台服务端读取,则建议将其设置为httponly。
<2>若网站设置了http请求重定向为https,则所有涉及cookie逻辑都在https下完成,建议将其设置为secure
问:为什么设置了httponly-cookie盗窃的威胁并没有彻底消除?
答:因为httponly作用只是限制从其他非HTTP的API(如JavaScript)访问,cookie还是有可能传递的过程中被监听捕获后信息泄漏。将 HttpOnly 属性设置为 true,并不能防止对网络频道具有访问权限的攻击者直接访问该 Cookie。针对这种情况,应考虑使用安全套接字层 (SSL) 来提供帮助。setcookie("tmp", 100, NULL, NULL, NULL, TRUE, TRUE);【https】
另设置secure属性的前提是系统采用了SSL机制,即https,若系统未使用ssl,则即使设置了secure属性,也不生效。
2.2 CSRF漏洞测试 中危
漏洞描述:CSRF,全称Cross-site request forgery,即跨站请求伪造,是指利用受害者尚未失效的身份认证信息(cookie、会话等),诱骗其点击恶意链接或者访问包含攻击代码的页面,在受害人不知情的情况下以受害者的身份向(身份认证信息所对应的)服务器发送请求,从而完成非法操作(如转账、改密等)。
CSRF与XSS最大的区别就在于,CSRF并没有盗取cookie而是直接利用。
漏洞危害:由于发生CSRF攻击后,攻击者是强迫用户向服务器发送请求,所以会造成用户信息被迫修改,更严重者引发蠕虫攻击。
产生原因:
- 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
- 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
- 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
- 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A
- 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
防护建议:
<1>验证HTTP referer字段
在后端程序接收到请求时,应检查请求的来源地址(HTTP Referer)是否合法(利用白名单),如果请求来源不在指定的名单中,即视为CSRF。
<2>随机token
对于敏感的网页,可利用cookie或隐藏域设置一组随机token(同时产生存在于server的session中),当后端程序收到前端请求时,必须检验此token是否与后端session存储的内容相符,若不符就视为非法请求。可利用防重放攻击中的sign当作token。
2.3 SSRF漏洞 中危
漏洞描述:SRF(Server-Side Request Forgery,服务器端请求伪造)漏洞,是一种由攻击者构造请求,由服务器端发起请求的安全漏洞,本质上是属于信息泄露漏洞。
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制 。比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等。
SSRF主要攻击方式如下:
攻击者想要访问主机B上的服务,但是由于存在防火墙或者主机B是属于内网主机等原因导致攻击者无法直接访问主机B。而主机A存在SSRF漏洞,这时攻击者可以借助主机A来发起SSRF攻击,通过主机A向主机B发起请求,从而获取主机B的一些信息。
漏洞危害:
利用file协议读取本地文件
对服务器所在内网、本地进行端口扫描,获取一些服务的banner信息
攻击运行在内网或本地的应用程序
对内网web应用进行指纹识别,识别企业内部的资产信息
攻击内外网的web应用,主要是使用HTTP GET请求就可以实现的攻击
现在服务器上有一个ssrf.php的页面,该页面的功能是获取URL参数,然后将URL的内容显示到网页页面上。
#ssrf.php
<?php
function curl($url){
$ch=curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HEADER,0);
curl_exec($ch);
curl_close($ch);
}
$url=$_GET['url'];
curl($url);
?>
程序获取url参数,通过curl_init()初始化curl组件后,将参数URL带入curl_setopt($ch,CURLOPT_URL,$url),然后调用curl_exec请求该URL。由于服务器端会将banner信息返回给客户端,所以可根据banner判断主机是否存在某些服务。
我们访问该链接:http://127.0.0.1/ssrf.php?url=http://127.0.0.1/test.php ,它会将test.php页面显示
如果我们把url的参数换成 http://www.baidu.com ,页面则会返回百度的页面
于是我们可以将URL参数换成内网的地址,则会泄露服务器内网的信息。将URL换成file://的形式,就可以读取本地文件。这和文件包含漏洞很类似! 如下,我们可以读取服务器host文件的信息
SSRF漏洞防御
限制请求的端口只能为web端口,只允许访问http和https的请求(禁掉file协议)
限制不能访问内网的ip,以防止对内网进行攻击
屏蔽返回的详细信息
2.4会话相关漏洞 中危
漏洞描述:
1、会话登录
<1>非法账号,禁用、锁定、无效、万能账号无法登录
<2>登录失败非法提示,规范错误提示信息,统一为用户登录信息不正确
<3>暴力破解,使用验证码机制以及错误次数限制
<4>非法访问,未登录用户不能访问未授权系统功能
<5>测试系统登录功能是否存在修改返回包绕过前台用户名、密码验证,直接进入系统等。
2、会话设计
<1>超时处理,登录用户长时间不操作,应设置合理的会话超时时间
3、会话注销
<1>系统应存在注销功能,用户可手动注销,退出系统
<2>注销后应清除会话信息,不能通过浏览器后退键重新进入系统内部
2.5会话固定漏洞 中危
漏洞描述:检测用户登录前后cookie,对其中JSESSIONID(JSP)或者SessionId(ASP)进行记录,若登录后,cookie中的这个值没有发生变化,则判定为“会话标识未更新”漏洞。
危害:攻击者通过某种方式(XSS)将自己的sessionid置入了被攻击者的浏览器,将会话标识改为某个攻击者预设的值,被攻击者正常登录,若服务器接收了这个预设值,那么相当于攻击者获得了被攻击者登录后权限,因此要求登录时更新会话标识。
会话固定攻击手段:
<1>在URL中注入Session ID,这是最简单的一种方式,当然也最容易被检测到。
<2>用隐藏的表单字节。攻击者可以构造一个很像登录方式的登录表单并设定Session ID,然后诱惑用户登录。
<3>通过跨站脚本用客户端脚本来设定Cookie,如攻击者可以构造一个链接如下:http://www.buybook.com/viewprofile.jsp?p=30<script>document.cookie="sessionid=1234567";</script>。
<4>通过跨站脚本用<meta>标签进行设定,如攻击者可以构造一个链接如下:http://www. buybook.com/viewprofile.jsp?p=30<meta http-equiv=Set-Cookie content ="sessionid=1234567">。
防护建议:
在验证登录逻辑的时候,先强制让当前session过期,然后更新session。
Cookie和session
session、cookie与“记住我的登录状态”的功能的实现
Cookie的机制
Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能。
Cookie的Domain和Path属性标识了这个Cookie是哪一个网站发送给浏览器的;Cookie的Expires属性标识了Cookie的有 效时间,当Cookie的有效时间过了之后,这些数据就被自动删除了。如果不设置过期时间,则表示这个Cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,Cookie就消失了。这种生命期为浏览会话期的 Cookie被称为会话Cookie。会话Cookie一般不保存在硬盘上而是保存在内存里。如果设置了过期时间,浏览器就会把Cookie保存到硬盘 上,关闭后再次打开浏览器,这些Cookie依然有效直到超过设定的过期时间。存储在硬盘上的Cookie可以在不同的浏览器进程间共享,比如两个IE窗 口。而对于保存在内存的Cookie,不同的浏览器有不同的处理方式。
Session的机制
Session是存放在服务器端的类似于HashTable结构来存放用户 数据,当浏览器第一次发送请求时,服务器自动生成了一个HashTable和一个Session ID用来唯一标识这个HashTable,并将其通过响应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取出Session ID,并和保存的所有Session ID进行对比,找到这个用户对应HashTable。
一般情况下,服务器会在一定时间内(默认20分钟)保存这个HashTable,过了时间限制,就会销毁这个HashTable。在销毁之前,程序员可以 将用户的一些数据以Key和Value的形式暂时存放在这个HashTable中。当然,也有使用数据库将这个HashTable序列化后保存起来的,这 样的好处是没了时间的限制,坏处是随着时间的增加,这个数据库会急速膨胀,特别是访问量增加的时候。一般还是采取前一种方式,以减轻服务器压力。
Session的客户端实现形式(即Session ID的保存方法)
[1] 使用Cookie来保存,这是最常见的方法,本文“记住我的登录状态”功能的实现正式基于这种方式的。服务器通过设置Cookie的方式将Session ID发送到浏览器。如果我们不设置这个过期时间,那么这个Cookie将不存放在硬盘上,当浏览器关闭的时候,Cookie就消失了,这个Session ID就丢失了。如果我们设置这个时间为若干天之后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应网站时,同 样会发送到服务器上。
[2] 使用URL附加信息的方式,也就是像我们经常看到JSP网站会有aaa.jsp?JSESSIONID=*一样的。这种方式和第一种方式里面不设置 Cookie过期时间是一样的。
[3] 第三种方式是在页面表单里面增加隐藏域,这种方式实际上和第二种方式一样,只不过前者通过GET方式发送数据,后者使用POST方式发送数据。但是明显后 者比较麻烦。
实现“记住我的登录状态”的功能
前面我们了解到,如果我们将Session ID通过Cookie发送到客户端的时候设置其过期时间为1年,那么在今后的一年时间内,客户端访问我的网站的时候都回将这个Session ID值发送到服务器上,服务器根据这个Session ID从内存或者数据库里面恢复存放Key-Value对的Hashtable。
其实这已经很好的实现了我们的功能了。但是,前面也提到了,实际上Session并不会一直都存在的,过了一定的时间之后,服务器上的Session就被 销毁了,以减轻服务器的访问压力。当服务器上的数据被销毁后,即使客户端上存放了Cookie也没有办法“记住我的登录状态”了。
通用的实现办法是,将用户的用户名和加密之后的密码也通过Cookie的方式存放在客户端,当服务器上的Session销毁以后,使用Cookie里面存 放的用户名和加密之后的密码重新执行一次登录操作,重建Session,并更新客户端上Cookie中存放的的Session ID,而这个操作是发生在用户请求一个需要身份验证的页面资源的背后,对于用户来讲是透明的,于是就达到了“记住我的登录状态”的目的了。
2.6会话复杂度测试 低危
漏洞描述:测试目标系统产生的sessionid是否具备足够的复杂度。
测试步骤:
<1>在浏览器中配置代理,开启burpsuite,并设置拦截
<2>打开目标系统登录页面,输入正确的用户名和密码提交登录,拦截给请求
<3>将burpsuite拦截的登录请求注入burp sequencer
<4>在sequencer中配置token位置和进程数后,单击“start live capture”

<5>使用burp sequencer向目标系统快速大量地提交登录请求以获得批量sessionid,并将sessionid保存到本地,使用文本编辑器打开保存sessionid的文件
<6>使用文本编辑器打开保存sessionid的文件,检查sessionid的长度和构成
预期结果:
2.7会话预测测试 低危
漏洞描述:测试目标系统产生的sessionid是否可预测。
测试步骤:
<1>使用文本编辑器打开保存的sessionid的文件
<2>检查产生的token是否存在静态不变的部分和可预测的部分


<3>删除静态和可预测部分后的sessionid是否满足会话复杂度要求
| 测试编号 | 测试项 | 本次是否测试 | 测试定性 |
| Web_Auth_01 | 目录枚举测试 | √是□否 | 中危 |
| Web_Auth_02 | 路径遍历测试 | √是□否 | 中危 |
| Web_Auth_03 | 未授权访问漏洞 | √是□否 | 中危 |
| Web_Auth_04 | 越权访问漏洞 | √是□否 | 中危 |
| Web_Auth_05 | 任意文件读取 | √是□否 | 中危 |
3.1目录遍历测试 低危
目录遍历漏洞是由于网站存在配置漏洞,导致网站目录可以被任意浏览,这会导致网站很多隐私文件与目录泄露,比如数据库备份文件、配置文件等,攻击者利用该信息可以为进一步入侵网站做准备。
目录浏览漏洞的探测 :可以利用web漏洞扫描器扫描web应用进行检测,也可通过搜索,网站标题包含 “index of” 关键词的网站进行访问
目录浏览漏洞的危害:攻击者通过访问网站某一目录时,该目录没有默认首页文件或没有正确设置默认首页文件,将会把整个目录结构列出来,将网站结构完全暴露给攻击者; 攻击者可能通过浏览目录结构,访问到某些隐秘文件(如PHPINFO文件、服务器探针文件、网站管理员后台访问地址、数据库连接文件等)。
目录浏览漏洞的预防:
<1>IIS中关闭目录浏览功能:在IIS的网站属性中,勾去“目录浏览”选项,重启IIS。
<2>Apache中关闭目录浏览功能:打开Apache配置文件httpd.conf,查找“Options Indexes FollowSymLinks”,修改为“ Options -Indexes”(减号表示取消,保存退出,重启Apache)。
<3>Nginx 中默认不会开启目录浏览功能,若您发现当前已开启该功能,可以编辑nginx.conf文件,删除如下两行:autoindex on;autoindex_exact_size on,然后重启Nginx。
3.2路径遍历测试 中危
漏洞描述:一个已经授权的用户,通过更改访问时的一个参数,从而访问到了原本其没有得到授权的对象 ,如可通过路径遍历下载敏感信息,可访问系统中目录列表等。
产生原因:目录遍历攻击是由于微博设计者没有考虑恰当的访问控制,使攻击人员利用服务器相关应用服务,来恶意的获取服务器上本不可访问的文件访问权限。
攻击方法:攻击者通过访问根目录,发送一系列”../”字符来遍历高层目录,甚至可以执行系统命令,甚至使系统崩溃。
测试方法:
<1>利用appscan\awvs工具进行扫描
<2>查看web log,如果发现有未授权用户访问越级目录,说明有目录遍历漏洞

<3>手动测试,发送一系列”../”字符来遍历高层目录或者进入系统根目录中。
漏洞危害:
<1>任何人都可以浏览该目录下的所有文件列表;
<2>如果该目录不存在默认的主页面文件,并且该目录包含了敏感的文件内容(如应用程序源码文件或其它的重要文件内容),那么将导致敏感文件内容外泄,从而对企业造成直接的经济损失或为恶意攻击者提供进一步攻击的有效信息。
防护建议:
<1>数据净化,对网络用户提交过来的文件名进行硬编码或者统一编码,对文件后缀进行白名单控制,对包含了恶意的符号或者空字节进行拒绝。
<2>web应用程序可以使用chrooted环境访问包含被访问文件的目录,或者使用绝对路径+参数来控制访问目录,文件的路径由程序强制指定,避免用户恶意摆脱到其他目录。
<3>对于IIS而言,如果不需要可执行的CGI,可以删除可执行虚拟目录或直接关闭目录浏览;如果确实需要可执行的虚拟目录,建议将可执行虚拟目录单独放在一个分区。
IIS服务器关闭目录浏览
<4>对于Apache而言,点击“options-indexes”命令,使目录中的索引不能被查看,或者为每一个目录创建一个默认的关于索引的html文件index.html
3.3未授权访问漏洞 高危
漏洞描述:用户在未登录的情况下,可访问系统内非授权的页面
测试方法:
一、登录控制
<1>用户登录系统,并访问需登录后才能访问的页面A,并记录url
<2>注销登录
<3>在浏览器直接打开页面A的url,查看页面响应
若能跳转至登录页面,无漏洞;若成功打开功能页面A,则存在未授权访问漏洞
二、URL控制
<1>篡改GET请求的URL参数值,是否可以越权访问
<2>将URL复制到没有权限的机器上,验证是否控制住
三、webservice控制
验证webservice服务的访问控制,WEBFORM页面或.asmx,.aspx,.asp等页面,在浏览器中打开,应该提示需要授权才能打开,不能直接打开。
3.4 越权访问漏洞 高危
漏洞描述:越权漏洞是Web应用程序中一种常见的安全漏洞。该漏洞是指应用在检查授权时存在纰漏,使得攻击者在获得低权限用户账户后,利用一些方式绕过权限检查(比如说修改数据包的值或者直接访问其他用户相应页面的链接),访问或者操作其他用户或者更高权限用户才能访问到的页面或数据。
越权分为水平越权和垂直越权:水平越权指的是攻击者越权访问到了一个和他拥有相同权限用户的资源,而垂直越权指的是一个低级别用户访问到了一个高级别用户的资源。

漏洞挖掘:在实际的代码安全审查中,这类漏洞往往很难通过工具进行自动化检测,因为必须通过人工判断,人工判断必须先分析当前网站处理业务的逻辑,通过拦截数据包进行业务逻辑判断,判断数据包中的各个参数的意义
<1>请求中不存在参数,只用cookie进行身份验证,不可越权;
<2>请求中存在参数,并且参数中的某些值可能是辨别信息的唯一值(如employeeID、departmentID、ID等),则可能存在越权;
测试方法:
检测水平越权
<1>打开两个浏览器,分别用普通用户登录
<2>查看每个页面的链接,抓包分析其参数的意义,找到与用户名有关的参数,修改成其他用户,重放,看能否访问。如果能访问,则存在水平越权
检测垂直越权
<1>打开两个浏览器,一个浏览器用超级管理员admin身份登录,一个浏览器用普通用户身份登录
<2>仔细对比两个浏览器之间,哪些页面是管理员用户独有的,然后复制链接到普通用户浏览器打开,或者抓包分析包的结构然后篡改重放,看能否访问。如果能访问,则存在垂直越权。
防护建议:
1、有关权限的管理,应在服务器上对每个登录用户session进行验证,在每个网页进入点都应检查用户是否具备相对应的操作权限,避免越权存取。
2、用户登录后,服务端不应再以客户端提交的用户身份信息作为依据,而应以会话中服务端保存的已登录的用户身份信息为准。
3、页面提交的资源标志与已登录的用户身份进行匹配比对,然后判断其对当前链接是否有权限
4、必须在服务器端对每个请求URL进行鉴权,不能仅仅通过客户端的菜单屏蔽或者按钮Disable来限制
3.5任意文件读取/下载漏洞 高危
漏洞描述:测试用户能否查看或下载任意的文件,可以对源代码文件、敏感文件、备份文件等进行下载。
测试方法:
1、通过web漏洞扫描工具对网站实施扫描可能发现任意文件读取/下载漏洞,发送一系列”../”字符来遍历高层目录,并且尝试找到系统的配置文件或者系统中存在的敏感文件。
2、也可通过判断网站语言,并根据其url中部分提供的参数,进行构造相关的路径信息,如收集到网站中间件版本为apache,则想办法构造../../../ WEB-INF/web.xml等,然后查看其是否可被读取或者下载出来。
3、有些WAF会过滤../,可以构造 /.%252e/.%252e/.%252e/ , %25对应的是%,%2e对应的是.,所以 .%252e/ 对应的是 ../ 
敏感字段:
| &RealPath= | &filepath= | &inputFile= |
| &FilePath= | &Path= | &url= |
| &urls= | &Lang= | &dis= |
| &data= | &readfile= | &filep= |
| &src= | &menu= | & |
详细测试方法:
Filename=../../../../../etc/password
Filename=../../../../../boot.ini
修改参数如file,filepath等通过../或..\等尝试穿越路径,使用%00尝试截断路径,查看是否可以下载到/etc/passwd, web.config、 WEB-INF/web.xml、应用源码等文件。
解决方案:
1、净化数据:对用户传过来的文件名参数进行统一编码,对文件类型进行白名单控制,对包含恶意字符或者空字符的参数进行拒绝。
2、web应用程序可以使用chroot环境包含被访问的web目录,或者使用绝对路径+参数来访问文件目录,使其即使越权也在访问目录之内。www目录就是一个chroot应用。由chroot创造出的那个根目录,叫做“chroot监狱”(所谓"监狱"就是指通过chroot机制来更改。某个进程所能看到的根目录,即将某进程限制在指定目录中,保证该进程只能对该目录及其子目录的文件有所动作,从而保证整个服务器的安全,详细具体chroot的用法,可参考http://blog.youkuaiyun.com/frozen_fish/article/details/2244870
3、任意文件下载漏洞也有可能是web所采用的中间件的版本低而导致问题的产生,例如ibm的websphere的任意文件下载漏洞,需更新其中间件的版本可修复。
4、要下载的文件地址保存至数据库中。
5、文件路径保存至数据库,让用户提交文件对应ID下载文件。
6、用户下载文件之前需要进行权限判断。
7、文件放在web无法直接访问的目录下。
8、不允许提供目录遍历服务。
9、公开文件可放置在web应用程序下载目录中通过链接进行下载。
3.6任意用户注册漏洞 高危
漏洞描述:绕过实名制使用任意手机号进行注册,以任意用户身份注册账号。覆盖注册:可以重复注册已注册用户,导致重复注册用户账号不可用甚至接管重复注册所有用户权限
漏洞示例:
在注册页面,只要输入有效的logincode,即可替代该账号原来的手机号,输入任意手机号,注册成功,存在任意账号注册漏洞

将手机号替换成自己的,然后输入手机验证码,即可登录进入系统,存在任意账号注册风险。
漏洞危害:攻击者只需获取用户ERP本地编号,即可替换原登录手机号,进行任意账号注册并登录进入系统,存在安全隐患。
修复示例:
对注册用户身份做校验
覆盖注册时应根据业务需求先解绑原账号
| 测试编号 | 测试项 | 本次是否测试 | 测试定性 |
| Web_Serv_01 | 设计权限/逻辑错误 | √是□否 | 中危 |
4.1单用户并发 中危
漏洞描述:
<1>不控制单用户并发数,同一个用户可同时在多个客户端登录,在某个客户端修改密码后,该用户在其他客户端的登录状态不受影响,仍可继续使用。(应强制所有客户端退出,重新登录)
<2>不控制单用户并发数,同一个用户可同时在多个客户端登录,在某个客户端删除数据后,其他客户端仍可对该数据进行修改操作。(判断数据逻辑状态和竞争条件)
<3>控制单用户并发数,同一个用户只能同时在一个客户端登录,且系统设置为“后”不能踢“前”(应设置后面登录的用户踢掉前面的,避免恶意占用,若后面的不能踢掉前面的用户,且前面用户未手动注销退出系统,则需等待前面用户会话自动失效才可登录)
4.2修改密码 高危
<1>新旧密码验证,新旧密码不能相同且应在同一个请求中发送
<2>应为post请求,不能在url上传输密码
<3>密码复杂度,大小写、特殊字符、数字3种及以上,密码位数8位及以上构成
<4>修改密码后逻辑,强制退出,重新登录
<5>初始密码,用户首次登录后应强制用户修改密码
4.3密码重置 高危
<1>修改请求中用户名、用户ID或手机号重置任意账号密码造成越权访问
防护建议:
用户操作个人信息时(读取、修改),服务端要对当前用户身份进行验证,防越权
用来标识用户身份的名称或ID应加密,或隐藏这些参数
建议直接从会话cookie或token中读取用户信息
密码reset时,服务端应对当前用户名,用户id、手机号、token等进行二次匹配,都为true时才可以修改成功
<2>修改响应包重置任意账号密码,服务端对重置密码操作验证(一般是短信验证码)时,结果为true时直接跳到下一步,无需向客户端单独返回验证结果
防护建议:
最后提交时,应对当前用户名、用户id、手机号、token等做二次匹配验证
<3>跳过验证步骤重置任意账号密码
防护建议:
每一个步骤要对前一个步骤进行验证
最后提交时,应对当前用户名、用户id、手机号、token等做二次匹配验证
4.4功能逻辑绕过前端校验 高危
漏洞描述:
系统前端控制已经被引用或占用的数据不允许修改或者删除,但是构造请求访问修改或删除数据的请求,并将请求中的数据id改为被引用或占用的数据,后台处理该请求,并返回修改/删除成功
系统前端控制未提交的单据不能走审批流程/已失效的订单不能发布等,但是通过构造请求的方式审批单据/发布订单,并将请求中的单据id或订单id改为未提交的、已失效的,服务器端正常处理构造的请求,并返回审批通过、发布成功等状态
项目实例:
<1>采购管理—出入库管理模块中,前端校验删除操作只能删除未上报的数据
<2>删除一个未上报状态的数据,并使用抓包工具抓取删除请求,可以看到是通过数据的ids进行数据的删除
<3>访问该模块时,通过抓包可以看到该模块所有数据的ids,包括已上报和未上报的数据
<4>重新构造请求,将删除请求中的参数信息ids修改为已上报的数据ids,服务器没有对数据的当前状态做判断,删除成功,存在逻辑漏洞
防护建议:
此类逻辑前后端应保持一致,服务器端处理时对数据的状态做二次校验,对已经被引用或占用的数据不允许被删除/修改
4.5输入框检查 低危
<1>长度
输入超长内容,页面截断或溢出,抛出非法异常
<2>类型
严格控制输入框类型,如年龄只能输入int字符
不应区分大小写,如上传.bmp文件上传成功,上传.BMP文件上传失败
<3>非法字符
输入JS文件或其他特殊字符,页面是否显示异常,是否抛出SQL,是否抛出程序堆栈或json等敏感信息,输入表情。
4.6修改响应包绕过逻辑漏洞 高危
漏洞描述:服务器返回的响应包中,存在标志位ture/false让客户端去判断该请求是否继续执行,然而当我们截获了响应包对标志位进行篡改操作之后,可以对客户端的判断产生影响,可绕过客户端的判断进行下一步操作。
漏洞实例:修改响应包绕过强制修改密码操作
<1>通过修改登录请求返回的响应中的staffcode字段值可绕过强制修改密码功能
。
防护建议:
将系统中的逻辑判断放在服务器执行,并直接向客户端返回结果。
| 测试编号 | 测试项 | 本次是否测试 | 测试定性 |
| Web_Risk_01 | 文件上传漏洞 | √是□否 | 高危 |
| Web_Risk_02 | SQL注入测试 | √是□否 | 高危 |
| Web_Risk_03 | XML实体攻击 | √是□否 | 高危 |
| Web_Risk_04 | XSS跨站脚本攻击 | √是□否 | 高危 |
| Web_Risk_05 | 命令注入测试 | √是□否 | 高危 |
5.1文件上传漏洞 中危
漏洞描述:文件上传漏洞是指攻击者上传了一个可执行的文件到服务器并执行,这里上传的文件可以是木马,病毒,恶意脚本或者webshell等。
产生原因:
文件上传漏洞,直面意思可以理解为利用WEB上传一些特定的文件。一般情况下文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。文件上传本身是互联网中最为常见的一种功能需求,关键是文件上传之后服务器端的处理、解释文件的过程是否安全。一般的情况有:
1. 上传文件WEB脚本语言,服务器的WEB容器解释并执行了用户上传的脚本,导致代码执行;
2. 上传文件FLASH策略文件crossdomain.xml,以此来控制Flash在该域下的行为;
3. 上传文件是病毒、木马文件,攻击者用以诱骗用户或管理员下载执行;
4. 上传文件是钓鱼图片或为包含了脚本的图片,某些浏览器会作为脚本执行,实施钓鱼或欺诈。
测试方法:
1.上传文件是否有格式限制,是否可以上传exe文件;
2.上传文件是否有大小限制,上传太大的文件是否导致异常错误,上传0K的文件是否会导致异常错误,上传并不存在的文件是否会导致异常错误;
3.修改扩展名的方式是否可以绕过格式限制,是否可以通过压包方式绕过格式限制;
4.是否有上传空间的限制,是否可以超过空间所限制的大小,如将超过空间的大文件拆分上传是否会出现异常错误。
5.上传文件大小大于本地剩余空间大小,是否会出现异常错误。
6.关于上传是否成功的判断。上传过程中,中断。程序是否判断上传是否成功。
7.对于文件名中带有中文字符,特殊字符等的文件上传。
过滤方案:
1、前端脚本检测文件扩展名。当客户端选择文件点击上传的时候,客户端还没有向服务器发送任何消息,前端的 js 脚本就对文件的扩展名进行检测来判断是否为上传的类型。
#前端脚本检测,只允许上传 .jpg格式的文件
<script type="text/javascript">
function selectFile(fnUpload) {
var filename = fnUpload.value;
var mime = filename.toLowerCase().substr(filename.lastIndexOf("."));
if(mime!=".jpg")
{
alert("请选择jpg格式的照片上传");
fnUpload.outerHTML=fnUpload.outerHTML;
}
}
</script>
2、后端脚本检测文件扩展名,数据提交到后端,后端的函数对上传文件的后缀名进行检测,比如黑名单检测不允许上传 .php 、.asp 后缀格式的文件;白名单检测只允许上传 .jpg 格式的文件
#后端php检测
$info=pathinfo($_FILES["file"]["name"]);
$ext=$info['extension'];// 得到文件扩展名
if (strtolower($ext) == "php") { #黑名单检测,不允许上传php格式的文件
exit("不允许的后缀名");
}
3、后端通过对上传文件的 Content-Type 类型进行黑白名单检测过滤
#后端对上传文件的 Content-Type类型进行检测,只允许上传 image/gif、image/jpeg、image/pjpeg格式的文件
if (($_FILES["file"]["type"] != "image/gif") && ($_FILES["file"]["type"] != "image/jpeg")
&& ($_FILES["file"]["type"] != "image/pjpeg")){
exit($_FILES["file"]["type"]);
exit("不允许的格式");
4、通过函数比如 getimagesize() 函数检测你上传的图片的大小是否是正常的图片大小,防止上传一句话木马。通过分析图片头部来判断这个是不是一个有效的图片格式,比如 jpg 格式图片头部是 JFIF ,gif头部是GIF89a,png头部是%PNG
#后端检测上传的文件是否是正常大小的图片
if(!getimagesize($_FILES["file"]["tmp_name"])){
exit("不允许的文件");
}
注意:在生产环境中的过滤,往往是这些方法都会结合的,而不只是单单的某一个过滤方法。生产环境中的过滤是很严格的。
防护建议:
1、客户端检测,使用 js 对上传图片检测,包括文件大小、文件扩展名、文件类型等
2、服务端检测,对文件大小、文件路径、文件扩展名、文件类型、文件内容检测、对文件重命名等
3、服务器端上传目录设置不可执行权限
4、检查网站有没有文件解析漏洞和文件包含漏洞
5、将文件上传到单独的文件服务器,并且单独设置文件服务器的域名
5.2SQL注入测试 高危
漏洞描述:SQL注入漏洞是因为后台SQL语句拼接了用户的输入,而且web应用程序对用户输入数据的合法性没有判断和过滤,前端传入后端的参数是攻击者可控的,攻击者可以通过构造不同的sql语句来实现对数据库的任意操作。比如增删改查,如果数据库的用户权限足够大,还可以对操作系统执行操作。
产生方式: 若程序使用了JDBC查询,且开发人员使用了语句拼接
以下面的sql查询为例:select * from users where Username=‘$username’and Password=‘$password’如果我们在页面上输入以下的用户名和密码:$username=1’or‘1’=‘1$password=1’or‘1’=‘1那么整个查询语句就变成:select * from users where Username=‘1’or ‘1’=‘1’and Password=‘1’or ‘1’=‘1’假设参数值是通过GET方法传递到服务器的,且域名为www.example.com,
那么我们的访问请求就是:
http://www.example.com/index.php?username=1'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%20'1对上面的SQL语句作简单分析后我们就知道由于该语句永远为真,所以肯定会返回一些数据,在这种情况下实际上并未验证用户名和密码,并且在某些系统中,用户表的第一行记录是管理员,那这样造成的后果则更为严重
测试方法:
<1>输入单引号’或者分号; 两者在sql中是字符串终结符, 如果程序没做过滤,则会产生错误信息。
<2>输入拼接sql,查看是否执行(返回数据),如1’ or 1=1
<3>使用sqlmap扫描,查看是否存在注入漏洞
<4>使用burpsuite\appscan\wvs工具进行扫描
http://www.xxx.com/show.asp?id=474 and 1=1, 运行正常,且与http://www.xxx.com/show.asp?id=474运行结果相同;http://www.xxx.com/show.asp?id=474 and 1=2,show.asp运行异常
到这里基本上可断定存在SQL注入点,至于能否进入到后台,还需进一步注入测试。
```Sqlmap.py -u ”http://www.uangyih.com.tw/china/prod_item_detail.php?item_id=43”```

``` Sqlmap.py -u ”http://www.uangyih.com.tw/china/prod_item_detail.php?item_id=43” --dbs```
执行该指令后发现该网站中有176个数据库
Step.4 查看当前数据库
运行下面的命令,查看当前数据库:
Sqlmap.py -u ”http://www.uangyih.com.tw/china/prod_item_detail.php?item_id=43” --current-db

Step.5 列出目标数据库的表
现在我们需要知道在数据库uangyih_db中都有哪些表,为了弄清这些信息,我们使用下面的命令:
Sqlmap,py -u ”http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15” -D uangyih_db --tables


Step.6 列出指定数据库表中列
现在我们需要列出数据库uangyih_db的表admin_account中的所有的列,使用SQLMAP进行这一步会非常简单,运行下面的命令:
sqlmap.py -u ”http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15” -D uangyih_db -T admin_account --columns

其中username和pass_word字段就是我们要找的
Step.7 获取用户名
sqlmap.py -u ”http://www.sqldummywebsite.com/cgi-bin/item.cgi?item_id=15” -D uangyih_db -T admin_account -C username --dump

Step.8 获取密码


解决方案:
1.不要信任用户的输入,要对用户的输入输出进行校验,可以通过正则表达式,或限制长度,或者使用过滤函数,对单引号和双"-"进行转换等。
2.不使用动态拼装SQL,使用参数化的SQL或者使用存储过程进行数据查询存取。
3.不使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
5.使用正则表达式过滤,对用户输入的特殊字符进行严格过滤,如 ’、”、<、>、/、*、;、+、-、&、|、(、)、and、or、select、union
6.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中。
5.3XML实体攻击 中危
漏洞描述:XXE漏洞全称XML External Entity Injection,即xml外部实体注入漏洞。XXE漏洞发生在应用程序解析XML输入时,没有禁止外部实体的加载,导致可加载恶意外部文件,造成文件读取、命令执行、内网端口扫描、攻击内网网站、发起dos攻击等危害。xxe漏洞触发的点往往是可以上传xml文件的位置,没有对上传的xml文件进行过滤,导致可上传恶意xml文件。
漏洞利用:上传或控制一个xml文件,让服务器端去解析该文件,即可以读取服务端文件内容。
漏洞实例:
<1>进入目标网站 http://web.jarvisoj.com:9882/ 发现一个输入框,我们对其进行抓包
<2>发现请求的body中是一段json数据,修改发现可以被解析
<3>修改json处,构造一个xml表单进行xml注入,服务器端成功解析该xmL内容,返回flag.txt文件内容,说明存在xml外部实体攻击漏洞。
防护建议:
<1>使用开发语言提供的禁用外部实体的方法
PHP:
libxml_disable_entity_loader(true);
JAVA:
DocumentBuilderFactory dbf =DocumentBuilderFactory.newInstance();
dbf.setExpandEntityReferences(false);
Python:
from lxml import etree
xmlData = etree.parse(xmlSource,etree.XMLParser(resolve_entities=False))
<2>过滤用户提交的XML数据,不允许XML中含有自己定义的DTD
过滤关键字:<\!DOCTYPE和<\!ENTITY,或者SYSTEM和PUBLIC。
- 会话管理与潜在威胁
- 用户名密码保存在cookie中,易被窃取;
- 会话cookie不包含“httponly”属性,因此注入站点的恶意脚本可能访问此cookie,并窃取它的值。任何存储在会话令牌中的信息都可能被窃取,并在后续用于身份盗窃或用户伪装。
- 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;
- 在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;
- 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;
- 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A
- 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。
- 所有的sessionid的字符串长度都应大于等于16
- 所有的sessionid都由数字、普通小写字符、普通大写字符和特殊字符中的2种组合而成。
- 用户权限与潜在威胁
- 设计权限与逻辑错误
- web页面与潜在威胁
5.4XSS跨站脚本攻击 高危
漏洞描述:跨站脚本是一种经常出现在web应用程序中的计算机安全漏洞,是由于web应用对用户提交请求参数未做充分的检查过滤,允许用户在提交的数据中加入HTML\JS代码,未加编码地输出到第三方用户浏览器,恶意攻击者可以利用JS、activeX、html语言甚至flash应用的漏洞,发送恶意代码给另一个用户,因为浏览器无法识别脚本是否可信,从而跨站漏洞脚本便运行并让攻击者获取其他用户信息。
危害:攻击者能盗取会话cookie或session、获取账户、模拟其他用户身份,甚至可以修改网页呈现给其他用户的内容。
攻击分类:
<1>反射型XSS攻击
又称为非持久性跨站脚本攻击,它是最常见类型的XSS。漏洞产生的原因是攻击者注入的数据反应在响应中,一个典型的非持久性XSS包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击)。
实例:正常发送的消息http://www.test.com/message.php?send=hello,word!
接收者将会接收信息并显示hello,world
本文详细分析了各种WEB安全漏洞,包括配置管理、弱口令、不安全加密算法、安全配置不当等问题,以及如何修复这些漏洞。介绍了如明文传输、存储、弱口令、不安全加密算法的危害和防护措施,如启用SSL、加密敏感数据、设置复杂密码策略、禁用不必要HTTP方法、限制并发登录、强化文件上传与SQL注入防御等。同时提醒关注跨站脚本(XSS)、XML实体攻击等其他威胁,并提出相应的防范策略。
482

被折叠的 条评论
为什么被折叠?



