-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathncenc.sh
executable file
·127 lines (106 loc) · 3.19 KB
/
ncenc.sh
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
#!/bin/bash
# Netcat wrapper to encrypt traffic with openssl
# Display usage
if [ $# -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
echo 'Netcat wrapper to encrypt traffic with openssl
Usage:
./ncenc.sh <nc arguments...>
Example:
./ncenc.sh -lvnp 4242 # Listen on port 4242
./ncenc.sh 127.0.0.1 4242 # Connect to 4242 on localhost
See more with `./ncenc.sh -h`'
exit 1
fi
# Check if tools are installed and return them absolute path
check_tool() {
tool_path=$(which $1)
if ! [ -x "$tool_path" ]; then
echo "Error: $1 is missing, please install it." >&2
return 1
fi
echo $tool_path
}
OPENSSL=$(check_tool openssl) || exit $?
NC=$(check_tool nc) || exit $?
BASE64=$(check_tool base64) || exit $?
# Retrieve arguments
NC_ARGS=""
SOCKET_TYPE="client"
IS_VERBOSE=false
for arg in "$@"; do
# Check if nc is running as a server or client
if [ "$arg" = "-l" ] || [ "$arg" = "--listen" ] || echo "$arg" | grep -Eq '^\-.*l.*$'; then
SOCKET_TYPE="server"
fi
# Check if nc is verbose
if [ "$arg" = "-v" ] || [ "$arg" = "--verbose" ] || echo "$arg" | grep -Eq '^\-.*v.*$'; then
IS_VERBOSE=true
fi
NC_ARGS="$NC_ARGS $arg"
done
# Echo verbose only if verbose mode is enabled
verbose_echo() {
if $IS_VERBOSE; then
echo "$@" >&2
fi
}
# Create temporary directory to store encryption keys
KEYS_PATH="$(mktemp -d)"
trap 'rm -rf -- "$KEYS_PATH"' EXIT
# Generate key pair with openssl
verbose_echo "Generating key pair..."
MY_KEY_PATH="$KEYS_PATH/mykey.pem"
$OPENSSL genrsa 2048 >"$MY_KEY_PATH"
MY_PUBLIC_KEY=$($OPENSSL pkey -in "$MY_KEY_PATH" -outform pem -pubout)
SKYF0L_PUBLIC_KEY_PATH="$KEYS_PATH/skyf0lpubkey.pem"
# Nc loop
WELCOME_MESSAGE="Welcome to the encrypted netcat, please use NcEnc to communicate with me!"
(
echo "$WELCOME_MESSAGE"
## Wait for nc start
sleep 0.2
## Send server public key
if [ "$SOCKET_TYPE" = "server" ]; then
verbose_echo "Send server public key..."
echo "$MY_PUBLIC_KEY"
fi
## Wait until other public key is received
verbose_echo "Wait for other public key..."
while [ ! -f "$SKYF0L_PUBLIC_KEY_PATH" ]; do
sleep .2
done
## Check if received public key is valid, otherwise exit
$OPENSSL pkey -inform PEM -pubin -in "$SKYF0L_PUBLIC_KEY_PATH" -noout
if [ $? -ne 0 ]; then
echo "Error: Invalid client public key." >&2
exit 1
fi
## Send client public key
if [ "$SOCKET_TYPE" = "client" ]; then
verbose_echo "Send client public key..."
echo "$MY_PUBLIC_KEY"
fi
verbose_echo "=========================="
## Read from stdin loop
while IFS= read -r IN; do
echo -n "$IN" | $OPENSSL pkeyutl -encrypt -pubin -inkey "$SKYF0L_PUBLIC_KEY_PATH" | $BASE64 -w 0
echo
done
) |
(
## Run nc server
$NC $NC_ARGS
) |
(
## Receive other public key
sed '/-----END PUBLIC KEY-----/q' | grep -v "$WELCOME_MESSAGE" >"$SKYF0L_PUBLIC_KEY_PATH".tmp
verbose_echo "Other public key received"
mv "$SKYF0L_PUBLIC_KEY_PATH".tmp "$SKYF0L_PUBLIC_KEY_PATH"
## Wait for other public key to be received by read loop
sleep .3
## Write to stdout loop
while IFS= read -r OUT; do
echo "$OUT" | $BASE64 -d | $OPENSSL pkeyutl -decrypt -inkey "$MY_KEY_PATH"
echo
done
)