记一次渗透测试中rdoc远程代码执行

admin 2023年5月9日18:22:12评论41 views字数 2084阅读6分56秒阅读模式

前言

最近在渗透测试的时候,在后台发现一个打包功能点,可以对文件进行解析,并生成html文档。

记一次渗透测试中rdoc远程代码执行

发现文档是rdoc生成的,搜索发现rdoc是ruby中的一个文档生成器,并且rdoc低于3.0.1版本存在命令注入漏洞的,利用CVE-2021-31799成功getshell,顺便本地搭建了一个环境来分析一下。

漏洞描述

  • 漏洞类型

命令注入

  • 影响版本

RDoc 3.11 - 6.3.0

  • 漏洞等级

  • CVE编号

CVE-2021-31799

组件介绍

RDoc是Ruby程序的文档生成器。它可以解析Ruby源代码并生成HTML文档。它可以通过包含在Ruby发行版中的命令行工具使用,也可以通过作为一个Gem包进行安装。RDoc支持文本格式的注释和Ruby源代码中的一些标记来指示要如何渲染注释。它还可以生成相应的RDoc文件,使您可以浏览整个库。

Rdoc的安装

gem install rdoc -v 6.3.0

漏洞分析

  • 漏洞详情

RDoc用来调用Kernel#open来打开一个本地文件。如果一个Ruby项目有一个文件,其名称以|开头,以tag结尾,那么管道字符后面的命令就会被执行。

  • 漏洞分析

首先,漏洞详情说的是open函数,在ruby中,open函数是可以直接执行命令的,在清风月郎居师傅的博客文章中介绍

记一次渗透测试中rdoc远程代码执行

官方文档给出一个示例代码,可以通过管道符号执行系统命令

记一次渗透测试中rdoc远程代码执行

查看rdoc修复代码,漏洞函数是在产生漏洞的代码在lib/rdoc/rdoc.rb的remove_unparseable方法,使用了open函数接收外部参数。

记一次渗透测试中rdoc远程代码执行

  def remove_unparseable files

    files.reject do |file, *|

      file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i or

        (file =~ /tags$/i and

         **open(file, 'rb')** { |io|

           io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/

         })

    end

  end

把rdoc 的6.3.0源码下载到本地进行调试。
Release v6.3.0 · ruby/rdoc · GitHub
在本地目录中提前新建好一个文件,命令为
touch '| touch evil.txt && echo tags'

记一次渗透测试中rdoc远程代码执行

下面开始分析该漏洞过程。
先在编辑器中给该方法打上断点

记一次渗透测试中rdoc远程代码执行

IDE的运行配置,设置好工作目录和rdoc文件位置
记一次渗透测试中rdoc远程代码执行

点击debug,在该方法前面暂停下来。

记一次渗透测试中rdoc远程代码执行

给该方法传入了一个hash,hash中的key为目录中的文件名称。

{"| touch evil.txt && echo tags"=>2023-04-18 07:38:21.544248155 +0000}

通过reject方法把key值取出来,| touch evil.txt && echo tags ,赋予file变量。

把file变量进行两次判断,用or连接。

记一次渗透测试中rdoc远程代码执行

  • 第一个匹配
    file =~ /\.(?:class|eps|erb|scpt\.txt|svg|ttf|yml)$/i
    用于检查文件名是否符合一些特定的扩展名,即class、eps、erb、scpt.txt、svg、ttf、yml,不区分大小写,这个匹配肯定是不符合的,但是这里用的是or,ruby进入下一个判断。

  • 第二个匹配

(file =~ /tags$/i and  
open(file, 'rb') { |io|
io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/
})

先对file变量进行匹配,现在file变量的值是
| touch evil.txt && echo tags
符合括号中代码的第一个匹配规则,匹配判断结尾是否有tags字符串,返回真

记一次渗透测试中rdoc远程代码执行

然后and进行下一个判断,open函数执行变成了下面这串代码

open("| touch evil.txt && echo tags",’rb’)

然后把结果保存到io变量中,通过read方法读取io中的值,进行匹配

io.read(100) =~ /\A(\f\n[^,]+,\d+$|!_TAG_)/

等方法执行完毕,就执行了touch evil.txt命令,成功在目录中新建了evil.txt文件。

记一次渗透测试中rdoc远程代码执行

还可以通过"|$(id)-tags" 这样的输入,执行命令。

记一次渗透测试中rdoc远程代码执行

修复过程

官方把open函数更换成了File.open函数

记一次渗透测试中rdoc远程代码执行

修复措施

升级到rdoc6.3.1版本

参考链接

  • https://blog.vackbot.com/archives/ruby-an-quan-man-tan

  • https://niubl.com/2021/05/04/research-on-ruby-command-injection-vulnerability/

转载:https://forum.butian.net/share/2245作者:带头小弟。欢迎大家去关注作者


记一次渗透测试中rdoc远程代码执行 点击下方小卡片或扫描下方二维码观看更多技术文章记一次渗透测试中rdoc远程代码执行

记一次渗透测试中rdoc远程代码执行

师傅们点赞、转发、在看就是最大的支持


原文始发于微信公众号(星冥安全):记一次渗透测试中rdoc远程代码执行

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月9日18:22:12
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次渗透测试中rdoc远程代码执行http://cn-sec.com/archives/1717405.html

发表评论

匿名网友 填写信息