Contents

picoCTF - Reverse Engineering - bloat.py


Reverse Engineering - bloat.py - writeup

description

Can you get the flag?

Run this Python program in the same directory as this encrypted flag.

writeup

So let’s download the python program and the encrypted flag first!

1
wget https://artifacts.picoctf.net/c/434/bloat.flag.py
1
wget https://artifacts.picoctf.net/c/434/flag.txt.enc

Let’s make a copy of the python program and try to fix it using debugging in bpython!

1
cp bloat.flag.py flag.py

After a lot of debugging and reverse engineering using bpython I found the flag!

1
bpython
 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
bpython Version 0.22.1 mit Python 3.9.10 /usr/bin/python3
>>> import sys;
>>> a = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "
>>> def arg133(arg432):
...   if arg432 == a[71]+a[64]+a[79]+a[79]+a[88]+a[66]+a[71]+a[64]+a[77]+a[66]+a[68]:
...     return True
...   else:
...     print(a[51]+a[71]+a[64]+a[83]+a[94]+a[79]+a[64]+a[82]+a[82]+a[86]+a[78]+\
... a[81]+a[67]+a[94]+a[72]+a[82]+a[94]+a[72]+a[77]+a[66]+a[78]+a[81]+\
... a[81]+a[68]+a[66]+a[83])
...     sys.exit(0)
...     return False
... 
>>> def arg111(arg444):
...   return arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\
... a[75]+a[72]+a[78]+a[77])
... 
>>> def arg232():
...   return input(a[47]+a[75]+a[68]+a[64]+a[82]+a[68]+a[94]+a[68]+a[77]+a[83]+\
... a[68]+a[81]+a[94]+a[66]+a[78]+a[81]+a[81]+a[68]+a[66]+a[83]+\
... a[94]+a[79]+a[64]+a[82]+a[82]+a[86]+a[78]+a[81]+a[67]+a[94]+\
... a[69]+a[78]+a[81]+a[94]+a[69]+a[75]+a[64]+a[70]+a[25]+a[94])
... 
>>> def arg132():
...   return open('flag.txt.enc', 'rb').read()
... 
>>> pwd()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    pwd()
NameError: name 'pwd' is not defined
>>> def arg112():
...   print(a[54]+a[68]+a[75]+a[66]+a[78]+a[76]+a[68]+a[94]+a[65]+a[64]+a[66]+\
... a[74]+a[13]+a[13]+a[13]+a[94]+a[88]+a[78]+a[84]+a[81]+a[94]+a[69]+\
... a[75]+a[64]+a[70]+a[11]+a[94]+a[84]+a[82]+a[68]+a[81]+a[25])
... 
>>> def arg122(arg432, arg423):
...     arg433 = arg423
...     i = 0
...     
...     while len(arg433) < len(arg432):
...         arg433 = arg433 + arg423[i]
...         i = (i + 1) % len(arg423)        
...     
...     return "".join([chr(ord(arg422) ^ ord(arg442)) for (arg422,arg442) in zip(arg432,arg433)])
... 
>>> arg112()
Welcome back... your flag, user:
>>> def arg232()
  File "<input>", line 1
    def arg232()
                ^
SyntaxError: invalid syntax
>>> arg232()
Please enter correct password for flag: Traceback (most recent call last):
  File "<input>", line 1, in <module>
    arg232()
  File "<input>", line 2, in arg232
    return input(a[47]+a[75]+a[68]+a[64]+a[82]+a[68]+a[94]+a[68]+a[77]+a[83]+\
  File "/usr/lib/python3/dist-packages/bpython/curtsiesfrontend/repl.py", line 168, in readline
    value = self.coderunner.request_from_main_context()
  File "/usr/lib/python3/dist-packages/bpython/curtsiesfrontend/coderunner.py", line 200, in request_from_main_
context
    raise KeyboardInterrupt()
KeyboardInterrupt
>>> arg112()
Welcome back... your flag, user:
>>> arg132()
b'\x02\x08\x13\x1c 5*\x17\r\\^\x10\x07\x05F\x00U[]Y\x011\x14V\x07,\x06X\t_Q\x0c\\E\x1c'
>>> arg232()
Please enter correct password for flag: bla
'bla'
>>> arg132()
b'\x02\x08\x13\x1c 5*\x17\r\\^\x10\x07\x05F\x00U[]Y\x011\x14V\x07,\x06X\t_Q\x0c\\E\x1c'
>>> arg232()
Please enter correct password for flag: test
'test'
>>> arg133(arg432)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    arg133(arg432)
NameError: name 'arg432' is not defined
>>> arg432 = arg232()
Please enter correct password for flag: test
>>> arg133(arg432)
>>> arg133(arg432)
1
bpython
 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
bpython Version 0.22.1 mit Python 3.9.10 /usr/bin/python3
>>> a = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ "
>>> def arg232():
...   return input(a[47]+a[75]+a[68]+a[64]+a[82]+a[68]+a[94]+a[68]+a[77]+a[83]+\
... a[68]+a[81]+a[94]+a[66]+a[78]+a[81]+a[81]+a[68]+a[66]+a[83]+\
... a[94]+a[79]+a[64]+a[82]+a[82]+a[86]+a[78]+a[81]+a[67]+a[94]+\
... a[69]+a[78]+a[81]+a[94]+a[69]+a[75]+a[64]+a[70]+a[25]+a[94])
... 
>>> print(arg232());
Please enter correct password for flag: 

>>> arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\
... a[75]+a[72]+a[78]+a[77])
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\
NameError: name 'arg122' is not defined
>>> def arg122(arg432, arg423):
...     arg433 = arg423
...     i = 0
...     
...     while len(arg433) < len(arg432):
...         arg433 = arg433 + arg423[i]
...         i = (i + 1) % len(arg423)        
...     
...     return "".join([chr(ord(arg422) ^ ord(arg442)) for (arg422,arg442) in zip(arg432,arg433)])
... 
>>> print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\)
  File "<input>", line 1
    print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\)
                                                                             ^
SyntaxError: unexpected character after line continuation character
>>> a[75]+a[72]+a[78]+a[77])
  File "<input>", line 1
    a[75]+a[72]+a[78]+a[77])
                           ^
SyntaxError: unmatched ')'
>>> print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\)
  File "<input>", line 1
    print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+\)
                                                                             ^
SyntaxError: unexpected character after line continuation character
>>> a[75]+a[72]+a[78]+a[77])
  File "<input>", line 1
    a[75]+a[72]+a[78]+a[77])
                           ^
SyntaxError: unmatched ')'
>>> print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+a[75]+a[72]+a[78]+a[77]))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+a[75]+a[72]+a[78]+a[77]))
NameError: name 'arg444' is not defined
>>> arg444 = arg132()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    arg444 = arg132()
NameError: name 'arg132' is not defined
>>> def arg132():
...   return open('flag.txt.enc', 'rb').read()
... 
>>> arg444 = arg132()
>>> print(arg122(arg444.decode(), a[81]+a[64]+a[79]+a[82]+a[66]+a[64]+a[75]+a[75]+a[72]+a[78]+a[77]))
picoCTF{d30bfu5c4710n_f7w_e9e38c27}

So the flag is:

1
picoCTF{d30bfu5c4710n_f7w_e9e38c27}