pickled-rolls
problem
from pickle import loads
flag = loads(bytes.fromhex('80047d284b2a4b754b124b374b264b674b154b5f4b284b724b1e4b5f4b054b704b194b334b224b5f4b074b634b2c4b7d4b114b5f4b134b684b104b6d4b0f4b304b0a4b334b244b344b204b724b254b6e4b1a4b724b234b644b1b4b6e636f730a72656d6f76650a635f5f6d61696e5f5f0a5f5f66696c655f5f0a8552304b084b6b4b034b664b0b4b354b0e4b724b1c4b334b214b334b294b304b044b7b4b184b374b144b334b2b4b354b1f4b344b0d4b664b174b6e4b014b634b004b694b0c4b5f4b274b334b1d4b374b024b744b064b314b094b314b164b317530636261736536340a6236346465636f64650a566148523063484d364c7939336433637565573931644856695a53356a62323076643246305932672f646a316b55586330647a6c585a31686a55513d3d0a85522e'))
print(flag)
solution
the pickle data prints the rickroll link and deletes the file we saved the program to, so we have to figure out a way to extract the pickle data.
here, we can use the pickletools
python module to analyse the code:
import pickletools
pickletools.dis(bytes.fromhex('80047d284b2a4b754b124b374b264b674b154b5f4b284b724b1e4b5f4b054b704b194b334b224b5f4b074
b634b2c4b7d4b114b5f4b134b684b104b6d4b0f4b304b0a4b334b244b344b204b724b254b6e4b1a4b724b234b644b1b4b6e636f730a72656d6f76650
a635f5f6d61696e5f5f0a5f5f66696c655f5f0a8552304b084b6b4b034b664b0b4b354b0e4b724b1c4b334b214b334b294b304b044b7b4b184b374b1
44b334b2b4b354b1f4b344b0d4b664b174b6e4b014b634b004b694b0c4b5f4b274b334b1d4b374b024b744b064b314b094b314b164b3175306362617
36536340a6236346465636f64650a566148523063484d364c7939336433637565573931644856695a53356a62323076643246305932672f646a316b5
5586330647a6c585a31686a55513d3d0a85522e'))
output:
0: \x80 PROTO 4
2: } EMPTY_DICT
3: ( MARK
4: K BININT1 42
6: K BININT1 117
8: K BININT1 18
10: K BININT1 55
12: K BININT1 38
14: K BININT1 103
16: K BININT1 21
18: K BININT1 95
20: K BININT1 40
22: K BININT1 114
24: K BININT1 30
26: K BININT1 95
28: K BININT1 5
30: K BININT1 112
32: K BININT1 25
34: K BININT1 51
36: K BININT1 34
38: K BININT1 95
40: K BININT1 7
42: K BININT1 99
44: K BININT1 44
46: K BININT1 125
48: K BININT1 17
50: K BININT1 95
52: K BININT1 19
54: K BININT1 104
56: K BININT1 16
58: K BININT1 109
60: K BININT1 15
62: K BININT1 48
64: K BININT1 10
66: K BININT1 51
68: K BININT1 36
70: K BININT1 52
72: K BININT1 32
74: K BININT1 114
76: K BININT1 37
78: K BININT1 110
80: K BININT1 26
82: K BININT1 114
84: K BININT1 35
86: K BININT1 100
88: K BININT1 27
90: K BININT1 110
92: c GLOBAL 'os remove'
103: c GLOBAL '__main__ __file__'
122: \x85 TUPLE1
123: R REDUCE
124: 0 POP
125: K BININT1 8
127: K BININT1 107
129: K BININT1 3
131: K BININT1 102
133: K BININT1 11
135: K BININT1 53
137: K BININT1 14
139: K BININT1 114
141: K BININT1 28
143: K BININT1 51
145: K BININT1 33
147: K BININT1 51
149: K BININT1 41
151: K BININT1 48
153: K BININT1 4
155: K BININT1 123
157: K BININT1 24
159: K BININT1 55
161: K BININT1 20
163: K BININT1 51
165: K BININT1 43
167: K BININT1 53
169: K BININT1 31
171: K BININT1 52
173: K BININT1 13
175: K BININT1 102
177: K BININT1 23
179: K BININT1 110
181: K BININT1 1
183: K BININT1 99
185: K BININT1 0
187: K BININT1 105
189: K BININT1 12
191: K BININT1 95
193: K BININT1 39
195: K BININT1 51
197: K BININT1 29
199: K BININT1 55
201: K BININT1 2
203: K BININT1 116
205: K BININT1 6
207: K BININT1 49
209: K BININT1 9
211: K BININT1 49
213: K BININT1 22
215: K BININT1 49
217: u SETITEMS (MARK at 3)
218: 0 POP
219: c GLOBAL 'base64 b64decode'
237: V UNICODE 'aHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj1kUXc0dzlXZ1hjUQ=='
299: \x85 TUPLE1
300: R REDUCE
301: . STOP
here, we can see a base64 decode for the rickroll link
take a look at the documentation here and see the different opcodes that pickle uses.
we can see that there is a lot of BININT1 opcodes here, and also that there is an empty dict created at the beginning of the opcodes.
from this, we can infer that the integers are dictionary item data, and so we can reassemble the dictionary using text format wizard
{42: 117
18: 55
38: 103
21: 95
40: 114
30: 95
5: 112
25: 51
34: 95
7: 99
44: 125
17: 95
19: 104
16: 109
15: 48
10: 51
36: 52
32: 114
37: 110
26: 114
35: 100
27: 110
8: 107
3: 102
11: 53
14: 114
28: 51
33: 51
41: 48
4: 123
24: 55
20: 51
43: 53
31: 52
13: 102
23: 110
1: 99
0: 105
12: 95
39: 51
29: 55
2: 116
6: 49
9: 49
22: 49}
these are just decimal codes for ascii chars, we can just sort them with python or decode by hand (which i did)
the flag is ictf{p1ck135_fr0m_7h3_1n73rn37_4r3_d4ng3r0u5}