定义:安全测试是在软件产品开发基本完成时,验证产品是否符合安全需求定义和产品质量标准的过程。
概念:安全测试是检查系统对非法侵入渗透的防范能力。
准则:理论上来讲,只要有足够的时间和资源,没有无法进入的系统。因此,系统安全设计的准则是使非法侵入的代价超过被保护信息的价值。
目标:通过对系统进行精心、全面的脆弱性安全测试,发现系统未知的安全隐患并提出相关建议,确保系统的安全性。安全性一般分为应用程序级别和系统级别,区别如下:
应用程序级别:包括对应数据或业务功能的访问,核实应用程序的用户权限只能操作被授权访问的那些功能或数据。
系统级别:包括对操作系统的目录或远程访问,主要核实具备系统和应用程序访问权限的操作者才能访问系统和应用程序。
一、短信验证码
1、确保验证码与用户名、密码是一次性同时提交给服务器进行验证的,如果分开提交、分开验证,那么系统存在漏洞
2、在登录界面单击右键查看HTML 源代码,如果在HTML 源代码中可以查看到验证码的值,说明系统存在漏洞
3、测试生成的验证码的有效次数只为一次,即只要使用该验证码登录过一次后,该验证码就失效
4、验证码随机生成规则
5、验证码有效时间内使用,失效无法使用
6、对手机号做验证,正确的手机号才可发短信成功
7、同1个手机号不能连续获取短信验证码,如设置1分钟仅允许使用1次
8、同1手机号,1天设置最大发送验证码次数,如同1手机号1天最多发10条
9、设置每日短信总成功条数上限
10、当同1个手机号码或者ip重复连续不断发起请求时,将手机号码或者ip拉黑处理
二、开关
1、功能增加开关,当功能出现严重BUG(如刷钱操作)时,关闭功能,避免损失
三、支付
昨日有用户使用时发现,摩拜单车安卓最新版(4.1.0版)出现技术漏洞,用户充值1元竟被返现110元。无独有偶,上网搜索看到,发现一漏洞的网友并不在少数,有网友设置截图显示,从昨日上午到12:15-13:42,其连续充值7次1块钱,系统连续7次返值110元,共计返值770元,不过截止到下午14:45分左右,类似情况不再出现
例:充100送120
1、充值时拦截请求,修改充值金额为1元,发出请求,测试服务端是否进行金额校验
例:购买100元商品
2、余额99,下单购买商品进行支付,拦截请求修改金额为100,发出请求,测试服务端是否进行金额校验
例:发薪资、提现
3、余额100,发薪资100并发100次,测试加锁校验
余额100,发薪资100,并发审核100次,测试加锁校验
余额100,提现100并发100次,测试加锁校验
四、篡改响应
1、认证成功可获得积分
输入任意认证信息,提交成功,抓取接口,拦截响应,修改响应为成功,导致认证成功并获得积分
五、越权
1、登录权限越权
token失效、账号被踢出,使用创建订单、充值、付款功能,对token检验进行测试
2、业务逻辑越权
新建的订单、已付款的订单、已发货的订单、已收货的订单、已完成的订单、已评价的订单,进行付款操作测试
3、垂直越权未授权的功能
主管有修改权限,客服有查看权限,主管账号更换为客服账号,进行修改操作测试
4、水平越权其它用户资源
通过修改URL链接上的参数来进行一些非对应账号信息的查看和操作。
例1:修改URL上的订单号为别人的,查看、修改、删除、评价、操作别人的订单进行测试
例2:修改URL上的订单参数为不存在的,查看、修改、删除、评价、操作别人的订单进行测试
六、敏感数据传输
1、登录密码、交易密码是否加密处理传输
2、用户身份证号、银行卡是否暴露在接口中
七、密码、修改密码、找回密码、重置密码
1、如果为输入密码的方式,查看HTML 源代码,检查是否存在关于密码的一些数据
2、重置后的密码一般通过用户的邮箱或手机短信来通知用户
3、修改密码时是否要求输入旧密码,如果不需要用户填写旧密码,说明系统存在缺陷。
4、测试是否可以修改其他用户密码,一般只有管理员或有相关权限的用户可以修改其他用户密码
5、如果初始口令为系统提供的默认口令或者是由管理员设定,用户使用初始口令成功登录,系统必须强制用户更改初始口令,直至更改成功,否则存在漏洞
6、修改密码、找回密码、重置密码,需强制踢出用户
7、密码输入错误,需限制每日上限次数,达到上限,暂时锁定,无法使用,过天可恢复正常使用
8、密码需使用强口令
9、密码复制粘贴
八、SQL、代码注入
SQL注入漏洞原理
SQL 注入是一种将 SQL 代码插入或添加到应用(用户)的输入参数中,之后再将这些参数传递给后台的 SQL 服务器加以解析并执行的攻击。
攻击者能够修改 SQL 语句,该进程将与执行命令的组件(如数据库服务器、应用服务器或 WEB 服务器)拥有相同的权限。 如果 WEB
应用开发人员无法确保在将从 WEB 表单、cookie、输入参数等收到的值传递给 SQL查询(该查询在数据库服务器上执行)之前已经对其进行过验证,通常就会出现 SQL 注入漏洞。
1、登录注入
账号登录时SQL: select * from users where username='wangli' and password='123456'
<1>我们现在需要构建一个比如:在用户名输入框中输入: ’ or 1=1#,密码随便输入111,这时候的合成后SQL语句为:
select * from users where username=' ' or 1=1#' and password='111'
等价于select * from users where username='' or 1=1
等价于select * from users就可以登录成功了
2、搜索类
<1>搜索姓名,输入单引号、双引号,点搜索,系统报错,证明我们提交数据被系统接收,存在SQL注入漏洞
搜索姓名' 如:wangli'
搜索姓名" 如:wangli"
<2>搜索id=1时,判断是否存在注入
输入1查询成功
输入1' or '1'='1 、1' or '1'='1' #、1' or 1=1# 返回多个结果,说明存在字符型注入
输入1 or 1=1返回多个结果,说明存在数字型注入
输入1' and '1'='2 查询失败
' and 1=2#
3、url传参注入
字符型注入:
在url后面加单引号、双引号报错
接着用 ' and '1'='1,' and '1'='2判断页面,或者' and 1=1#,' and 1=2#
首先应测试是否存在注入漏洞,简单的:’ 或 and 1=1 and 1=2之类的SQL语句。
如果没有检测,直接运行SQL语句,说明有机会注入。
举例:
从参数注入,简单的测试方法是:
http://www.xxx.com/index.php?id=2'
http://www.xxx.com/index.php?id=2' and 1=1
http://www.xxx.com/index.php?id=2' and 1=2
4、代码注入
1、提交死循环代码,测试是否进行过滤处理
<script>
for(i=0;i<1;i--)
{
alert("msg")
}
</script>
<input type="text"/>
<input/>
<input/
<script>alert('hello');</script>
1.jpg" οnmοuseοver="alert('xss')
"></a><script>alert(‘xss’);</script>
http://xxx';alert('xss');var/ a='a
‘”>xss&<
a=”\” ; b=”;alert(/xss/);//”
<img src=“输出内容” border=“0” alt=“logo” />
2、输入<html”>”gfhd</html>,看是否出错;
3、输入<input type=”text” name=”user”/>,看是否出现文本框;
4、输入<script type=”text/javascript”>alert(“提示”)</script>看是否出现提示。
5、输入特殊字符 如:~!@#$%^&*()_+<>:”{}|
6、输入超大数9999999999,超长字符、0、null、NULL、负数
5、枚举查询表列数(order by)
搜索框输入' order by 10 #
构造出SQL为select * from user where mobile='' order by 10 # '
select * from user where mobile='正确的手机号' order by 10 # '
如果10报错[Err] 1054 - Unknown column '10' in 'order clause',说明列不足10个,依次向前实验
如果9时不报错,说明有9列
总结与主流防御
1.永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号、双"--"、#、恒等进行转换等。
2.永远不要使用动态拼装SQL,可以使用参数化的SQL或者直接使用存储过程进行数据查询存取。
3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。
4.不要把机密信息明文存放,请加密或者hash掉密码和敏感的信息。
5.应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装,把异常信息存放在独立的表中
6、过滤关键字,对一些sql语句中可能出现的关键词进行过滤
7、编码/转移特殊符号,对用户输入的进行编码或转义,使其无法产生原有效果
8、语义分析拦截,对用户输入进行判断,保证不存在于任意可执行的sql语句的片段中