-
-
Notifications
You must be signed in to change notification settings - Fork 438
/
phpsploit
executable file
·224 lines (183 loc) · 7 KB
/
phpsploit
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""PhpSploit: Furtive post-exploitation framework
PhpSploit is a remote control framework, aiming to provide a stealth
interactive shell-like connection over HTTP between client and web server.
It is a post-exploitation tool capable to maintain access to a compromised
web server for privilege escalation purposes.
https://github.com/nil0x42/phpsploit
"""
import sys
import os
VERSION = "3.2"
# check operating system
if sys.platform.lower().startswith('win'):
sys.exit('[-] If you use Windows, you should be '
'a TARGET rather than an attacker ...')
# check python version
ver = sys.version_info
if ver[0] < 3 or (ver[0] == 3 and ver[1] < 5):
sys.exit('[-] PhpSploit needs python >= 3.5 to run')
# check dependencies
from importlib.util import find_spec
missing_deps = set()
deps_list = {
"phpserialize": ("phpserialize",),
"pyparsing": ("pyparsing",),
"PySocks": ("socks", "sockshandler",),
"ExtProxy": ("extproxy",),
}
for name, deps in deps_list.items():
for dep in deps:
if find_spec(dep) is None:
missing_deps.add(name)
break
if missing_deps:
for name in missing_deps:
print("[-] Missing dependency: %r" % name, file=sys.stderr)
sys.exit("[?] Install dependencies with: "
"`pip3 install -r requirements.txt`")
try:
import src # spread phpsploit sources
import random
import argparse
import subprocess as sp
import core
import ui.input
import ui.output
import ui.interface
from ui.color import colorize
from datatypes import Path
except KeyboardInterrupt:
sys.exit("\r[-] PhpSploit initialization interrupted")
def parser_help_formatter(prog):
"""argparser help output formatter"""
kwargs = dict()
kwargs['width'] = ui.output.columns()
kwargs['max_help_position'] = 34
fmt = argparse.HelpFormatter(prog, **kwargs)
return fmt
def build_parser():
"""build argparse parser"""
p = argparse.ArgumentParser()
p.formatter_class = parser_help_formatter
p.description = "The stealth post-exploitation framework"
p.add_argument('-v', '--version',
help="output version information and exit",
action="store_true")
p.add_argument('-c', '--config',
help="use alternative configuration file",
metavar="<FILE>")
p.add_argument('-l', '--load',
help="load session file",
metavar="<SESSION>")
p.add_argument('-t', '--target',
help="set remote TARGET URL",
metavar="<URL>")
p.add_argument('-s', '--source',
help="run commands from file (disables interactive mode)",
metavar="<FILE>")
p.add_argument('-e', '--eval',
help="run phpsploit command (disables interactive mode)",
metavar="<CMD>")
p.add_argument('-i', '--interactive',
help="force interactive mode if unset by `-e` or `-s`",
action="store_true")
return p
def run_process(cmd):
"""get output of given shell command"""
child = sp.Popen(cmd, stdout=sp.PIPE, stderr=sp.DEVNULL)
streamdata = child.communicate()[0]
if child.returncode != 0:
return ""
return streamdata.decode("utf-8").strip()
def rand_quote():
"""return a random funny quote"""
msg_list = Path(src.BASEDIR + "data/quotes.lst").readlines()
return random.choice(msg_list).strip()
def cmdrun(iface, cmdobj, show_err=False):
"""run a phpsploit command
handle syntax errors & return command's retcode
"""
try:
retval = iface.interpret(cmdobj)
if retval != 0 and show_err and iface.last_exception:
iface.interpret("corectl stack-traceback")
except (SyntaxWarning, SyntaxError) as err:
retval = iface.onexception(err)
return retval
# pylint: disable=too-many-branches
def main():
"""phpsploit's main function
"""
# Make phpsploit usable as shebang for scripting
if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]):
sys.argv.insert(1, "--source")
parser = build_parser()
opt = vars(parser.parse_args())
if opt['version']:
git_ver = run_process(['git', '-C', src.BASEDIR, 'describe'])
version = (git_ver + " (git)") if git_ver else VERSION
print("PhpSploit Framework, version %s\n"
"License GPLv3+: GNU GPL version 3 or later"
" <http://gnu.org/licenses/gpl.html>\n\n"
"This is free software; you are free"
" to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law."
% version)
return 0
# Enable stdout wrapper
sys.stdout = ui.output.Wrapper(backlog=True)
# determine if the interface would run in interactive mode
interactive = False
if ui.input.isatty():
if (not opt['eval'] and not opt['source']) or opt['interactive']:
interactive = True
# make this variable accessible from phpsploit core
ui.interface.interactive = interactive
# Start shell interface
iface = ui.interface.Shell()
if opt['config'] is None:
opt['config'] = core.USERDIR + "config"
if cmdrun(iface, "source -e '%s'" % opt['config'], show_err=True) != 0:
print()
parser.error("%r: config file contains invalid commands."
% opt['config'])
elif interactive and ui.output.isatty():
logo = Path(src.BASEDIR + "data/logo.ascii").read()
cmdrun(iface, "lrun clear")
print(logo)
print(colorize("%DimBold", "# Stealth & persistent C2 framework via ", "%White", "evil PHP oneliner"))
cmdrun(iface, "help")
iface.init()
if opt['load']:
if cmdrun(iface, "session load '%s'" % opt['load']) != 0:
print()
parser.error("%r: invalid session file." % opt['load'])
if opt['target']:
if cmdrun(iface, "set TARGET '%s'" % opt['target']) != 0:
print()
parser.error("%r: couldn't set target url." % opt['target'])
if opt['source']:
if cmdrun(iface, "source '%s'" % opt['source']) != 0:
print()
parser.error("%r: couldn't read source file." % opt['source'])
retval = 0
if opt['eval']:
retval = cmdrun(iface, opt['eval'])
if interactive or not ui.input.isatty():
iface.cmdloop()
if ui.output.isatty():
print(colorize("%DimWhite", '\n' + rand_quote() + '\n'))
return retval
if __name__ == "__main__":
sys.exit(main())
else:
def check_import():
"""check whether this file is imported for a CI test"""
launcher = os.path.abspath(__file__)
test_dir = os.path.join(os.path.dirname(launcher), "test/")
caller = os.path.abspath(sys.argv[0])
if not caller.startswith(test_dir):
sys.exit('[-] Phpsploit must be run from launcher: ' + launcher)
check_import()