Reverse me challenge
1
Disconnect3d
AlligatorCon 2k18 ~world
https://python-challenges.com/
nc 51.38.138.161 31337
import os�import sys��print('~~ May the Witchers be with you. Always.')��started = False�filtered = False�
import os�import sys��print('~~ May the Witchers be with you. Always.')��started = False�filtered = False��with open(__file__) as f:� print('~'*30)� for line in f:� if 'import os' in line:� started = True� elif not started:� continue�� if line == '#end-of-filter\n':� filtered = False�� elif filtered:� continue�� print(line, end='')� if 'class Challenge:\n' in line:� filtered = True� print('# [ filtered ]')� print('~'*30)�
def disconnect_code():� print(� 'I am closin\' the', __file__, 'file so it aint too eazy; you know, for your own fun.\n'� )� os.close(100)��
def disconnect_code():� print(� 'I am closin\' the', __file__, 'file so it aint too eazy; you know, for your own fun.\n'� )� os.close(100)���LOL_NO = "I won't give you flag like this"�LOL_MEH = "Meh, you need a bit more here"�
def disconnect_code():� print(� 'I am closin\' the', __file__, 'file so it aint too eazy; you know, for your own fun.\n'� )� os.close(100)���LOL_NO = "I won't give you flag like this"�LOL_MEH = "Meh, you need a bit more here"��print("Flags have a format of FLAG{[A-Za-z0-9_]+}")�
def disconnect_code():� print(� 'I am closin\' the', __file__, 'file so it aint too eazy; you know, for your own fun.\n'� )� os.close(100)���LOL_NO = "I won't give you flag like this"�LOL_MEH = "Meh, you need a bit more here"��print("Flags have a format of FLAG{[A-Za-z0-9_]+}")��class Challenge:�# [ filtered ]�#end-of-filter�
def run():� assert __file__ == '/proc/self/fd/100' # Disconnect3d's magic�� disconnect_code()�� print('\n\n\nOkay. Now you can show off your skills. gl hf')�� while True:� msg = input('msg: ')[:300] # you don't need that many, but feel free...�� print(eval(msg)) # YOLO. gl hf�
def run():� assert __file__ == '/proc/self/fd/100' # Disconnect3d's magic�� disconnect_code()�� print('\n\n\nOkay. Now you can show off your skills. gl hf')�� while True:� msg = input('msg: ')[:300] # you don't need that many, but feel free...�� print(eval(msg)) # YOLO. gl hf���if __name__ == '__main__':� run()�
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~�Flags have a format of FLAG{[A-Za-z0-9_]+}�I am closin' the /proc/self/fd/100 file so it aint too eazy; you know, for your own fun.�����Okay. Now you can show off your skills. gl hf�msg:
eval is evil
17
'__import__("os").system("...")'
18
eval(input, {'__builtins__':{}})
19
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
20
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
21
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
22
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
23
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
24
"{}.__class__.__base__.__subclasses__()[59]()._module�.__builtins__['__import__']('os').system('echo sick')"
25
The challenge
26
class Challenge:�# [ filtered ]�#end-of-filter
27
First level
28
Reverse me challenge
class Challenge:� def first_level(self):� return 'That was just a begining. First flag: FLAG{easy_peasy_lemon_squeezy}'�
29
class Challenge:�# [ filtered ]�#end-of-filter
30
Reverse me challenge
class Challenge:� def first_level(self):� return 'That was just a begining. First flag: FLAG{easy_peasy_lemon_squeezy}'
msg: dir(Challenge)
['first_level', 'second_level', 'third_level', ...]
�
31
Reverse me challenge
class Challenge:� def first_level(self):� return 'That was just a begining. First flag: FLAG{easy_peasy_lemon_squeezy}'
msg: dir(Challenge)
['first_level', 'second_level', 'third_level', ...]
msg: Challenge().first_level()
That was just a begining. First flag: FLAG{easy_peasy_lemon_squeezy}
�
32
Second level
33
def second_level(self):� raise Exception(LOL_NO)�� def a():� """� Never gonna give you up� Never gonna let you down� Never gonna run around and desert you� Never gonna make you cry� Never gonna say goodbye� Never gonna tell a lie and hurt you� """� def b():� """� Never gonna give you up� Never gonna let you down� Never gonna run around and desert you� Never gonna make you cry� Never gonna say goodbye� Never gonna tell a lie and hurt you� """�
34
def c():� """� Never gonna give you up� Never gonna let you down� Never gonna run around and desert you� Never gonna make you cry� Never gonna say goodbye� Never gonna tell a lie and hurt you� """� def d():� """� Never gonna give you up� Never gonna let you down� Never gonna run around and desert you� Never gonna make you cry� Never gonna say goodbye� Never gonna tell a lie and hurt you� """� def e():� return 'Lets play moar =). Second flag: FLAG{this_was_also_easy}'� def f():� """� Never gonna give you up� Never gonna let you down� Never gonna run around and desert you� Never gonna make you cry� Never gonna say goodbye� Never gonna tell a lie and hurt you� """�� return LOL_MEH�� def third_level(self):� raise Exception(LOL_NO)� � key = [3, 1, 3, 3, 7]� ciphertext = '^DGMH[t@Or]CH]r^JZvEHYM'�� flag = ''.join(chr(ord(ciphertext[i]) ^ key[i%len(key)] ^ 42) for i in range(len(ciphertext)))�� return 'This could be deducted... MOOAAR. Third flag: FLAG{%s}' % flag�
35
msg: Challenge().second_level()
36
msg: Challenge().second_level()
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
File "/proc/self/fd/100", line 109, in second_level
Exception: I won't give you flag like this
37
msg: Challenge.second_level.__code__
<code object second_level at 0x7f437b874d20, file
"/proc/self/fd/100", line 108>
38
msg: Challenge.second_level.__code__.co_consts
(
None,�
<code object a (...)>,
'Challenge.second_level.<locals>.a',
<code object b (...)>,
'Challenge.second_level.<locals>.b',
<code object c (...)>,
'Challenge.second_level.<locals>.c',
<code object d (...)>,
'Challenge.second_level.<locals>.d',
<code object f (...)>,
'Challenge.second_level.<locals>.f'
)
39
msg: Challenge.second_level.__code__.co_consts[7].co_consts
(
‘Never gonna give you up (...)',
<code object e (...)>,
'Challenge.second_level.<locals>.d.<locals>.e',
None
)
40
msg: Challenge.second_level.__code__.co_consts[7].co_consts[1].co_consts
(
None,
'Lets play moar =). Second flag: FLAG{this_was_also_easy}'�)
41
Third level
42
Third level
def third_level(self):� raise Exception(LOL_NO)� � key = [3, 1, 3, 3, 7]� ciphertext = '^DGMH[t@Or]CH]r^JZvEHYM'�� flag = ''.join(chr(ord(ciphertext[i]) ^ key[i%len(key)] ^ 42) for i in range(len(ciphertext)))�� return 'This could be deducted... MOOAAR. Third flag: FLAG{%s}' % flag�
43
Meet dis
44
45
46
47
48
__import__('dis').dis(Challenge.third_level)
49
msg: __import__('dis').dis(Challenge.third_level)
162 0 LOAD_GLOBAL 0 (Exception)
3 LOAD_GLOBAL 1 (LOL_NO)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 RAISE_VARARGS 1
164 12 LOAD_CONST 1 (3)
15 LOAD_CONST 2 (1)
18 LOAD_CONST 1 (3)
21 LOAD_CONST 1 (3)
24 LOAD_CONST 3 (7)
27 BUILD_LIST 5
30 STORE_DEREF 1 (key)
165 33 LOAD_CONST 4 ('^DGMH[t@Or]CH]r^JZvEHYM')
36 STORE_DEREF 0 (ciphertext)
167 39 LOAD_CONST 5 ('')
42 LOAD_ATTR 2 (join)
45 LOAD_CLOSURE 0 (ciphertext)
48 LOAD_CLOSURE 1 (key)
51 BUILD_TUPLE 2
54 LOAD_CONST 6 (<code object <genexpr> (...))
57 LOAD_CONST 7 ('Challenge.third_level.<locals>.<genexpr>')
50
msg: __import__('dis').dis(Challenge.third_level)
162 0 LOAD_GLOBAL 0 (Exception)
3 LOAD_GLOBAL 1 (LOL_NO)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 RAISE_VARARGS 1
164 12 LOAD_CONST 1 (3)
15 LOAD_CONST 2 (1)
18 LOAD_CONST 1 (3)
21 LOAD_CONST 1 (3)
24 LOAD_CONST 3 (7)
27 BUILD_LIST 5
30 STORE_DEREF 1 (key)
165 33 LOAD_CONST 4 ('^DGMH[t@Or]CH]r^JZvEHYM')
36 STORE_DEREF 0 (ciphertext)
167 39 LOAD_CONST 5 ('')
42 LOAD_ATTR 2 (join)
45 LOAD_CLOSURE 0 (ciphertext)
48 LOAD_CLOSURE 1 (key)
51 BUILD_TUPLE 2
54 LOAD_CONST 6 (<code object <genexpr> (...))
57 LOAD_CONST 7 ('Challenge.third_level.<locals>.<genexpr>')
51
msg: __import__('dis').dis(Challenge.third_level)
162 0 LOAD_GLOBAL 0 (Exception)
3 LOAD_GLOBAL 1 (LOL_NO)
6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
9 RAISE_VARARGS 1
164 12 LOAD_CONST 1 (3)
15 LOAD_CONST 2 (1)
18 LOAD_CONST 1 (3)
21 LOAD_CONST 1 (3)
24 LOAD_CONST 3 (7)
27 BUILD_LIST 5
30 STORE_DEREF 1 (key)
165 33 LOAD_CONST 4 ('^DGMH[t@Or]CH]r^JZvEHYM')
36 STORE_DEREF 0 (ciphertext)
167 39 LOAD_CONST 5 ('')
42 LOAD_ATTR 2 (join)
45 LOAD_CLOSURE 0 (ciphertext)
48 LOAD_CLOSURE 1 (key)
51 BUILD_TUPLE 2
54 LOAD_CONST 6 (<code object <genexpr> (...))
57 LOAD_CONST 7 ('Challenge.third_level.<locals>.<genexpr>')
52
60 MAKE_CLOSURE 0
63 LOAD_GLOBAL 3 (range)
66 LOAD_GLOBAL 4 (len)
69 LOAD_DEREF 0 (ciphertext)
72 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
75 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
78 GET_ITER
79 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
82 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
85 STORE_FAST 1 (flag)
169 88 LOAD_CONST 8 ('This could be deducted... MOOAAR. Third flag: FLAG{%s}')
91 LOAD_FAST 1 (flag)
94 BINARY_MODULO
95 RETURN_VALUE
None
53
msg: __import__('dis').dis(Challenge.third_level.__code__.co_consts[6])
167 0 LOAD_FAST 0 (.0)
>> 3 FOR_ITER 49 (to 55)
6 STORE_FAST 1 (i)
9 LOAD_GLOBAL 0 (chr)
12 LOAD_GLOBAL 1 (ord)
15 LOAD_DEREF 0 (ciphertext)
18 LOAD_FAST 1 (i)
21 BINARY_SUBSCR
22 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
25 LOAD_DEREF 1 (key)
28 LOAD_FAST 1 (i)
31 LOAD_GLOBAL 2 (len)
34 LOAD_DEREF 1 (key)
37 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
40 BINARY_MODULO
41 BINARY_SUBSCR
42 BINARY_XOR
43 LOAD_CONST 0 (42)
46 BINARY_XOR
47 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
50 YIELD_VALUE
51 POP_TOP
52 JUMP_ABSOLUTE 3
>> 55 LOAD_CONST 1 (None)
58 RETURN_VALUE
54
TIL
55
You can use exec and pdb�in eval
56
Lets see some cool solutions
57
exec("import pdb; pdb.run('Challenge().second_level()')")�from types import CodeType��def fix_function(func, payload):
fn_code = func.__code__
func.__code__ = CodeType(fn_code.co_argcount, fn_code.co_kwonlyargcount,fn_code.co_nlocals,fn_code.co_stacksize,fn_code.co_flags,payload,fn_code.co_consts,fn_code.co_names,fn_code.co_varnames,fn_code.co_filename,fn_code.co_name,fn_code.co_firstlineno,fn_code.co_lnotab,fn_code.co_freevars,fn_code.co_cellvars,)��payload = b't\x00\x00d\x01\x00d\x02\x00\x84\x00\x00}\x01\x00d\x03\x00d\x04\x00\x84\x00\x00}\x02\x00d\x05\x00d\x06\x00\x84\x00\x00}\x03\x00d\x07\x00d\x08\x00\x84\x00\x00}\x04\x00d\t\x00d\n\x00\x84\x00\x00}\x05\x00t\x02\x00S'�ch = Challenge.second_level
fix_function(ch, payload)
ch(Challenge())�
58
exec("import pdb; pdb.run('Challenge().second_level()')")�from types import CodeType��def fix_function(func, payload):
fn_code = func.__code__
func.__code__ = CodeType(fn_code.co_argcount, fn_code.co_kwonlyargcount,fn_code.co_nlocals,fn_code.co_stacksize,fn_code.co_flags,payload,fn_code.co_consts,fn_code.co_names,fn_code.co_varnames,fn_code.co_filename,fn_code.co_name,fn_code.co_firstlineno,fn_code.co_lnotab,fn_code.co_freevars,fn_code.co_cellvars,)��payload = b't\x00\x00d\x01\x00d\x02\x00\x84\x00\x00}\x01\x00d\x03\x00d\x04\x00\x84\x00\x00}\x02\x00d\x05\x00d\x06\x00\x84\x00\x00}\x03\x00d\x07\x00d\x08\x00\x84\x00\x00}\x04\x00d\t\x00d\n\x00\x84\x00\x00}\x05\x00t\x02\x00S'�ch = Challenge.second_level
fix_function(ch, payload)
ch(Challenge())�
59
exec("import pdb; pdb.run('Challenge().second_level()')")�from types import CodeType��def fix_function(func, payload):
fn_code = func.__code__
func.__code__ = CodeType(fn_code.co_argcount, fn_code.co_kwonlyargcount,fn_code.co_nlocals,fn_code.co_stacksize,fn_code.co_flags,payload,fn_code.co_consts,fn_code.co_names,fn_code.co_varnames,fn_code.co_filename,fn_code.co_name,fn_code.co_firstlineno,fn_code.co_lnotab,fn_code.co_freevars,fn_code.co_cellvars,)��payload = b't\x00\x00d\x01\x00d\x02\x00\x84\x00\x00}\x01\x00d\x03\x00d\x04\x00\x84\x00\x00}\x02\x00d\x05\x00d\x06\x00\x84\x00\x00}\x03\x00d\x07\x00d\x08\x00\x84\x00\x00}\x04\x00d\t\x00d\n\x00\x84\x00\x00}\x05\x00t\x02\x00S'�ch = Challenge.second_level
fix_function(ch, payload)
ch(Challenge())�
60
func.__code__.co_code
exec("import pdb; pdb.run('Challenge().second_level()')")�from types import CodeType��def fix_function(func, payload):
fn_code = func.__code__
func.__code__ = CodeType(fn_code.co_argcount, fn_code.co_kwonlyargcount,fn_code.co_nlocals,fn_code.co_stacksize,fn_code.co_flags,payload,fn_code.co_consts,fn_code.co_names,fn_code.co_varnames,fn_code.co_filename,fn_code.co_name,fn_code.co_firstlineno,fn_code.co_lnotab,fn_code.co_freevars,fn_code.co_cellvars,)��payload = b't\x00\x00d\x01\x00d\x02\x00\x84\x00\x00}\x01\x00d\x03\x00d\x04\x00\x84\x00\x00}\x02\x00d\x05\x00d\x06\x00\x84\x00\x00}\x03\x00d\x07\x00d\x08\x00\x84\x00\x00}\x04\x00d\t\x00d\n\x00\x84\x00\x00}\x05\x00t\x02\x00S'�ch = Challenge.second_level
fix_function(ch, payload)
ch(Challenge())�
61
func.__code__.co_code
Next
62
exec("import dis")�exec("ch = Challenge()")�exec("from types import CodeType as CT")�exec("fnc = Challenge.second_level.__code__")�print(fnc.co_code)�exec("payload = fnc.co_code[-4:] + b't\x05\x00S'")�print("hello")�print(fnc.co_code)�exec("AAAA = [fnc.co_argcount, fnc.co_kwonlyargcount, fnc.co_nlocals, fnc.co_stacksize, fnc.co_flags, payload, fnc.co_consts, fnc.co_names, fnc.co_varnames, fnc.co_filename, fnc.co_name, fnc.co_firstlineno, fnc.co_lnotab, fnc.co_freevars, fnc.co_cellvars]")�exec("Challenge.second_level.__code__ = CT(*AAAA)")�dis.dis(ch.second_level)�ch.second_level()�
63
exec("import dis")�exec("ch = Challenge()")�exec("from types import CodeType as CT")�exec("fnc = Challenge.second_level.__code__")�print(fnc.co_code)�exec("payload = fnc.co_code[-4:] + b't\x05\x00S'")�print("hello")�print(fnc.co_code)�exec("AAAA = [fnc.co_argcount, fnc.co_kwonlyargcount, fnc.co_nlocals, fnc.co_stacksize, fnc.co_flags, payload, fnc.co_consts, fnc.co_names, fnc.co_varnames, fnc.co_filename, fnc.co_name, fnc.co_firstlineno, fnc.co_lnotab, fnc.co_freevars, fnc.co_cellvars]")�exec("Challenge.second_level.__code__ = CT(*AAAA)")�dis.dis(ch.second_level)�ch.second_level()�
64
65
Next
66
Jumping in pdb
67
with Telnet('51.38.138.161', 31337) as tn:� # tn.write(b"Challenge().second_level.__func__.__code__" + b'\n')� tn.write(b"__import__('dis').dis(Challenge().third_level)" + b'\n')� tn.write(b"__import__('pdb').run('Challenge().third_level()')" + b'\n')� tn.write(b"step" + b'\n')� tn.write(b"step" + b'\n')� tn.write(b"j 164" + b'\n')
# tn.write(b"__import__('pdb').runcall(d)" + b'\n')�
68
Next
69
You can read /proc/self/mem
70
import re�p = "/proc/self/"�
ma = open(p+"maps",'r')�me = open(p+"mem",'rb',0)
�for l in ma.readlines():� m = re.match(r'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])', l)� if m.group(3) == 'r':� s = int(m.group(1),16)� me.seek(s)� chunk = me.read(int(m.group(2),16)-s)� print(chunk,)
71
msg: exec('import re\np="/proc/self/"\nma=open(p+"maps",\'r\')\nme=open(p+"mem",\'rb\',0)\nfor l in ma.readlines():\n m=re.match(r\'([0-9A-Fa-f]+)-([0-9A-Fa-f]+) ([-r])\', l)\n if m.group(3) == \'r\':\n s=int(m.group(1),16)\n me.seek(s)\n chunk=me.read(int(m.group(2),16)-s)\n print(chunk,)\n')�
72
73
74
75
*this is only the part that fit on the screen
\x00\x00\x00\x00\x00\x00 you\n """\n def e():\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 =). Second flag: FLAG{this_was_also_easy}\'\n def\x00\x01\x00\x00\x00\x00\x00\x00\x00 Never gonna give you up\n Never gonna\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 Never gonna run around and desert you\n Neve\xf0\x19,\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00 Never gonna say goodbye\n Never gonna\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n """\n\n return LOL_MEH\n\n def third_\xe0\xbc2\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00se Exception(LOL_NO)\n \n key = [3, 1, 3, 3,\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \'^DGMH[t@Or]CH]r^JZvEHYM\'\n\n flag = \'\'.join(chr(o\xb06+\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x00\x00\x00\x00i%len(key)] ^ 42) for i in range(len(ciphertext)))\n\n \xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e deducted... MOOAAR. Third flag: FLAG{%s}\' % flag\n\n#endP\xb53\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00 assert __file__ == \'/proc/self/fd/100\' # Disconnect\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ct_code()\n\n print(\'\\n\\n\\nOkay. Now you can show off y(\x1a,\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00 while True:\n msg = input(\'msg: \')[:300] # you d\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 feel free...\n\n print(eval(msg)) # YOL\xd8\xb43\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00= \'__main__\':\n run()\n \x16\x00\x00\x00\x00\x00\x000\x16\x0
76
\x00\x00\x00\x00\x00\x00 you\n """\n def e():\n \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 =). Second flag: FLAG{this_was_also_easy}\'\n def\x00\x01\x00\x00\x00\x00\x00\x00\x00 Never gonna give you up\n Never gonna\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 Never gonna run around and desert you\n Neve\xf0\x19,\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00 Never gonna say goodbye\n Never gonna\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n """\n\n return LOL_MEH\n\n def third_\xe0\xbc2\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00se Exception(LOL_NO)\n \n key = [3, 1, 3, 3,\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \'^DGMH[t@Or]CH]r^JZvEHYM\'\n\n flag = \'\'.join(chr(o\xb06+\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x00\x00\x00\x00i%len(key)] ^ 42) for i in range(len(ciphertext)))\n\n \xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00e deducted... MOOAAR. Third flag: FLAG{%s}\' % flag\n\n#endP\xb53\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00 assert __file__ == \'/proc/self/fd/100\' # Disconnect\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ct_code()\n\n print(\'\\n\\n\\nOkay. Now you can show off y(\x1a,\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00 while True:\n msg = input(\'msg: \')[:300] # you d\xe0\xf6=\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 feel free...\n\n print(eval(msg)) # YOL\xd8\xb43\x1d\xcf\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00= \'__main__\':\n run()\n \x16\x00\x00\x00\x00\x00\x000\x16\x0
77
key = [3, 1, 3, 3, 7]
ciphertext = '^DGMH[t@Or]CH]r^JZvEHYM'
flag = \'\'.join(chr(ord(ciphertext[i])len(key)] ^ 42) for i in range(len(ciphertext)))
ord(ciphertext[i])%
key[i%len(key)]
flag = \'\'.join(chr(oXX"\xab\x7f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00a\x00\x00\x00\x00\x00\x00\x00i%len(key)] ^ 42) for i in range(len(ciphertext)))
flag = \'\'.join(chr(o\xb06+\x1d\xcf\x7fXXXXXXXXXXaXXXXXXXi%len(key)] ^ 42) for i in range(len(ciphertext)))\n\n
flag = ''.join(chr(oX6+XXXXXXXXXXXXXaXXXXXXXi%len(key)] ^ 42) for i in range(len(ciphertext)))
flag = ''.join(chr(ord(ciphertext[i]) ^ key[i%len(key)] ^ 42) for i in range(len(ciphertext)))
78
Some of the notes :P
Lets try to get all the source code!
Input: open(__file__).read()
79
Lets try to get all the source code!
Input: open(__file__).read()
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '/proc/self/fd/100'
80
Wait what?
'/proc/self/fd/100'
$ mount
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
(...)
81
Wait what?
'/proc/self/fd/100'
$ mount
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
(...)
82
Wait what?
'/proc/self/fd/100'
$ mount
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
(...)
83
So...
The file was read by [C]Python… but it is not there anymore.
def disconnect_code():� print(� 'I am closin\' the',� __file__,
'file so it aint too eazy;',� 'you know, for your own fun.\n'� )� os.close(100)�
84
So...
The file was read by [C]Python… but it is not there anymore.
def disconnect_code():� print(� 'I am closin\' the',� __file__,
'file so it aint too eazy;',� 'you know, for your own fun.\n'� )� os.close(100)�
85
So...
The file was read by [C]Python… but it is not there anymore.
def disconnect_code():� print(� 'I am closin\' the',� __file__,
'file so it aint too eazy;',� 'you know, for your own fun.\n'� )� os.close(100)�
86
Here comes the fun part!
87
Can we break or hack the server?
I don’t know.
If you ask for permission:�Yes, you can try.
88
Can we break or hack the server?
I don’t know.
If you ask for permission:�Yes, you can try.
89
Can we break or hack the server?
I don’t know.
If you ask for permission:�Yes, you can try.
90
But… good luck!
91
Lets see some examples!
92
Lets see some examples!
Input: msg: __import__('os').fork()
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
BlockingIOError: [Errno 11] Resource temporarily unavailable
93
Lets see some examples!
Input: msg: __import__('os').fork()
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
BlockingIOError: [Errno 11] Resource temporarily unavailable
94
Lets see some examples!
Input: msg: os.system('cat /etc/passwd')
-1
95
So maybe DOS?
96
DOS?
Input: list(range(2**32))
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
MemoryError
97
DOS?
Input: list(range(2**32))
Traceback (most recent call last):
File "/proc/self/fd/100", line 188, in <module>
File "/proc/self/fd/100", line 184, in run
File "<string>", line 1, in <module>
MemoryError
98
Behind the scenes
99
nsjail
100
How is it done?
101
How is it done?
Tool created by Jagger from Dragon Sector CTF team
102
How is it done?
Tool created by Jagger from Dragon Sector CTF team
Funfact: he was supposed to be my manager in Google
103
How is it done?
Tool created by Jagger from Dragon Sector CTF team
Funfact: he was supposed to be my manager in Google but apparently I rejected them
104
How its build
105
Build
docker build -t test .
docker run -d -v /sys/fs/cgroup:/sys/fs/cgroup:rw -p 31337:31337 --privileged --rm test
106
Build
docker build -t test .
docker run -d -v /sys/fs/cgroup:/sys/fs/cgroup:rw -p 31337:31337 --privileged --rm test
107
Wait whaaaat? Rooot?
Build
FROM nsjail
RUN apt-get update && apt-get install -y python3
ADD . /task
RUN groupadd nobody
CMD /task/launch.sh
108
launch.sh
#!/bin/bash
mkdir -p /sys/fs/cgroup/{cpu,memory,pids}/NSJAIL
nsjail --config /task/nsjail.cfg 100<>/task/chall.py
109
nsjail.cfg
name: "Python challenges task"
description: "yolo"
mode: LISTEN
hostname: "OhYouHaxx0rThereIsNothingHere"
bindhost: "0.0.0.0"
port: 31337
110
nsjail.cfg
pass_fd: 0
pass_fd: 1
pass_fd: 2
pass_fd: 100
111
nsjail.cfg
pass_fd: 0
pass_fd: 1
pass_fd: 2
pass_fd: 100
keep_env: true
112
nsjail.cfg
time_limit: 60
max_cpus: 1
cgroup_pids_max: 1
rlimit_as: 64
rlimit_core: 0
rlimit_cpu: 10
rlimit_fsize: 0
rlimit_nofile: 32
rlimit_stack_type: SOFT
rlimit_nproc_type: SOFT
113
nsjail.cfg
uidmap {
inside_id: "1"
outside_id: "nobody"
}
gidmap {
inside_id: "1"
outside_id: "nobody"
}
114
nsjail.cfg
mount_proc: true
mount {
src: "/usr"
dst: "/usr"
is_bind: true
rw: false
}
mount {
src: "/lib"
dst: "/lib"
is_bind: true
rw: false
}
mount {
src: "/lib64"
dst: "/lib64"
is_bind: true
rw: false
}
mount {
src: "/bin"
dst: "/bin"
is_bind: true
rw: false
}
115
nsjail.cfg
mount {
src: "/task/fake_passwd"
dst: "/etc/passwd"
is_bind: true
rw: false
mandatory: true
is_dir: false
}
mount {
dst: "/tmp"
fstype: "tmpfs"
rw: true
}
116
nsjail.cfg
exec_bin {
path: "/usr/bin/python3"
arg0: "python3"
arg: "/proc/self/fd/100"
}
117
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
118
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
119
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
120
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
121
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
122
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
123
DEFAULT ALLOW
nsjail.cfg
seccomp_string: "POLICY example { "
seccomp_string: " ERRNO(1337) { getuid, getgid, geteuid, getegid }, "
seccomp_string: " ERRNO(0) { ptrace }, "
seccomp_string: " ALLOW { execve } "
seccomp_string: "} "
seccomp_string: "USE example DEFAULT ALLOW "
seccomp_log: true
124
DEFAULT ALLOW
LOL WUT?
And that’s all :)
125
Hope you enjoyed!
126
Thanks
127
PS
128
Make a lightning talk! :)
129
The end