文章来源:奇安信攻防社区(苏苏的五彩棒)
原文地址:https://forum.butian.net/share/942
可能存在漏洞:密码硬编码、密码明文存储、弱口令、密码强度策略问题
关键字:password、pass、jdbc、密码
操作:使用代码编辑器的全局搜索功能搜索相应关键字,然后查看代码是否存在漏洞。
实战:成功找到一个数据库的弱口令、一个密码强度策略问题
XSS分为反射型XSS、存储型XSS、DOM型XSS
关键字:getParameter
操作:反射型XSS漏洞通过外部输入,然后直接在浏览器触发,简单来说反射型xss的执行过程 前端—>后端—>前端。在白盒审计的过程中,我们需要寻找带有参数的输出方法,然后根据输出方法对输出内容回溯输入参数。
实战:下图就是一个典型的反射型XSS案例,randCode是从HttpServletRequest中直接获取的,然后代码中没有对输入输出进行过滤、干扰或编码,导致了反射型XSS漏洞的产生。
关键字:">${
操作:在挖掘存储型XSS的时候,要统一寻找“输入点”和“输出点”,可以考虑使用以下方式提高效率,(1)黑白盒结合。(2)通过功能、接口名、表名、字段名等角度做搜索。
输入输出点:
输入点 输出点
document.Url evaldocument. location document.write
document.referer document.InnterHTML
document. form document.OuterHTML
操作:DOM型XSS漏洞不需要与服务器交互,它只发生在客户端处理数据阶段。所以只需要查看是否有不可控的数据经过输入点输入,然后未经过滤或者编码就被输出。
关键字:Statement
操作:JDBC有两种方法执行SQL语句,分别为PrepareStatement和Statement。两个方法的区别在于PrepareStatement会对SQL语句进行预编译,Statement方法在每次执行时都需要编译。大家可能都知道SQL注入的一个防御方法就是使用预编译,但并不意味着使用PrepareStatement 就绝对安全,不会产生SQL注入。
Mybatis框架下”${xxx}”这样格式的参数会直接参与SQL语句的编译,易产生SQL注入漏洞,出现这种情况主要分为以下三种:
如以下SQL查询语句:Select * from article where name like ‘%${title}%’
如以下SQL查询语句:Select * from news where id in (${id})
如以下SQL查询语句:Select * from news where title =‘123’ order by ${time} asc
其实不光PHP,Java中也是存在文件包含漏洞的,JSP的文件包含分为静态包含和动态包含两种。
静态包含:%@include file="test.jsp"%
动态包含:<jsp:include page="<%=file%>"></jsp:include>、<c:import url="<%=url%></c:import>
Java的文件包含只会造成文件读取和文件下载的漏洞。
危险函数:
download
fileName
filePath
write
getFile
getWriter
FileInputStream
操作:寻找未做严格校验的可控路径,可以通过路径对文件进行下载读取操作
危险函数:
File
lastIndexOf
indexOf
FileUpload
getRealPath
getServletPath
getPathInfo
getContentType
equalsIgnoreCase
FileUtils
MultipartFile
MultipartRequestEntity
UploadHandleServlet
FileLoadServlet
FileOutputStream
getInputStream
DiskFileItemFactory
操作:
可以从以下几点寻找任意文件上传漏洞
1、仅前端过滤导致的任意文件上传漏洞
2、后端过滤不严格导致的任意文件上传漏洞
危险函数:
ObjectInputStream.readObject
ObjectInputStream.readUnshared
XMLDecoder.readObject
Yaml.load
XStream.fromXML
ObjectMapper.readValue
JSON.parseObject
危险基础库:
com.mchange:c3p0 0.9.5.2com.mchange:mchange-commons-java 0.2.11commons-beanutils 1.9.2commons-collections 3.1commons-fileupload 1.3.1commons-io 2.4commons-logging 1.2org.apache.commons:commons-collections 4.0org.beanshell:bsh 2.0b5
org.codehaus.groovy:groovy 2.3.9org.slf4j:slf4j-api 1.7.21org.springframework:spring-aop 4.1.4.RELEASE
操作:反序列化操作一般应用在导入模板文件、网络通信、数据传输、日志格式化存储、对象数据落磁盘、或DB存储等业务场景。因此审计过程中重点关注这些功能板块。通过寻找危险函数确定反序列化输入点,然后再考察应用的Class Path中是否包含危险基础库。若包含危险库,则使用ysoserial进行攻击复现。若不包含危险库,则查看一些涉及命令、代码执行的代码区域,防止程序员代码不严谨,导致bug。
危险函数:
javax.xml.parsers.DocumentBuilderFactory;
javax.xml.parsers.SAXParser
javax.xml.transform.TransformerFactory
javax.xml.validation.Validator
javax.xml.validation.SchemaFactory
javax.xml.transform.sax.SAXTransformerFactory
javax.xml.transform.sax.SAXSource
org.xml.sax.XMLReader
DocumentHelper.parseText
DocumentBuilder
org.w3c.dom
org.xml.sax.helpers.XMLReaderFactory
org.dom4j.io.SAXReader
org.jdom.input.SAXBuilder
org.jdom2.input.SAXBuilder
javax.xml.bind.Unmarshaller
javax.xml.xpath.XpathExpression
javax.xml.stream.XMLStreamReader
org.apache.commons.digester3.Digester
rg.xml.sax.SAXParseExceptionpublicId
实战1:
我们可以看到下面的代码使用了危险函数DocumentBuilder(),没有对传参进行过滤限制。
并且SAMLResponse可控,攻击者传入构造好的xml代码,造成XXE漏洞。
实战2:微信支付接口XXE
WXPayUtil下的xmlToMap方法存在XXE漏洞,使用了DocumentBuilder危险函数,直接将传入的字符串转换为了map集合,并且未对字符串进行过滤,导致攻击者可以传入任意的攻击代码。
我们写一个测试方法,调用xmlToMap方法,发现成功读取文件内容。
package com.github.wxpay.sdk;import java.util.Map;public class test { public static void main(String[] args) {
String str = "<?xml version='1.0' encoding='utf-8'?>\r\n"+
"\r\n"+ " ]>\r\n"+
"<creds><goodies>&goodies;</goodies><pa>susu</pa></creds>";
Map<String, String> map; try {
map = new WXPayUtil().xmlToMap(str);
System.out.println(map);
} catch (Exception e) {
e.printStackTrace();
}
}
}
可能有些同学会有疑惑,为什么要嵌套两个元素,如: "<creds><passwd>&goodies;</passwd></creds>";
因为传入的xml语句的元素会被当作map的key,变量会被当成map的value,如果是只嵌套一个元素,如:"<creds>&goodies;</creds>";
转换为map后就变成了{ },因为是获取子节点传入nodeList中,上面的写法没有子节点,所以输出null。
可以看到子节点都被转换为map输出出来。
实战3:solrXXE漏洞(CVE-2017-12629)
出现问题的代码存在于在/solr/src/lucene/queryparser/src/java/org/apache/lucene/queryparser/xml/CoreParser.java文件中
我们可以看到下面的代码使用了危险函数DocumentBuilder(),并且没有对传参进行过滤限制,也未禁用DTD和外部实体,造成了XXE漏洞。
挖掘CSRF漏洞,一般需要首先了解程序的框架。
CSRF漏洞一般会在框架中存在防护方案,所以在审计时,首先要熟悉框架对CSRF的防护方案,若没有防护方案,则存在CSRF漏洞;
若有防护方案,则可以首先去查看增删改请求中是否有token、formtoken、csrf-token 等关键字,若有则可以进一步去通读该Web程序对CSRF的防护源码,来判断其是否存在替换token值为自定义值并重复请求漏洞、重复使用token等漏洞
。此外还要关注源程序是否对请求的Referer进行校验
等。
危险函数:
HttpClient.execute()
HttpClient.executeMethod()
HttpURLConnection.connect()
HttpURLConnection.getInputStream()
URL.openStream()
HttpServletRequest()
BasicHttpEntityEnclosingRequest()
DefaultBHttpClientConnection()
BasicHttpRequest()
操作:程序中发起HTTP请求操作一般在获取远程图片、页面分享收藏等业务场景,在代码审计时可重点关注危险函数。
实战:UeditorSSRF漏洞
代码中的validHost方法对url进行判断,如果不合法,就提示“被阻止的远程主机”;当满足条件后会使用validContentState方法查看返回的状态是否为200,若不为200,则提示“远程连接出错”,如果url无法访问,则提示“抓取远程图片失败”,这就间接造成了SSRF漏洞。
我们在代码中找到captureRemoteData中调用了validHost方法,我们可以看到captureRemoteData中使用了HttpURLConnection。
然后capture方法中调用了captureRemoteData,在invoke中调用了capture方法。
我们进入到invoke中发现,要想调用capture就需要满足条件为actionCode为ActionMap.CATCH_IMAGE,当actionType值为catchimage,即action参数对应为catchimage时,才可能触发SSRF漏洞。
可能有点绕,但简单总结就是ction=catchimage->invoke->capture->captureRemoteData->validHost(SSRF)
。
操作:可以使用一些搜索平台查看应用程序所选的第三方组件是否存在漏洞。
框架相关:S2、shiro、Spring
中间件相关:JBoss、Weblogic、Jenkins
Java库相关:Fastjson、Jackson
第三方编辑器:UEditor、KindEditor、FCKeditor
实战:我们可以在项目的pom.xml中查看
关键字:短信、用户不存在、验证码、邮箱、发送
操作:应用程序中可能存在许多接口用来做一些如发送短信验证码、判断用户是否存在,这些接口功能一旦能够进行重复请求就会造成一些问题漏洞。
实战:
未对短信发送做次数限制导致短信轰炸漏洞
当账号输入错误后,提示“账号不存在”,造成用户名可枚举漏洞
操作:在对一些数据进行增删改查的时候,如果没有鉴权,就会导致越权漏洞,一般越权漏洞需要根据实际的项目流程来寻找挖掘。
实战:下图就是进行删除操作的时候,没有进行鉴权,直接匹配到id就进行了删除。
危险函数:
sendRedirect
getHost
redirect
setHeader
forward
操作:重点寻找危险函数,然后查看是否对重定向地址做有限制。
JAVA代码审计基础(一)
2022-08-20
巧用burp安排某系统
2022-08-19
记一次对学校某系统的黑盒测试到教育SRC
2022-08-18