雷石|对用友NC任意文件读取漏洞的分析

admin 2024年1月19日15:59:28评论63 views字数 3002阅读10分0秒阅读模式

雷石|对用友NC任意文件读取漏洞的分析

     最近看到⼀些漏洞资讯越来越离谱,⼀些错误的信息竟可以互相转发却⽆⼈察觉,今天就分析⼀下漏洞。

⽤友NC-word.docx任意⽂件读取?你确定吗?

     起始时看到漏洞⽂章,所有公众号都在发该接⼝的存在任意⽂件读取,但清⼀⾊给出的poc都是读取web.xml

雷石|对用友NC任意文件读取漏洞的分析

     看到漏洞正好有环境当然要复现下,但复现过程中发现了不对劲,对其展开了⼀番研究。

漏洞复现

     ⾸先看⽹上给的POC:

http://127.0.0.1/portal/docctr/open/word.docx?disp=/WEB-INF/web.xml

     看起来似乎没有没问题,试了⼀下确实"读"到了⽂件,但试了不能穿越⽬录。

雷石|对用友NC任意文件读取漏洞的分析

     那么再试试该其他⽂件,先查看下该⽬录下有什么⽂件。

雷石|对用友NC任意文件读取漏洞的分析

     试⼀下index.jsp,显示了html代码,jsp解析了,这样⽂件"读取"有点奇怪啊。

雷石|对用友NC任意文件读取漏洞的分析

漏洞分析:

     从代码下⼿,发现了⼤问题。

     关键代码如下:

packagenc.uap.lfw.file.action; importjava.io.IOException; importjavax.servlet.RequestDispatcher; importjavax.servlet.ServletException; importjavax.servlet.ServletRequest; importjavax.servlet.ServletResponse; importjavax.servlet.http.HttpServlet; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importorg.apache.commons.lang.StringUtils; public class DocServlet extends HttpServlet {  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {  String url = req.getParameter("disp");  if (StringUtils.isEmpty(url)) //判断url是否为空 return;  if (url.toLowerCase().startsWith("/portal")) //字符转⼩写,并字符串检查开头 url = url.substring(7); //第7个字符开始提取⼦字符串 if (StringUtils.isEmpty(url))  return;  if (url.toLowerCase().startsWith("/docctr/open/office"))  return;  byte[] byte1 = url.getBytes("ISO-8859-1");  url = new String(byte1, "UTF-8");  RequestDispatcher dispatcher =req.getSession().getServletContext().getRequestDispatcher(url);  dispatcher.forward((ServletRequest)req, (ServletResponse)resp);  }  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throwsServletException, IOException {  doGet(req, resp);  } }

     ⾸先⼤概看⼀眼代码,并没有⽤于⽂件操作或IO流的包和函数。

     阅读如上代码,从接收参数disp后,先是⼏次判读是否为空和字符串开头,条件为真直接结束,否则往下执⾏。

     ⽽关键代码是

req.getSession().getServletContext().getRequestDispatcher(url);

getRequestDispatcher()是请求转发,前后页⾯共享⼀个request ; 这个是在服务端运⾏的,对浏览器来说是透明的.

     很明显这绝不是⼀个⽂件读取的漏洞,⽽是请求转发造成的漏洞,访问⼀个URL会将请求转发到另⼀个URL,访问jsp⽂件能够解析执⾏也证明了这点。

     但请求转发造成的漏洞也不能够称呼"重定向漏洞",请求重定向(redirect):客户端发送⼀个请求,服务器返响应,响应⾥⾯记录客户端需再次发起请求的地址,此时客户端会再次请求发送给这个新的地址。重定向是客户端的⾏为,客户端需要访问两次服务器,发送的是两次请求且是不同的Request请求和Response响应,请求过程数据不共享。

    在第⼆次请求时浏览器url地址会变请求转发(forward):指的是浏览器向服务器发送⼀个请求,服务器会帮客户端将请求转发到⽬标地址,再将响应结果返回给客户端,重定向是服务器实现的,客户端不关⼼服务器如何⼯作,只接受响应,在交互过程中使⽤同⼀个Request请求对象和Response响应对象,数据都是共享的,浏览器URL地址不会发⽣变化那为什么能访问WEB-INF⽬录下配置⽂件呢?正常情况访问查阅资料了解到:WEB-INF⽬录,应⽤服务器把它指为禁访⽬录,在浏览器中⽆法访问,但是可以让servlet进⾏访问。

     从以上可以判断,漏洞原理是通过请求转发绕过了对web-inf⽬录的访问限制,应该称为“绕过”,而绝非“文件读取”。相似的漏洞如“Apache Shiro身份绕过(CVE-2022-40664)”漏洞是通过EequestDispatcher转发或包含时Shiro中的身份验证绕过⽽产⽣的漏洞上⾯看了反⾯例⼦,再来看⼀个正经的⽂件读取漏洞。

⽤友U8C-PrintTemplateFileServlet⽂件读取-删除

     这⾥先贴下代码吧。

雷石|对用友NC任意文件读取漏洞的分析

     从代码引⽤的包就可看到引⽤了⽂件流的包。

     ⾸先是接收参数filePath,然后定义realPath变量,并拼接组合,然后读取⽂件。

     在46⾄62⾏,是读取⽂件流并返回给浏览器的实现过程。但在64⾏的判断中会删除服务器中的⽂件。

由于会删除文件,建议在测试环境复现

复现漏洞‍‍

 POC

http://172.16.1.200:8088/servlet/~uapweb/nc.lfw.billtemplate.servlet.PrintTemplateFileServlet?filePath=2222.txt

     访问不存在⽂件会报错,并泄漏绝对路径。

雷石|对用友NC任意文件读取漏洞的分析

     ⾸先在服务器该⽬录放置⼀个测试⽂件“flag.txt”并再次访问该⽂件。

雷石|对用友NC任意文件读取漏洞的分析

     读取该⽂件,成功返回⽂件内容。

雷石|对用友NC任意文件读取漏洞的分析

     此时服务器⽬录下⽂件已被删除。

雷石|对用友NC任意文件读取漏洞的分析

结语

     不知何时圈⼦从浮躁到现在的抽象,SQL注⼊不叫“注入”叫“任意文件上传”(通过sql注⼊写webshell)或叫“RCE”(写webshell再调⽤命令执⾏函数)、权限绕过不叫“绕过”叫任意⽂件读取 ,漏洞评级也有了“核弹级”。

本文作者:xueqi

雷石|对用友NC任意文件读取漏洞的分析

雷石安全实验室

原文始发于微信公众号(雷石安全实验室):雷石|对用友NC“任意文件读取”漏洞的分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年1月19日15:59:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   雷石|对用友NC任意文件读取漏洞的分析https://cn-sec.com/archives/2410812.html

发表评论

匿名网友 填写信息