注入类
数据库注入
SQL注入
结构化查询语言 (Structured Query Language)简称SQL,结构化查询语言是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统关系型数据库 ,是指采用了关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解,关系型数据库这一系列的行和列被称为表,一组表组成了数据库。常见的关系型数据库有Oracle、DB2、Microsoft SQL Server、MySQL、 Microsoft Access
sql语句可分为
数据查询语言(DQL):用以从表中获得数据。常用保留字: SELECT 、WHERE、ORDER BY、GROUP BY、HAVING数据操作语言(DML):用于添加、修改、删除表中的行。常用保留字: INSERT 、UPDATE 、 DELETE事务控制语言(TCL):确保被DML语句影响的表的所有行及时得以更新。常用保留 字:COMMIT、SAVEPOINT、ROLLBACK数据控制语言(DCL):通过GRANT或REVOKE实现权限控制,确定单个用户和用户组对数据库对象的访问数据定义语言(DDL):在数据库中创建新表或修改、删除表。常用保留字:CREATE、ALERT、DROP指针控制语言(CCL):通过DECLARE CURSOR、FETCH INTO和UPDATEWHERE CURRENT
SQL注入攻击是由于web应用程序开发中,没有对用户输入数据的合法性进行判断,攻击者可以通过输入区域(如URL、表单等),利用某些特殊构造的SQL的特殊字符和指令,提交一段数据库查询代码,操纵并获得敏感数据。攻击的对象是:数据库
示例:
String query = "SELECT * FROM users WHERE userName = '"+ 用户名变量 + "' AND password = '"+ 密码变量 + "'";
ResultSet rs = stmt.execute(query);
如果使用攻击载荷:
用户名: admin’ or ‘1’=‘1
密 码:admin@123’or ‘1’=‘1
单引号用于闭合
sql注入的步骤
① 识别Web应用与数据库交互的可能输入(识别潜在注入点)② SQL注入语句测试③ 根据服务器返回判别注入语句是否影响了SQL执行结果以判断是否存在SQL注入
sql注入分类
– Error-based SQL injection(报错型注入)通过返回的错误的信息
– Boolean-based blind SQL injection(布尔型注入) 通过条件的正误的判断
– Time-based blind SQL injection(基于时间延迟注入) 判断是否会延时返回请求的结果
按照注入参数类型分为
1.数字型注入http://test.com/shownews.php?id=1select * from news where news_id=12.字符型注入http://test.com/show.php?name=appleselect * from fruits where name= ' apple '
测试sql注入的类型:
Oracle: JAVADB2: JAVASQL Server: C#、ASP、.NETMySQL: PHP、JAVA
基于特有的函数判断数据库类型
基于特有的数据表进行判断
sql注入按照注入方式分为
显示注入• union query #联合查询注入,通过union联合查询获取查询结果• error based #报错注入,通过报错信息获取查询结果盲注• boolean based blind #布尔盲注,通过应用返回不同的值推断条件真假• time based blind #时间盲注,通过不同的时间延迟推断条件真假优先级: union query≥error based>boolean based blind>time based blind
联合查询注入
union query前提:页面可以显示数据库查询结果id=1 order by 5 #猜字段数id=-1 union select 1,2,3,4,5 #测试哪个字段有回显id=-1 union select 1,concat(user(),0x2b,database()),3,4 #获取数据库用户和数据库名id=-1 union select 1,group_concat(distinct table_name),3,4 frominformation_schema.tables where table_schema=database() #获取表名id=-1 union select 1,group_concat(distinct column_name),3,4 frominformation_schema.columns where table_name= 'user' #获取列名id=-1 union select 1,concat(id,0x2b,name,0x2b,password),3,4 from user #获取具体数据
报错注入
error based前提:应用可以输出数据库报错信息•floor()and (select 1 from(select count(*),concat(version(),floor(rand(0)*2))x frominformation_schema.tables group by x)a)•updatexml()and 1=(updatexml(1,concat(0x3a,(select user())),1))•extractvalue()and extractvalue(1,concat(0x5c,(select user())))•exp()and exp(~(select * from(select user())a))
布尔盲注
前提:条件真假页面有差别,可区分。可根据返回页面不同判断条件真假需要一位一位猜解,常用到substr、ascii、mid等函数if(substr(flag,1,1)in(0x66),3,0)select case when ascii(mid((select flag from flag),1,1))=65 then 'A' else 'B' end
前提:在其他注入方式使用不了的情况下才会考虑时间盲注,需要借助时间延迟函数或其他方式达到时延的效果来判断条件真假if(substr(flag,1,1)in(0x66),sleep(2),0)select case when ascii(mid((select flag from flag),1,1))=65 thenbenchmark(100000,sha1('1 ')) else '' end
提交参数类型
– 数字型
– 字符型
– 搜索型
sql注入防范措施:
-
使用参数化查询
-
严格限定参数类型和格式,明确参数检验的边界,必须在服务端正式处理之前对提交的数据的合法性进行检查;
-
验证输入/参数过滤,即白/黑名单验证;
SQL注入的危害:
-
数据库信息泄漏:数据库中存放的用户的隐私信息的泄露。
-
网页篡改:通过操作数据库对特定网页进行篡改。
-
网站被挂马,传播恶意软件:修改数据库一些字段的值,嵌入网马链接,进行挂马攻击
-
数据库被恶意操作:数据库服务器被攻击,数据库的系统管理员帐户被窜改。
-
服务器被远程控制,被安装后门。经由数据库服务器提供的操作系统支持,让黑客得以修改或控制操作系统。
-
破坏硬盘数据,瘫痪全系统。
跨站脚本攻击xss
跨站脚本攻击:web开发者在编写应用程序时没有对用户提交的语句和变量进行过滤和限制。从本质上来说就是将数据注入到了静态脚本代码中(HTML或者Javascript等),当浏览器渲染整个HTML文档的过程中触发了注入的脚本,导致了XSS攻击的发生。
分类
1.反射型XSS:跨站代码一般存在于链接中,请求这样的链接时,跨站代码经过服务端反射回来,这类跨站的代码一般不存储到服务端。
2.存储型XSS: 存储型XSS,它和反射型XSS最大的不同就是,攻击脚本将被永久地存放在目标服务器的数据库和文件中。通常是因为服务器端将用户输入的恶意脚本没有经过验证就存储在数据库中,并且通过调用数据库的方式,将数据呈现在浏览器上。
3.DOM型XSS:一种基于DOM的跨站,这是客户端脚本自身解析不正确导致的安全问题
反射性XSS:
- 用户正常登录
- 攻击者向客户发送恶意的url
- 客户使用浏览器访问恶意的url
- 服务端对攻击者的js做出回应
- 攻击中的js代码进行执行
- 用户的浏览器向攻击者发送会话令牌
- 攻击者劫持会话用户
存储型XSS:
- 用户正常浏览服务器的信息
- 通过发帖向服务器发送包含恶意代码的帖子
- 用户向服务器请求帖子的内容
- 服务器返回了包含恶意代码的帖子
- 客户端服务器执行了恶意的代码
DOM型XSS
与反射型 XSS 、存储型 XSS 的区别就在于 xss 代码并不需要服务器解析响应的直接参与,触发XSS 靠的是浏览器端的DOM解析
XSS的防范措施
对用户提交内容进行合法性校 验对用户提交内容进行转义处理对用户输入的长度进行限制限制Cookie到期时间对输出数据使用HtmlEncoder对一些字符做转义处理
CSRF跨站请求伪造
服务器收到攻击者伪造的来自浏览器的请求并执行
跟跨站脚本(XSS)相比,XSS利用的是用户浏览器对网站的信任,CSRF利用的是网站对用户浏览器的信任。
要完成CSRF攻击需要的条件
1.账号不能登出
2.双方需要使用同样的浏览器
攻击流程• 攻击者发现XSS漏洞——构造代码——发送给受害人——受害人打开——攻击者获取受害人的cookie——完成攻击• 攻击者发现CSRF漏洞——构造代码——发送给受害人——受害人打开—— 受害人执行代码 ——完成攻击
• XSS容易发现,因为攻击者需要登录后台完成攻击,管理员可以看日志发现攻击者。• CSRF则不同,他的攻击一直是管理员自己实现的,攻击者只负责了构造代码
CSRF防护
HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的request.getHeader("REFERER");通过检查Referer的值,我们就可以判断这个请求是合法的还是非法的,那么Refere Check 可以用于监控CSRF攻击的发生
文件上传漏洞
非法文件上传产生的主要原因就是在服务器端没有对用户上传的文件类型做校验或者校验不完整,导致用户可以上传恶意脚本到服务器可利用该缺陷上传 Webshell 、病毒及其他恶意代码能够进行进一步提权,获取数据库信息(拖库)甚至那倒服务器权限
文件上传防护
路径遍历-任意文件下载
服务器端,接收浏览器传来的文件名称,在服务器端拼凑成文件的绝对路径,并且用输出流下载
String path = request.getParameter("path");
java.io.OutputStream os = response.getOutputStream();
java.io.FileInputStream fis = new java.io.FileInputStream(path);
byte[] b = new byte[1024];
int i = 0;
while ((i = fis.read(b)) > 0 ){
os.write(b, 0, i);
}
fis.close();
os.flush();
os.close();
构造攻击载荷
../../../../../../../etc/passwd
路径遍历防护
1、要下载的文件地址保存至数据库中。2、文件ID使用随机数命名3、文件路径保存至数据库,用户提交文件对应ID下载文件。4、下载文件之前做权限判断。5、记录文件下载日志
针对文件的访问,直接给出文件路径的链接。如:<a href= “http://xx.xx.xx.xx/upload/file1.jpg”>
broken Authentication 失效的身份认证
1.用户身份验证凭证没有使用哈希或加密保护;2.认证凭证可猜测;3.SessionId暴露在URL里;4.SessionId没有超时限制;5.密码、会话ID和其他认证凭据使用未加密连接传输
认证信息未加密:
密码信息明文传输、密码信息明文存储
会话管理:
会话更新:
会话标识信息在认证前后是否进行了更新操作。会话存放:会话标识信息是否存放在了URL链接或页面信息等不安全的地方。会话销毁:会话使用完毕或权限注销后是否进行会话终止及销毁操作。
失效的访问控制
网站权限是指系统设置的某种安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源。
越权攻击是指攻击者通过技术手段,查看或使用了非自己权限下的功能或信息。
未授权攻击
未授权查看攻击者在未登录状态下, 通过特定链接地址,查看到他人用户信息未授权功能使用攻击者在未登录状态下, 通过特定链接地址,使用特定用户或系统功能
越权
垂直越权漏洞 ,也称权限提升漏洞,由于Web应用程序没有做权限控制或者仅在菜单上做了权限控制,导致的恶意用户只要猜测其他管理页面的URL,就可以访问或控制其他角色拥有的数据或页面,达到权限提升目的攻击者使用 低权限 账户,查看或使用到了 高权限 账号才能使用的信息和功能水平越权漏洞 ,Web应用程序接收到用户请求,修改某条数据时,没有判断数据的所属人,或判断数据所属人时,从用户提交的request参数(用户可控数据)中,获取了数据所属人id,导致恶意攻击者可以通过变换数据ID,或变换所属人id,修改不属于自己的数据。恶意用户可以删除或修改其他人数据攻击者使用有特定权限账户,访问或使用到了 同级别 其他用户的模块功能
越权漏洞防护
垂直越权漏洞: 在调用功能之前,验证当前用户身份是否有权限调用相关功能(推荐使用过滤器,进行统一权限验证)水平越权漏洞: 在用户进行操作时,从session中获取用户id,将传入的参数与用户的身份做绑定校验。
Java反序列化漏洞
序列化:ObjectOutputStream类 --> writeObject()
该方法对参数指定的 obj 对象进行序列化,把字节序列写到 一个目标输出流中,按 Java 的标准约定是给文件一个 .ser 扩展名1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;2) 通过对象输出流的writeObject()方法写对象。反序列化: ObjectInputStream类 --> readObject()该方法从一个源输入流中读取字节序列,再把它们反序列化 为一个对象,并将其返回1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;2) 通过对象输入流的readObject()方法读取对象
攻击者可以进行恶意的构造,让反序列化产生非预期的对象,非预期的对象在产生过程中就可能带来任意代码执行。