编译与反编译:
- 使用IntelliJ IDEA反编译Jar包
- 用IJ IDEA将项目打成jar包
JAVA web:
- 分层架构:为了方便清楚包与包之间的业务逻辑关系
- 视图层(View 视图)
- 控制层(Controller、Action 控制层)
- 服务层(Service)
- 业务逻辑层BO(business object)
- 实体层(entity 实体对象、VO(value object) 值对象 、模型层(bean)。
- 持久层(dao- Data Access Object 数据访问层、PO(persistant object) 持久对象)
- 模块化开发:
- Maven
- Gradle
- OSGi ( Open Service Gateway Initiative 可实现模块热部署)
- Servlet 是在Java Web容器上运行的小程序 ,通常我们用 Servlet 来处理一些较为复杂的服务器端的业务逻辑。值得注意的是在 Servlet3.0 之后( Tomcat7+ )可以使用注解方式配置 Servlet 了。
- Servlet3.0 之前的版本都需要在 web.xml 中配置, Servlet 是 两对标签 ,由 <servlet> 和 <servlet-mapping> 组成, Spring MVC框架就是基于Servlet技术 实现的。
- 实现一个 Servlet 很简单,只需要继承 javax.servlet.http.HttpServlet 类并重写 doXXX 方法或者 service 方法
- JSP、Servlet之间的关系
- JSP、JSPX文件是可以直接被Java容器直接解析的动态脚本,jsp和其他脚本语言无异,不但可以用于页面数据展示,也可以用来处理后端业务逻辑。
- 从本质上说JSP就是一个Servlet,因为jsp文件最终会被编译成class文件,而这个Class文件实际上就是一个特殊的Servlet。
- Filter
- Filter是JavaWeb中的过滤器,用于过滤URL请求。通过Filter我们可以实现URL请求资源权限验证、用户登陆检测等功能。
- Filter是一个接口,实现一个Filter只需要重写 init 、 doFilter 、 destroy 方法即可,其中过滤逻辑都在 doFilter 方法中实现。
- Filter和Servlet一样是Java Web中最为核心的部分,使用Servlet和Filter可以实现后端接口开发和权限控制,当然使用Filter机制也可以实现MVC框架, Struts2 实现机制就是使用的Filter。
- Filter的配置类似于Servlet,由 <filter> 和 <filter-mapping> 两组标签组成,如果Servlet版本大于3.0同样可以使用注解的方式配置Filter。
Filter和Servlet代码审计技巧总结:
对于基于 Filter 和 Servlet 实现的简单架构项目,代码审计的重心集中于找出所有的 Filter分析其过滤规则,找出是否有做全局的安全过滤、敏感的URL地址是否有做权限校验并尝试绕过Filter 过滤。第二点则是找出所有的 Servlet ,分析 Servlet 的业务是否存在安全问题,如果存在安全问题是否可以利用?是否有权限访问?利用时是否被Filter过滤?等问题,切勿看到 Servlet 、 JSP 中的漏洞点就妄下定论,不要忘了 Servlet前面很有可能存在一个全局安全过滤的Filter 。
Filter和Servlet技术异同总结:
- Filter和Servlet都需要在web.xml或注解(@WebFilter、@WebServlet)中配置,而且配置方式是非常的相似的。
- Filter和Servlet都可以处理来自Http请求的请求,两者都有request、response对象。
- Filter和Servlet基础概念不一样,Servlet定义是容器端小程序,用于直接处理后端业务逻辑,而Filter的思想则是实现对Java Web请求资源的拦截过滤。
- Filter和Servlet虽然概念上不太一样,但都可以处理Http请求,都可以用来实现MVC控制器( Struts2和Spring框架分别基于Filter和Servlet 技术实现的)。
- 一般来说Filter通常配置在MVC、Servlet和JSP请求 前面,常用于后端 权限控制、统一的Http请求 参数过滤(统一的XSS、SQL注入、Struts2命令执行等攻击检测处理)处理,其核心主要体现在请求 过滤上,而Servlet更多的是用来 处理后端业务请求上。
Sping控制器
Spring Controller注解:
- @Controller
- @RestController
- @RepositoryRestController
Spring MVC请求配置注解:
- @RequestMapping
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
- @PatchMapping
XML配置bean容器(老旧的Spring项目)
<bean name="/test.do" class="org.javaweb.codereview.controller.TestController"/>
Strust2控制器
Struts2主要的开发模式是基于xml配置,在 struts.xml 中配置Action地址和对应的处理类。
不过Struts2( 2.1.6 版本开始)也可以使用 struts2-convention-plugin 插件来实现基于注解方式的配置。
快速找出Http请求请求URL(查找请控制器、查找请求注解)
代码审计中我们可以选择优先从 Controller 、 Servlet 和 JSP 中入手,也可以选择从漏洞点反向推出Http请求的入口地址
IDEA全局搜索:ctrl+shift+F
Find命令查找class文件:
- 查找 请求处理注解: find ~/cms/ -type f -name "*.class" |xargs grep -E "RequestMapping|GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping|RepositoryRestResource"
- 查找 控制器: find ~/cms/ -type f -name "*.class" |xargs grep -E "Controller|@RestController|RepositoryRestController"
问:如何快速找出Http请求的请求url?
答:IDEA全局搜索或者find搜索class文件:三个控制器、七个请求注解(*****Mapping)
JAVA语言的动态性相关技术:
利用这些动态性的技术从而挖出的相关漏洞,危害巨大
- Java反射机制
- MethodHandle(类似于反射,但效率远高于反射)
- JDK动态代理
- 使用JVM上的动态语言(如:Groovy、JRuby、Jython) JVM上居然还有动态语言?
- 表达式库(如:OGNL、MVEL、SpEL、EL)
- JSP 、 JSPX 、 Quercus (Resin容器提供了PHP5支持)
- 字节码库(如:Asm、Javassist、Cglib、BCEL)
- ScriptEngineManager(脚本引擎)。
- 动态编译(如:JDT、JavaCompiler)
- ClassLoader 、 URLClassLoader
- 模版引擎(如: Freemarker 、 Velocity )
- 序列化、反序列化(包含 Java 对象序列化 、 XML 、 JSON 等)
- JNI、JNA(Java调用C/C++)
- OSGi(Open Service Gateway Initiative)
- RMI(Java远程方法调用,基于对象序列化机制实现)
- WebService
- JDWP ( Java Platform Debugger Architecture Java调试协议)
- JMX(Java Management Extensions)
JAVA反射机制: java反射调用漏洞
Java反射机制可以无视类方法、变量访问权限修饰符,可以调用任何类的任意方法、访问并修改成员变量值。也就是说只要发现一处Java反射调用漏洞几乎就可以为所欲为了。当然前提可能需要你能控制反射的类名、方法名和参数。
一行代码即可实现反射调用Runtime执行本地命令:
Runtime.class.getMethod("exec", String.class).invoke(Runtime.class.getMethod("getRuntime").invoke(null), "whoami")
Java反射获取类方法有两种方式:
- getMethod(xxx),getMethods()
- getDeclaredMethod(xxx)、getDeclaredMethods()。
区别在于getMethod会返回当前类和父类的所有public方法,而getDeclaredMethod返回的是当前的所有方法。
Java反射获取类成员变量有两种方式:
- getField(xxx)、getFields()
- getDeclaredField(xxx)、getDeclaredFields()
getField和getDeclaredField区别同上,如果想要调用private修饰的Field或者Method只需要设置下setAccessible为true就可以了,如:xxxMethod.setAccessible(true)。
JDK7+ MethodHandle
JDK7开始Java提供了MethodHandle可以非常方便的访问和调用类方法,MethodHandle的能力和Java反射机制相似,但效率却远高出Java反射机制,但MethodHandle也并不是那么完美的,缺点是MethodHandle必须要求JDK版本大于等于1.7,MethodHandle也无法像反射那样调用私有方法和变量。
JAVA代码审计Checklist
- 业务层安全
- 代码实现
- 服务架构
ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。当前ORM框架主要有五种:Hibernate(Nhibernate),iBATIS,mybatis,EclipseLink,JFinal。
业务层面代码审计Checklist
- 验证码:
- 不过期的验证码导致可爆破
- 第三方API未做请求限制导致轰炸
- 验证码明文传输
- 加密算法:
- 数据传输未加密
- 硬编码或弱加密
- cookie直接明文存储用户名和密码
- 验证码明文传输
- CSRF
- 未采用验证码或Token
- ORM框架(对象持久化到数据库的框架)
- 横向越权(订单遍历,个人信息遍历...)
- 纵向越权(创建管理员用户...)
- 逻辑漏洞
- 找回密码可通过修改返回包绕过旧密码
- 条件竞争(并发支付)
- API
- 第三方API不安全的调用
- 未做请求限制导致轰炸
- 异常处理
- 不安全的异常处理代码,导致爆出数据库信息或绝对路径
代码层面代码审计Checklist
- 任意文件上传、下载、重命名、删除、遍历等
- SQL注入
- XXE(XML实体dtd注入攻击)
- 系统命令执行
- 反序列化攻击(攻击发生在反序列化的过程之中)
- Java反射机制可以无视类方法、变量访问权限修饰符,可以 调用任何类的任意方法、访问并修改成员变量值)
- SSRF(服务器端请求伪造)
- JDK<1.7.40)
- 文件上传、下载、重命名、删除、遍历等
- fileName.indexOf('\u0000')
快速发现任意文件读取漏洞:
- JDK原始的 java.io.FileInputStream 类
- JDK原始的 java.io.RandomAccessFile 类
- Apache Commons IO提供的 org.apache.commons.io.FileUtils 类
- JDK1.7新增的基于NIO非阻塞异步读取文件的java.nio.channels.AsynchronousFileChannel类。
- JDK1.7新增的基于NIO读取文件的java.nio.file.Files类。常用方法如:Files.readAllBytes、Files.readAllLines