草庐IT

Java代码审计项目-某在线教育开源系统

smworld 2023-03-28 原文

环境部署

  1. 下载源代码,使用IDEA进行部署,项目pom.xml进行maven依赖包添加、配置数据库账号密码、配置开启端口后即可使用tomcat7插件运行项目。
  2. 搭建过程遇见两个坑点:
mysql建议直接使用5.5.*版本的,高版本的会因为mysql的默认配置需要额外配置而遇见各种问题,虽然最后都能搭建成功,但是直接使用低版本的就无需额外配置。

项目路径建议直接使用 http://IP:port 形式,后面不要配置额外的路径,加入额外项目配置后虽然可以部署成功,但是会导致一些页面或者图片加载不成功。

  1. 进行代码审计时,记得需要额外把\src\main\webapp\WEB-INF\lib\目录下的jar包反编译后再进行代码审计,因为使用IDEA进行源码关键字搜索时不会搜索jar包中的代码,我审计之前就没有注意到项目下的这个目录,导致前面审计过程中某些功能找不到源代码。

项目结构分析

这是一个SSM(即Spring Framework、Spring MVC、MyBatis)架构项目。

百科是这样介绍的:

  • pom.xml:审计maven项目首先应该查看pom.xm,通过查看此文件可以知道项目用了哪些组件及组件版本,这样可以快速查看组件对应的版本是否有漏洞。
观察到项目使用了log4j 且版本为1.2.17,此版本存在反序列化漏洞CVE-2019-17571(经过分析,不存在此漏洞,因为本项目未使用产生此漏洞的类即SocketNode类)。

还使用了druid 1.0.1 组件,可以找一些未授权接口(经过测试未发现此组件产生的未授权)。

mybatis 3.2.7 组件存在反序列化漏洞CVE-2020-26945(经过分析,不存在此漏洞,因为此项目未开启mybatis二级缓存功能)。

  • web.xml:程序启动时会先加载这个文件,此文件用来配置Filter、Listener、Servlet。此文件需要重点关注Filter过滤器的全局配置。此项目只配置了两个全局的过滤器且这两个过滤器都未对输入输出进行转义之类的字符处理,所以未配置全局的XSS过滤。

  • applicationContext.xml: spring的默认配置文件,当容器启动时找不到其他指定配置文档时,将加载这个配置文件,此文件也包含引用其他的配置文件。

  • spring-mvc.xml:此文件主要的工作是:启动注解、扫描controller包注解;静态资源映射;视图解析(defaultViewResolver);文件上传(multipartResolver);返回消息json配置。
  • web项目启动时,读取web.xml配置文件,首先解析的是applicationContext.xml文件,其次才是sping-mvc.xml文件。
  • Interceptor:拦截器,用于拦截用户请求并进行相应的处理。比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那样子判断当前时间是否是购票时间。此项目有3个拦截器,分别对前台用户、后台用户、网站配置管理处的用户是否登录与权限做相应处理。

代码审计

前台找回密码处验证码重复利用

直接在代码中搜索关键字验证码,对相关代码进行分析。

此处是找回密码功能,先后获取客户端与服务端验证码进行校验,校验成功后进入校验邮箱是否注册,若未注册则直接返回结果,未删除服务端中的旧验证码,所以此处可对验证码重复使用来爆破出已经注册的邮箱。

继续分析可知,邮箱存在且重置密码之后才清除服务端中的验证码。因为前台登录处无验证码,所以此处可配合登录处继续密码爆破。

但是经过分析,后台管理员登录处就不存在验证码重复利用,因为验证码校验正确后就会立马进行清除。

XSS

开头已经分析未发现全局的XSS过滤器,所以直接注册账号进行登录,见框就插入XSS payload。

在问答功能下的我要提问功能处发现存储型XSS。

此处只有标题有XSS而内容无XSS,找到对应的入口进行分析原因,questionsService.addQuestions()为添加问答方法,追踪此方法

QuestionsController-->QuestionsService-->QuestionsServiceImpl-->QuestionsDao-->QuestionsDaoImpl-->QuestionsMapper

根据追踪过程分析未做字符过滤就直接保存到数据库中。并且标题和内容都保存数据库中。

由此可知,存储过程标题和内容未做差异化处理,说明在输出的时候对内容进行了过滤,继续分析输出部分。由以上可知,存在XSS的url为http://127.0.0.1:8080/question/list。

直接在*.jsp文件中搜索question/list找到对应的输出点。很明显标题处是直接拼接数据库中的值并未使用标签包裹,而内容处则使用了<c:out>标签。在jsp文件中,使用<c:out>标签是直接对代码进行输出而不当成js代码执行。

自此,产生XSS的来龙去脉都已经知道了,所以输出变量时,没有使用<c:out>标签进行防护的都会产生XSS,经分析其他还有多处有XSS。

SQL注入

因为使用的时mybatis框架,所以直接在*Mapper.xml文件中搜索${即可。

发现存在多处使用${}进行拼接的地方,选择一处进行分析

找到对应的controller层入口。此处为后台管理员用户删除文章功能处。

抓取请求包直接使用sqlmap爆破即可。

其他还有几处也存在sql注入。类似分析即可。有几处因为是直接拼接路径中的字符作为参数的,所以这种情况即使使用${}也不会造成sql注入。

前台用户横向越权

在用户修改个人资料时,直接抓包修改 user.userId参数值即可越权登录到其他存在的用户。

分析代码可知,未对用户进行判断就直接把用户信息更新到数据库中,更新数据库中后直接使用userid进行自动重新登录从而可导致直接登录其他用户界面。

CSRF

后台管理员创建用户处存在CSRF漏洞,攻击者可结合此系统的XSS漏洞构造恶意代码从而导致创建系统管理员用户。

可用burpsuite自带的CSRF工具生成payload进行测试。

从代码处可知,未对请求体校验Referer字段,也无token机制。因此可造成CSRF。

前台文件上传getshell

前置知识点

jspx:以xml语法来书写jsp的文件,自定义的映射类型,jspx=jsp+xml;jspx文件本身符合xml的规范,但是它本质又是一个jsp文件,所以在所有jsp里面能够做到的事情在jspx里同样可以做到。

tomcat的web.xml中org.apache.jasper.servlet.Jspservlet配置关于jsp服务的解析,默认是都会解析jsp和jspx。

此处漏洞发生在前台用户上传头像处。

直接找到源代码进行分析,源码在\src\main\webapp\WEB-INF\lib\inxedu-jar.jar包中。

此处的fileType即为前端传入的文件类型后缀,分析代码可知,此处只过滤了jsp文件其他文件可随意上传,可以上传html文件造成XSS漏洞,由于此项目使用tomcat,所以可以上传jspx文件getshell。

使用哥斯拉工具生成jspx木马上传文件,上传成功。

连接成功。

有关Java代码审计项目-某在线教育开源系统的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  4. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  7. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  8. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  9. Ruby 从大范围中获取第 n 个项目 - 2

    假设我有这个范围:("aaaaa".."zzzzz")如何在不事先/每次生成整个项目的情况下从范围中获取第N个项目? 最佳答案 一种快速简便的方法:("aaaaa".."zzzzz").first(42).last#==>"aaabp"如果出于某种原因你不得不一遍又一遍地这样做,或者如果你需要避免为前N个元素构建中间数组,你可以这样写:moduleEnumerabledefskip(n)returnto_enum:skip,nunlessblock_given?each_with_indexdo|item,index|yieldit

  10. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

随机推荐