Dojo #44

Challenge "Hardware monitor" du dojo de YesWeHack (septembre 2025)

Le

Le Dojo de YesWeHack est un espace d’entraînement pratique où les hunters peuvent développer leurs compétences en identifiant et exploitant des failles de sécurité à travers une série de défis dédiés au bug bounty. C'est pourquoi les articles de cette catégorie sont tournés comme des rapports de bug bounty.

📝 Summary

A critical Remote Code Execution (RCE) vulnerability was discovered in the backup script loader of the Ruby application. The application improperly handles user-supplied input for backup scripts, allowing attackers to execute arbitrary Ruby code via the load method. The core design does not properly sanitize paths or restrict script execution to trusted files.


✍ Code

require 'erb'
require 'cgi'
require 'logger'
require 'pathname'

Dir.chdir('/tmp/app')

logger = Logger.new('logs/error.log')
logger.datetime_format = "%-m/%-d/%Y"

scriptFile = CGI.unescape("")
scriptFile = Pathname.new(scriptFile)

# Load given backup script
if scriptFile != '' then
    logger.info("Running bakup script #{scriptFile}")
    begin
        load "scripts/#{scriptFile.cleanpath}"
    rescue Exception => e
        logger.warn("The bakup script failed to run, error : #{e.message}")
    end
end


# Render the given page for our web application
puts ERB.new(IO.read("views/index.html")).result_with_hash({logs: File.read("logs/error.log")})

🔍 Technical Details

  1. Remote Code Execution via Unsanitized Script Load
    • Affected file: app.rb (or relevant Ruby file)
    • Location: script loading block
    • Vulnerability Type: Remote Code Execution (RCE)
    • Vulnerable code:
    scriptFile = CGI.unescape(\"<user-input>\")
    scriptFile = Pathname.new(scriptFile)
    
    if scriptFile != '' then
        logger.info(\"Running backup script #{scriptFile}\")
        begin
            load \"scripts/#{scriptFile.cleanpath}\"
        rescue Exception => e
            logger.warn(\"The backup script failed to run, error : #{e.message}\")
        end
    end
    

🧠 Root cause

The vulnerability arises from directly passing user input to Pathname.new and then to load without proper validation. Key issues:

  • Path Traversal / Unsanitized Input The use of cleanpath does not prevent maliciously crafted input that escapes the scripts/ directory.

  • Execution of Arbitrary Ruby Code Any Ruby code present in the user-supplied path is executed in the context of the server.

  • Log Injection The application logs the unsanitized user input (logger.info(\"Running backup script #{scriptFile}\")). This allows an attacker to inject valid Ruby code into log files, which can then be executed by the application.

  • Combined Exploit Mechanism An attackercan create a log file containing valid Ruby code executing system commands (log injection) and then execute it via load (path traversal). The attack relies on newline characters and Ruby syntax to craft executable code in the log.

Schéma : l'attaquant combine log injection et path traversal pour exécuter du code Ruby


💥 Impact

An attacker can execute arbitrary Ruby code on the server, potentially leading to:

  • Full server compromise
  • Reading sensitive files (/tmp/*.txt, logs, configuration)
  • Privilege escalation if the application runs with elevated permissions
  • Deployment of malware or lateral movement within the network

🛡️ Recommendation

  • Avoid loading user-supplied scripts directly. Only allow execution of predefined, trusted scripts.
  • Implement strict allowlists for acceptable script names.
  • Sanitize and validate paths thoroughly before passing them to load.
  • Sanitize log entries or use safe logging mechanisms to prevent log injection.
  • Consider sandboxing or using a safer execution environment if dynamic script execution is required.

✅ Proof of Concept (PoC)

Supplying the following payload as scriptFile input executes arbitrary commands:

../
][0] = 1,:ignored
puts `id`#/../logs/error.log

When processed by the application, this payload allows:

  • Injection of valid Ruby code into log files (log injection)
  • Execution of the code via path traversal (load), exposing sensitive files and confirming RCE.

Dojo : le tableau de bord exécute la commande id via l'injection, confirmant le RCE en tant que nobody

Flag

FLAG{D0nt_Und3res7imate_a_L0g_1njection}"

Accès Restreint

Cet article n'est pas (encore) publique.
Pour obtenir un accès anticipé, contactez-moi.

[[ passwordError ]]

[[ post.title ]]

[[ post.description ]]

Le [[ post.date ]]

[[ tag ]]
[[ currentMatchIndex + 1 ]] / [[ searchMatches.length ]] 0 / 0

Sommaire

Page principale