常见的Web攻击手段-完
【摘要】 常见的Web攻击手段SQL注入介绍SQL注入,就是在我们执行Sql的时候,拼接了一些不可控的入参,导致执行的sql偏离了我们预期的效果,从而被攻击者所利用。错误代码示例// 错误1 任意拼接sql// 说明:当name值为 1’ or 1=1时,造成注入String sql = “select * from user where name =”+name+" and password="+p...
常见的Web攻击手段
SQL注入
-
介绍
SQL注入,就是在我们执行Sql的时候,拼接了一些不可控的入参,导致执行的sql偏离了我们预期的效果,从而被攻击者所利用。
-
错误代码示例
// 错误1 任意拼接sql // 说明:当name值为 1' or 1=1时,造成注入 String sql = "select * from user where name ="+name+" and password="+password; // 错误2 错误的使用占位符 // 说明:当name值为 1' or 1=1时,造成注入当name值为 1' or 1=1时,造成注入 <Select> select * from user where name =${name} and password=${password} </Select>
-
测试手段
- mybatis关键字排查:
- ${}、PreparedStatement 、Statement 、.execute 、.executeQuery、jdbcTemplate、queryForInt、queryForObject、queryForMap、getConnection
- Hibernate关键字排查:
- .createQuery、createSQLQuery、getHibernateTemplate().find
- IBatis关键字排查:
- ibatis、$
- web页面尝试
- 如果前端未做字符限制,可直接进行输入字符 1’ or 1=1 进行尝试
- 如果前端做了字符限制,可获取接口,通过postman等工具更改参数 1’ or 1=1 进行尝试
- 嗅探工具+爆破工具
- 例如AppScan等Web扫描工具,通过嗅探接口,对接口进行字符篡改,适合大批量测试的场景,不过误报情况会比较多
- mybatis关键字排查:
-
防御措施
- 预编译的正确使用。注意是正确使用,不是说你用了预编译就是安全的,例如PreparedStatement,却使用的是拼接字符串,就不是正确的用法
- 白名单。相比较黑名单会更安全,不过限制也更多
- 黑名单。很容易被绕过,需要成熟的黑名单校验
命令注入漏洞
-
介绍
- 命令注入漏洞实质就是我们在使用一些操作系统命令的方法时,使用或者拼接了不可信的数据,导致服务执行了攻击者的命令。
-
错误代码示例
// 错误 任意拼接不可控的字符 RunTime.getRuntime().exec("cmd.exe /c dir" + dir); // 说明 本意为根据传入的值进行新建文件夹,当dir为 1 & del d:\\home\\dd.txt错误的删除了dd.txt // windows下举例说明 限制&&在cmd中使用 String cmd = "cmd /c Calc.exe && mkdir D:\\aaatest\\aaatest"; // linux举例说明 暂无 todo
-
测试手段
- 关键字搜索
- .eval、.exec、ProcessBuilder
- web页面
- 重点排查文件相关的功能、文件名、路径参数等
- 关键字搜索
-
防御措施
- 不使用外部输入的字符
- 白名单
- 黑名单
XML注入漏洞
-
介绍
- XML作为一种可拓展标记语言,通常可作为数据的存储或传输使用。如果xml可被用户可控,那么读取xml将会变得不安全
-
错误代码示例
// 错误 任意读取可不信数据 String userdata = "<USER role="+ GUESTROLE+ "><name>"+ request.getParameter("name")+ "</name><email>"+ request.getParameter("email")+ "</email></USER>"; // 说明 如何email为构造数据,可造成攻击 String email = user1@a.com</email></USER><USER role="admin_role"><name>lf</name><email>user2@a.com; // 最终效果 本来只能有一个角色,现在多了一个角色 <?xml version="1.0" encoding="UTF-8"?> <USER role="guest_role"> <name>user1</name> <email>user1@a.com</email> </USER> <USER role="admin_role"> <name>lf</name> <email>user2@a.com</email> </USER>
-
测试手段
- 人工
- 定位是否有使用xml进行数据传输,或者是否有构造xml的函数,查看是否可被外界输入控制
- 人工
-
防御措施
- 白名单
- 黑名单
XXE注入
-
介绍
- XXE注入是XML漏洞的一种,主要是因为XML解析器都提供了解析、执行外部实体的功能,导致系统执行了一些系统命令,如读取配置文件,发送请求等
-
错误代码示例
// 错误 直接读取外界传入的xml // xml攻击内容 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE aaa [<!ELEMENT aaa ANY ><!ENTITY bbb SYSTEM "./README.md" >]> <test> <OpenId>oKMoN1jk_mgBJFkIviUsdZ0-FsJk</OpenId> <SvrId>&bbb;</SvrId> </test> // 图示为SAXReader解析 Dom4j等其他同理 解析服务器本地资源 SAXReader reader = new SAXReader(); org.dom4j.Document read = reader.read("test.xml"); org.dom4j.Element rootElement = read.getRootElement(); Iterator<Element> elementIterator = rootElement.elementIterator(); while(elementIterator.hasNext()) { Element next = elementIterator.next(); System.out.println("next.getText() = " + next.getText()); } // 访问外部资源 <!ENTITY % dtd SYSTEM "http://localhost:88/evil.xml"> // 执行命令 <!ENTITY xxe SYSTEM "expect://ifconfig" >]>
-
测试手段
- 主要就是查看是否有解析xml的功能,然后判断xml是否可信,不可信是否有进行DTD禁止
- SAXReader
- DocumentHelper
- XpathExpression
- SchemaFactory
- DocumentBuilderFactoryImpl
- DocumentBuilderImpl
- SAXParserFactoryImpl
- SAXParserImpl
- DOMParser
- DOMParserImpl
- SAXParser
- XMLParser
- SAXTransformerFactory
- TransformerFactory
- Validator
- DocumentBuilderFactory
- SAXReader
- XMLInputFactory
- SAXBuilder
- SAXParserFactory
- SAXParser
- XMLReader
- 主要就是查看是否有解析xml的功能,然后判断xml是否可信,不可信是否有进行DTD禁止
-
防御措施
- 不使用外部不可信数据
- 禁止DTD解析
- 白名单
XPath注入漏洞
-
介绍
- XPath注入漏洞也是XML漏洞的一种,Xpath是XML的路径语言,可以用来对xml进行各种解析遍历和查询。类似于sql对数据库的查询
-
错误代码示例
// 错误 任意使用外部传入的变量作为xpath查询参数 // 目标xml文件 <?xml version="1.0" encoding="UTF-8"?> <users> <user> <firstname>Ben</firstname> <lastname>Elmore</lastname> <loginID>abc</loginID> <password>test123</password> </user> <user> <firstname>Shlomy</firstname> <lastname>Gantz</lastname> <loginID>xyz</loginID> <password>123test</password> </user> </users> // 测试方法============================================================== // 解析目标xml DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("test2.xml"); // 使用xpath路径语言 XPathFactory xPathFactory = XPathFactory.newInstance(); XPath xPath = xPathFactory.newXPath(); // 正常的输入情况 // String loginID = "abc"; // String password = "test123"; // 构造的输入情况 String loginID = "' or 1=1 or ''='"; String password = "' or 1=1 or ''='"; // 选取所有users元素不管在哪里,并选择符合表达的user子元素,在输出符合的firstname子元素的文本内容 XPathExpression expression = xPath.compile("//users/user" + "[loginID/text()='" + loginID + "' and password/text()='" + password + "']/firstname/text()"); // 根据路径表达式进行寻找并返回所有结果 NodeList nodeList = (NodeList) expression.evaluate(doc, XPathConstants.NODESET); for (int i = 0; i < nodeList.getLength(); i++) { System.out.println("value ====" + nodeList.item(i).getNodeValue()); }
-
测试手段
- 主要检测是否有使用xpath语言即可,使用了的话,判断输入是否可信
- xpath关键字
-
防御措施
- 不使用外部参数
- 白名单
- 黑名单
XSS漏洞
-
介绍
- XSS(Cross Site Scripting)跨站脚本攻击,攻击的目标为用户客户端,用户在浏览网页时,xss在本地执行,造成用户信息泄露,破坏页面,流量劫持,dos攻击等等
- xss主要分为:反射型、存储型、DOM型
-
错误代码示例
// 错误 示例 <img src=1 onerror=alert(1)/>
-
测试手段
-
web漏洞扫描工具:由于xss的发生场景较多,每一个接口都可能发生,url页面也可能,在此情况下,导致测试xss很难,所以一般可以使用 Appscan等web漏洞扫描工具进行协助,缺点就是可能误报较多
-
后端直接输出页面:PrintWriter、getOutputStream
-
JSP代码片段中<% jsp片段%>
-
JSP代码片段中${EL表达式} #变量
-
前端代码排查:太多…
- location.search - location.hash - location.href - ducument.URL - document.URLUnencoded - document.referer - document.write() - document.writeln() - .innerHTML= - .outerHTML= - .html() - eval() - execScript() - setTimeout() - Function() <script> <img> <input> <details> <svg> <select> <iframe> <video> <audio> <body> <table> <a> <form> <button> <p> <textarea> <keygen> <marquee> 等等...
-
-
防御措施
- 编码过滤、替换
- 白名单
- 黑名单
资源耗尽
-
介绍
- 资源耗尽主要针对当使用服务功能时,由于功能过于消耗服务器资源,如cpu,内存,磁盘,线程等一切会影响到其他正常用户的资源,导致服务无法被正常访问。
- 正则Redos
- 上传、下载文件
- XML注入
- xss攻击
- 反序列化漏洞
- IO流资源泄露
- 集合类使用不当
- 单例类
-
错误代码示例
// 错误 不同情况,错误不同,这里举例一个Redos例子 // 自我重复的正则 String input = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaX" Pattern pattern = Pattern.matches("^(a+)+$", input)
-
测试手段
- 正则redos
- 查看正则是否由用户自己定制
- 查看自我重复,复杂表达式,部分包含重复等等
- 使用工具进行检测RegexFuzzer
- 上传、下载文件
- 存在解压场景,zip高压缩文件,压缩层级过深,路径覆盖,内涵文件等
- 文件大小、数量、格式,路径校验
- 上传生成临时文件未删除
- 越权上传/下载文件
- 上传频率
- XML注入
- 针对引入外部实体
- 循环引用执行等问题
- IO流未关闭
- 直接未关闭
- 异常导致的未关闭
- 集合类使用不当
- 集合有增无减(静态、hashmap、hashset使用对象作为key,变更后无法删除等情况)
- 接受外部数据,未校验大小
- 单例类使用不当
- 单例为集合或者存在集合变量时,大量数据的涌入,类似于上面集合类的静态情况
- XSSFWorkbook解析xlsx文件
- XSSFWorkbook在解析行数较多的excel文件时,会耗时较长,长时间占用资源
- 反序列化漏洞
- 针对用户可控制反序列化内容的情况,造成循环引用或者数据量较大的情况
- 正则redos
-
防御措施
- 正则redos
- 字符长度限制:很多正则都是由于检索次数过多导致,长度可以极大的限制构造攻击字符
- 正则要符合规范,不能重复,太过复杂,部分包含重复等情况
- 工具配合检查
- 上传、下载文件
- 解压场景:要对zip解压后的大小,层级,路径做校验
- ZipINputStream、ZipEntry、TarInputStream、GZIPInputStream关键字匹配
- 普通文件上传需要对大小、数量、格式、路径进行基础校验
- multipartFile.getSize()大小校验不能使用content-length
- fileName.lastIndexOf(".")取最后的后缀名 不能取contentType
- 黑名单绕过需要格外注意,例如大小写的比较问题,png和PNg效果一样
- 路径标准化处理File.getCanonicalPath(注意\u0000、0x00绕过)。一般可以直接重命名保存,不使用原生名字。
- 需要对权限进行校验
- 耗资源的上传下载接口需要对频率或者流量进行降级处理
- 解压场景:要对zip解压后的大小,层级,路径做校验
- XML注入
- 白名单校验
- 禁止DTD场景
- IO流未关闭
- 排查关键字inputstream、outputstream、reader、writer
- 异常未关闭,try-with-resoures写法
- 集合类使用不当
- 静态集合排查
- 对象作为key或者hashset等类排查
- 外部应用数据大小校验
- 单例类使用不当
- 排查单例类是否有增无减
- XSSFWorkbook解析xlxs文件
- 排查关键字XSSFWorkbook
- 校验excel文件大小
- 反序列化漏洞
- 排查反序列化场景JAVA、XML、JSON、YAML等常见场景
- 正则redos
反序列化漏洞
-
介绍
- 反序列化本身没有问题,主要针对用户可控制反序列化内容时会产生漏洞,一般数据转换为类对象时触发,有JDK自带的,json的,xml的,yaml的
-
错误代码示例
// 错误1 JAVA原生方式 // 如果url.bin的值为客户端可控制,则反序列化可能会执行恶意代码 ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("url.bin")); inputStream.readObject(); // 反序列化的核心 重写了readObject方法,包括自己构造的类,第三方引入的类等 private void readObject(ObjectInputstream inputstream); // 反序列化的测试步骤 // 开头-自动触发,可以是静态代码块,构造方法,这是被反序列化的最外层 HashMap // 中间-进行转换,将自动触发和可执行任意代码 两个类结合起来的一系列转换 hashMap.put // 结尾-任意代码执行处,通过前面一系列类结合,达到该类的任意代码执行 URL // 错误2 fastjson方式 // 需要注意 新版本默认关闭了该反序列化 System.out.println(JSON.parseObject("{\"@type\":\"com.test$JsonResponse\",\"code\":\"1\"}"));
-
测试手段
- JAVA原生,
- readObject(),defaultReadObject(),readUnshared(),readExteralObject()方法
- json
- parseObject()、parse()、ObjectMapper.readValue、@JsonTypeInfo方法排查
- XML
- XMLDecoder.readObject()和XStream.fromXml()排查
- YAML
- YamlBeans和SnakeYaml排查read()和load()方法
- JAVA原生,
-
防御措施
- JAVA原生
- 最好是不直接使用客户端的值进行反序列化
- json
- 最好不开启autoType支持,以及不使用外部不可信数据反序列化
- XML
- 同上,最好不直接使用外部不可信数据
- YAML
- 同上,最好不直接使用外部不可信数据
- JAVA原生
CSV注入漏洞
-
介绍
- csv注入漏洞主要作用于导出表格的场景,以excel和csv文件为主,这类文件往往内置系统函数,可执行客户端命令,类似于xss,直接作用于客户端,达到信息泄露等
-
错误代码示例
// 错误 直接使用不可信数据进行导出 CSVWriter writer = new CSVWriter(new FileWriter("file_path")); writer.writeAll(dataList); // 排查是否存在漏洞 =cmd|' /C calc'!A0 +cmd|' /C calc'!A0 -cmd|' /C calc'!A0 @ABS(cmd|' /C calc'!A0)
-
测试手段
- 主要检测系统是否存在导出表格功能
- 存在则需要表格的数据进行判断,是否由外部输入控制,是否有进行数据校验
- 需要注意的事项
- 由于这个问题已经出现很久了,DDE动态数据交换。微软已经进行了加固,旧版2016前可以出发,新版本不再能触发,且不允许开启DDE功能。所以使用最新版本的excel可能不会触发csv,条件允许的情况下,使用旧版的excel最好,条件不允许的话,就没办法了,靠经验吧。
- 主要检测系统是否存在导出表格功能
-
防御措施
- 设置单元格格式为文本格式-推荐
- csv的触发条件主要为单元格格式默认是“常规”,如果为文本则不会触发函数
- 前面拼接单引号(’)-存在绕过风险
- 拼接单引号则告诉excel此处为文本,不过可能存在绕过风险,使用分号;同样excel新版本并不会触发,旧版本可能触发
- 过滤开头字符-存在绕过风险
- csv的注入漏洞,主要是以=、+、-、@开头的话会触发函数,所以直接检查是否已这些特殊字符开头,并进行过滤替换处理。不给过可能存在绕过风险,可能前面存在 空格(%0A)Tab(0x09 ) 换行( 0x0D )等情况绕过开头字符检测。同样excel新版本不会触发,旧版会触发
- 设置单元格格式为文本格式-推荐
CRLF注入
介绍
- CRLF(回车换行注入)主要针对日志打印的注入。通过在日志记录的时,伪造或插入无效的日志造成的攻击,对日志审计造成困难,或者将HTTP消息头注入恶意换行,造成xss漏洞等
错误代码示例
// 错误 直接记录日志
LOG.info("user name is " + username);
测试手段
- 关键字
- .info .error .debug .info .warn .debug
防御措施
-
框架配置
- 由于日志记录很多,也不可能一个一个排查,框架配置就很方便。以log4j举例 %enc{CRLF}
<!--使用%enc{%m}{CRLF} 过滤,不过这个由于统一过滤,所以对于本身需要换行的地方,或者一些系统本身打印的日志,换行会被替换掉。好处就是不用一个一个检查--> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} [%t] %-5p %c{1}:%L - %enc{%msg}{CRLF} %n" /> <!--拓展,有一些提供页面html查看日志,%enc{%m}{HTML}过滤xss-->
-
记录日志单独过滤
- 日志记录前过滤\r、\n特殊字符
SSRF漏洞
-
介绍
- SSRF(服务端请求伪造)主要指的是,客户端向服务端发送了一个url地址,服务端对该url地址发送请求,例如获取一张图片信息,获取一个资源。服务端伪造需要体现在,某些主机客户端无法直接请求,例如和服务端在同一区域内的其他服务端,这样就通过服务端访问到其他的服务器,达到服务端请求伪造。
-
错误代码示例
// 错误 服务端直接请求地址, 设URL为客户端直接传入 URLConnectioni con = url.openConnection();
-
测试手段
- 关键字排查
- HttpClient、Request、HttpURLConnection、okhttp、URLConnection、URL等关键字,查看发送的请求地址是否可由客户端控制
- 关键字排查
-
防御措施
- 不使用客户端数据或者部分使用
- 严格控制url地址,不使用或者只使用部分。需要注意的是,拼接时要注意特殊编码,特殊字符绕过等
- 白名单控制
- 主要限制可访问的地址范围,但是通常限制较大,难以满足客户的要求
- 黑名单控制
- 限制部分不可访问的地址,但是名单难以完全,可能会存在遗漏
- 不使用客户端数据或者部分使用
不安全重定向漏洞
-
介绍
- 不安全重定向主要针对服务存在需要进行页面跳转的场景,而跳转目标的地址如果可被用户控制,则很容易造成钓鱼,信息泄露等安全问题。
-
错误代码示例
// 错误 直接使用客户传入的地址进行跳转 String url = "http://www.baidu.com" response.sendRedirect(url);
-
测试手段
- 前端场景排查
- 登录跳转、详情跳转、分享跳转等
- 后端排查
- sendRedirect,redirect关键字,查看url是否可被客户端控制
- 前端场景排查
-
防御措施
- 白名单
- 比较明确的,就限制url地址,例如登录跳转。
- 白名单
文件上传漏洞
-
介绍
- 文件上传虽然简单,但是往往可能会存在各种设计缺陷还有开发缺陷,这些缺陷都会被利用,造成跨目录文件覆盖,资源耗尽,信息泄露,任意命令执行等等。
-
错误代码示例
// 错误1 直接上传文件未对文件大小进行限制 pubilc void upload(MultipartFile multipartFile) { saveFile(mutipartFile); } // 错误2 直接保存使用外部提供的文件名进行保存 File file = new File(path, fileName)
-
测试手段
- 关键字排查:
- outputStream,FileoutputStream,bufferedoutputStream,Writer,multipartFile输出流和文件流
- 大小校验
- 上传超大文件,根据上传时间响应时间进行判断是否合理,不合理查看是否有限流限制
- 格式类型校验
- 上传脚本文件.py、.jsp、.sh等。如何可以,可能存在脚本攻击等问题
- 上传限制以外的文件,如头像是否可以上传txt文本文件。附件上传限制以外的文件
- 路径校验
- 查看路径是否拼接文件名,或直接使用前端传入的文件。关键词new File(path);
- 上传压缩文件校验
- 查看是否有解压场景:关键字排查ZipINputStream,ZipEntry,TarInputStram,GZIPInputstream
- 压缩文件数量校验-构造大量文件或深度较深压缩包
- 压缩文件大小校验-构造zip炸弹
- 解压路径校验-构造跨目录文件
- 查看是否有解压场景:关键字排查ZipINputStream,ZipEntry,TarInputStram,GZIPInputstream
- 关键字排查:
-
防御措施
- 大小校验
- springboot框架,如springmvc提供的配置项spring.servlet.multipart.max-file-size
- 其他第三方开源框架。
- 自行校验,使用multipartFile.getSize()。不能使用content-length
- 格式校验
- 第三方开源框架校验
- 自行校验,fileName.substring(fileName.lastIndexOf(".")+1),取最后一个点名,不能使用file.getContentType
- 路径校验
- 不使用客户端提供的文件信息,自己生成文件名和路径进行存储
- 自行路径校验,使用File.getCanonicalPath()标准化处理,不能使用File.getAbsolutePath()进行校验,容易绕过,跨目录的情况
- 压缩文件校验-存在解压使用场景
- 第三方开源框架校验压缩文件
- 使用ZipInputStream获取解压文件,需要注意的是。要注意压缩包中还有压缩包的场景,需要嵌套解压,发现超过一定数量的文件或超过了预定的大小就应该及时结束校验。同时解压的过程中,也需要依次对文件的解压路径进行校验。
- 大小校验
文件下载漏洞
-
介绍
- 文件下载主要针对下载时的文件权限问题,主要是越权问题,跨目录等问题。
-
错误代码示例
// 错误 直接使用客户端传入的名字或者id拼接路径下载 String fileName= "../../txt.txt"; File file = new File(path+fileName)
-
测试手段
- 关键字排查
- OutputStream,FileOutputStream,OutputStream,Writer等IO输出流
- 目录拼接排查
- 查看下载文件时,是否直接使用外部传入的字符进行拼接
- 权限排查
- 查看下载是否符合预期权限,任意下载等情况
- 关键字排查
-
防御措施
- 使用文件服务器
- 如果文件存在服务部署的服务器上,容易导致各种目录攻击,还有dos攻击,直接使用文件服务器能减少很多问题。
- 使用id进行下载
- 不直接进行目录下载,通过id的方式进行下载,不使用外部的参数作为变量
- 权限校验
- 合理的校验文件下载,做好权限隔离
- 使用文件服务器
ps:本来发了一遍关于xss的实际演示,从发现注入点,到反向的字符注入过程,到结果实现,不过文章不让通过我就没办法了。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)