Skip to content

Instantly share code, notes, and snippets.

@5unKn0wn
Last active July 12, 2020 08:20
Show Gist options
  • Save 5unKn0wn/333290e702cdaf2cf12cb9313c4d73a7 to your computer and use it in GitHub Desktop.
Save 5unKn0wn/333290e702cdaf2cf12cb9313c4d73a7 to your computer and use it in GitHub Desktop.
TSG CTF 2020 onnxrev write-up

ONNXrev

Given problem.py convert user input to png file. and parse each pixel and toss to onnx model.

We can load model using onnx python library then it deserialize model.

import onnx

onnx_model = onnx.load('problem.onnx')
print onnx_model

After some graph node analyzing, I noticed that loop does matrix multiplication.

So I recovered original input vector using sage. (solve_eq.sage)

Next, inversing ml-operation (conv, relu, gemm, ...) is too complex, so I patched problem.onnx to return ml-operated value.

For that, I patched coefficient matrix which used in problem.onnx to identity matrix for multiplication does not change any result. (patch.py)

And patched problem.onnx to return ml-operated value.

From now, we know all ml-operated values so it is time to find flag. (get_flag.py)

TSGCTF{OnNx_1s_4_kiNd_0f_e5oL4ng_I_7hink}

#!/usr/bin/python3
from PIL import Image, ImageFont, ImageDraw
import numpy
import onnxruntime
table1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmno"
table2 = "pqrstuvwxyz0123456789_!@#$%^&*()-?=,.{}~g"
assert(len(table1) == 41 and 'g' in table1)
assert(len(table2) == 41 and 'g' in table2)
font = ImageFont.truetype("Inconsolata-Regular.ttf", 40)
w, h = font.getsize(table1)
assert((w, h) == (20 * 41, 42))
img = Image.new('RGB', (w, h), (255, 255, 255))
ImageDraw.Draw(img).text((0, 0), table1, font=font, fill=(0, 0, 0))
flagimg = numpy.array(img).astype(numpy.float32)
enc_table1 = []
for i in onnxruntime.InferenceSession('problem_fix.onnx').run(None, {'flagimg': flagimg})[0].tolist():
enc_table1.append(i[0])
w, h = font.getsize(table2)
assert((w, h) == (20 * 41, 42))
img = Image.new('RGB', (w, h), (255, 255, 255))
ImageDraw.Draw(img).text((0, 0), table2, font=font, fill=(0, 0, 0))
flagimg = numpy.array(img).astype(numpy.float32)
enc_table2 = []
for i in onnxruntime.InferenceSession('problem_fix.onnx').run(None, {'flagimg': flagimg})[0].tolist():
enc_table2.append(i[0])
enc_flag = [71, 54, 32, 39, 71, 5, 91, 17, 40, 12, 33, 22, 31, 27, 22, 9, 22, 90, 52, 12, 73, 22, 56, 65, 22, 51, 42, 43, 75, 9, 40, 86, 22, 10, 22, 7, 14, 52, 40, 90, 77]
str_flag = ''
for i in range(len(enc_flag)):
if enc_flag[i] in enc_table1:
str_flag += (table1[enc_table1.index(enc_flag[i])])
elif enc_flag[i] in enc_table2:
str_flag += (table2[enc_table2.index(enc_flag[i])])
else:
print("nop")
print(str_flag)
import onnx
import numpy as np
onnx_model = onnx.load('problem.onnx')
# print onnx_model
main_graph = onnx_model.graph
loop2_graph = main_graph.node[4].attribute[0].g
# create identity matrix
A = [[0 for i in range(41)] for j in range(41)]
for i in range(41):
for j in range(41):
if i == j:
A[i][i - j] = 1
B = []
for i in range(41):
for j in range(41):
B.append(A[i][j])
# replace original coeff matrix to identity matrix
const_tensor = onnx.helper.make_tensor('const_tensor', onnx.TensorProto.INT64, dims=[41, 41], vals=np.array(B, dtype=np.int64))
iden_node = onnx.helper.make_node(
op_type='Constant',
inputs=[],
outputs=['__coeff_in'],
name='add',
value=const_tensor
)
main_graph.node.remove(main_graph.node[3])
main_graph.node.insert(3, iden_node)
# move loop1result+0 to loop1result_tmp tensor
add_node = onnx.helper.make_node(
op_type='Add',
inputs=['loop1result', '_const_0'],
outputs=['loop1result_tmp'],
name='add',
)
loop2_graph.node.insert(11, add_node)
# add loop1result_tmp at loop2 output node
loop1result_tmp = onnx.helper.make_tensor_value_info('loop1result_tmp', onnx.TensorProto.INT64, [41])
loop2_graph.output.append(loop1result_tmp)
# add loop1result_tmp at flagchecker output node
main_graph.node[4].output.append("loop1result_tmp")
# change finalans type to int64 in FlagChecker
correct_count_output = onnx.helper.make_tensor_value_info('finalans', onnx.TensorProto.INT64, [41, 41])
main_graph.output.remove(main_graph.output[0])
main_graph.output.insert(0, correct_count_output)
# set finalans to loop1result_tmp
correct_count_node = onnx.helper.make_node(
op_type='Identity',
inputs=['loop1result_tmp'],
outputs=['finalans'],
name='ident_count'
)
main_graph.node.remove(main_graph.node[7])
main_graph.node.insert(7, correct_count_node)
onnx.checker.check_model(onnx_model)
onnx.save(onnx_model, 'problem_fix.onnx')
targ = [89361184, 80981968, 73492790, 89181639, 97473769, 85327607, 83810248, 104809552, 68042087, 88541894, 90928878, 90139662, 83258934, 83443064, 76731934, 89646687, 67536184, 73961171, 67019031, 94703877, 75897128, 79466697, 97147521, 83300221, 69279142, 66382011, 94241218, 95515184, 66383600, 85854285, 73732274, 74687498, 82587813, 86508784, 78267515, 81466357, 80349118, 92624472, 78756214, 81810692, 87033817]
coeff = [[45957, 39414, 62401, 85992, 88267, 37062, 43647, 53422, 38781, 11317, 94026, 62902, 56861, 56087, 84097, 48579, 78311, 45585, 12669, 68075, 22299, 59269, 67409, 72291, 53160, 85448, 75397, 47089, 48408, 602, 59854, 6796, 81053, 46092, 61110, 63418, 21979, 17618, 13170, 71692, 32337], [40534, 49616, 29073, 45600, 59183, 50785, 43640, 11787, 88633, 54140, 20605, 80802, 40322, 91281, 11503, 98624, 414, 93382, 94199, 78561, 88267, 19543, 5755, 50472, 72400, 24222, 50483, 68686, 78370, 68069, 41296, 56598, 13019, 50460, 9099, 33369, 80000, 48857, 5379, 23895, 89744], [70640, 61789, 20339, 14157, 85732, 96225, 6651, 58052, 49137, 63227, 25005, 39628, 91130, 61646, 34294, 40830, 73980, 26684, 13316, 98546, 49351, 53219, 27364, 10292, 25694, 24666, 26199, 61692, 21841, 36229, 25328, 16527, 57025, 5694, 52359, 33516, 81891, 10198, 43633, 68417, 79839], [678, 62842, 35175, 63688, 47643, 10832, 86877, 80520, 90786, 12067, 86654, 51263, 63204, 6715, 70143, 57163, 97188, 61081, 18248, 83645, 2091, 33484, 22643, 9654, 81807, 23163, 40896, 72696, 60574, 33664, 97774, 76433, 24105, 61273, 84201, 46082, 38868, 72462, 81017, 87800, 55065], [50732, 67002, 35476, 48917, 90442, 41905, 94552, 91687, 45987, 97150, 20307, 63967, 81112, 87569, 72424, 1625, 56324, 16976, 5895, 97708, 79892, 92944, 90711, 90732, 38708, 17926, 68586, 6368, 81208, 93560, 73306, 34259, 88116, 68371, 18427, 13061, 64913, 51656, 23437, 56925, 47463], [43572, 78593, 77234, 59005, 29881, 62681, 47176, 71986, 30690, 80462, 78702, 27578, 26578, 72297, 7367, 12050, 38514, 34910, 8677, 90882, 60251, 53878, 67205, 18629, 46799, 61512, 16215, 1770, 44391, 90338, 46036, 19969, 50167, 96343, 37742, 7805, 74006, 67394, 33388, 86952, 76252], [41687, 76444, 97345, 7925, 37341, 28261, 80532, 35081, 1348, 99707, 6722, 35188, 59286, 39223, 66177, 74427, 57034, 1214, 48418, 73443, 49005, 67460, 75605, 54155, 96967, 19047, 15381, 8388, 41559, 41296, 99840, 66104, 54755, 43047, 18801, 68076, 39499, 30486, 42528, 80046, 47566], [75896, 99462, 33401, 56507, 57972, 71230, 96548, 45119, 55484, 71561, 33350, 89167, 39339, 66489, 71128, 17510, 93737, 76016, 83302, 71422, 2982, 13365, 71703, 90581, 90036, 72095, 54739, 29486, 59316, 8014, 86747, 95050, 66803, 23297, 28617, 38744, 30554, 40720, 16596, 29987, 72758], [49299, 71322, 10449, 4217, 52688, 12282, 82939, 82227, 50428, 729, 32126, 23736, 24458, 11481, 51379, 52710, 99036, 65070, 34214, 85734, 66690, 14905, 78696, 40137, 63121, 14936, 5988, 21404, 2053, 63604, 26261, 52929, 44054, 31590, 97800, 98511, 99097, 23827, 3496, 41859, 90825], [34152, 86805, 64726, 12743, 83421, 37915, 95847, 94378, 9122, 50907, 98189, 62682, 68648, 75412, 47797, 6636, 39097, 92080, 86590, 60733, 51941, 53297, 72031, 47270, 67340, 73042, 4264, 51700, 75993, 47942, 7575, 47041, 23706, 29204, 65159, 72353, 58170, 26299, 60488, 88104, 22883], [55934, 61014, 8790, 4423, 5410, 89035, 55333, 57360, 99343, 76429, 94550, 53180, 30674, 40185, 10797, 51074, 10554, 33468, 2949, 48701, 96277, 41969, 55791, 80243, 78309, 28627, 63923, 34322, 34204, 70071, 79270, 56136, 71159, 92283, 63280, 119, 58162, 10600, 83170, 79189, 58677], [95891, 82893, 11633, 82436, 40758, 80000, 2272, 50863, 87309, 29120, 99377, 82309, 48395, 11918, 80372, 20771, 69517, 17499, 49918, 1540, 84746, 42832, 82916, 24641, 59988, 36714, 5267, 21474, 91177, 36731, 86315, 17454, 89662, 56958, 38547, 11725, 60828, 56588, 84831, 57911, 56581], [47819, 56363, 64498, 70932, 9068, 87221, 59160, 92067, 64119, 96641, 69527, 61276, 5759, 6835, 82987, 46853, 8538, 63923, 88311, 58124, 70419, 21680, 8432, 38861, 59063, 99365, 45297, 48609, 58006, 65793, 91100, 54646, 40870, 10258, 66271, 36718, 54248, 38301, 24558, 74331, 64561], [17430, 31191, 25179, 17861, 97882, 75394, 96423, 98977, 18053, 23358, 70569, 62327, 52649, 54592, 14344, 7470, 24303, 88132, 61450, 14628, 482, 48549, 62923, 43760, 26246, 82566, 58225, 34924, 62589, 33462, 74703, 44250, 55003, 3307, 67158, 88588, 61950, 93542, 36189, 15291, 30185], [88901, 38166, 70063, 99817, 21852, 37800, 52513, 8344, 38965, 11393, 50377, 57967, 77861, 38636, 96398, 8379, 16773, 1433, 85113, 99140, 695, 64939, 91811, 13603, 5318, 12312, 46938, 87213, 72147, 38395, 17376, 90786, 5473, 97125, 36057, 14525, 47738, 51165, 78645, 10243, 80513], [62842, 14580, 85854, 12729, 60141, 93894, 65585, 57009, 86282, 40225, 50347, 13260, 32102, 29409, 92982, 81150, 10575, 93309, 50059, 29288, 56283, 91933, 1191, 48762, 1756, 40996, 88875, 52801, 56171, 62140, 50334, 40664, 84244, 8821, 76584, 39159, 91837, 16191, 47054, 84340, 63627], [28108, 31743, 93087, 33144, 71257, 74917, 81966, 5275, 48845, 67491, 43587, 85459, 6015, 35736, 36441, 71910, 59123, 24531, 74908, 23125, 92970, 98420, 40159, 50210, 19487, 6680, 4503, 66780, 31520, 3883, 23976, 13760, 4208, 40591, 7523, 31854, 82105, 38383, 26463, 93406, 28892], [63269, 47286, 38415, 72484, 37, 88104, 76207, 10522, 93736, 23407, 27876, 86077, 98547, 62757, 91215, 73978, 79622, 3334, 36562, 13074, 43166, 1610, 19739, 57354, 49274, 59157, 39669, 45213, 21136, 49610, 37852, 15814, 30081, 89224, 96794, 69047, 25259, 69940, 4738, 57210, 11698], [33601, 6194, 63960, 66680, 27875, 20449, 87230, 57427, 19815, 80137, 24540, 46933, 21187, 44015, 21076, 8159, 63626, 70763, 85412, 2922, 5857, 39817, 68287, 26619, 6666, 6474, 11993, 92020, 24537, 202, 99322, 66802, 42407, 40408, 2594, 97121, 84477, 78104, 8159, 70467, 57736], [97635, 75238, 30766, 24222, 61939, 94540, 49192, 82616, 86566, 16281, 601, 33986, 65214, 82063, 45328, 41329, 40438, 33654, 42185, 56714, 96669, 58919, 24999, 56976, 49389, 24057, 72147, 34687, 96169, 64175, 36667, 56288, 55516, 51016, 25230, 75264, 97060, 74556, 26510, 69189, 67567], [89762, 10739, 47632, 2558, 24563, 91972, 70282, 9874, 56139, 48287, 60865, 15829, 97260, 67905, 20958, 93652, 94468, 57503, 87101, 96421, 27858, 44220, 14422, 39072, 31087, 67480, 67036, 87045, 60901, 86023, 72304, 35383, 11874, 13139, 5472, 26824, 32932, 36403, 49361, 40176, 11153], [25911, 70386, 31855, 88573, 15675, 86023, 42757, 18331, 62359, 45559, 60386, 14124, 39639, 79323, 99911, 37824, 61449, 5411, 25464, 86237, 72248, 35810, 46527, 81052, 14455, 55023, 6774, 10874, 39698, 94248, 65917, 87277, 23475, 35096, 11573, 25053, 91964, 16146, 47209, 61978, 33906], [72708, 5846, 82425, 70042, 92118, 46926, 99748, 84029, 95951, 38946, 58294, 31870, 31511, 75260, 77128, 81842, 86366, 89313, 8414, 93719, 20036, 17579, 71259, 79490, 46097, 58962, 68049, 65158, 84603, 22195, 77686, 85081, 17689, 64695, 68206, 60053, 79256, 17403, 70893, 86949, 48080], [63481, 82136, 26730, 86986, 30681, 48852, 67051, 78904, 79532, 70482, 90441, 55178, 20947, 58726, 96351, 48534, 8874, 3222, 3545, 43141, 25874, 63866, 16787, 39546, 2395, 60206, 25972, 70953, 68332, 88326, 9556, 45139, 36109, 67486, 23526, 24172, 43460, 89255, 71495, 80463, 10078], [17778, 65251, 1285, 62463, 37759, 61051, 8505, 64025, 55714, 98535, 47280, 90858, 8265, 98740, 4395, 13257, 45469, 35499, 49799, 12170, 91052, 71864, 85522, 48599, 24365, 12030, 82582, 42127, 52567, 63304, 81337, 899, 99128, 31739, 15695, 5968, 26817, 6825, 10416, 37507, 29183], [40132, 47210, 19092, 26973, 4139, 56172, 55629, 13156, 34846, 18491, 35921, 58149, 84653, 98832, 20129, 4198, 25291, 74817, 72851, 23533, 98377, 3994, 26429, 21311, 24944, 24792, 88977, 59900, 77708, 60281, 88563, 51128, 74212, 61327, 60128, 48166, 44676, 23874, 1812, 3458, 37468], [98520, 77138, 66949, 96404, 54973, 2885, 64796, 68431, 87407, 1031, 1873, 89218, 11388, 35524, 10524, 45758, 40551, 813, 66830, 256, 89887, 79522, 63368, 1171, 16063, 73005, 86255, 21851, 77367, 58443, 89810, 93191, 88743, 13992, 54566, 27434, 14051, 92903, 25888, 98699, 55535], [71776, 85140, 17114, 9229, 78740, 85340, 34142, 77215, 83518, 36863, 96162, 16967, 5352, 60644, 26344, 75360, 83584, 81913, 76287, 34572, 53867, 17653, 35255, 79871, 88904, 64058, 25214, 33058, 2339, 79587, 59513, 93668, 15772, 48695, 44003, 65361, 68650, 78212, 83158, 18935, 28923], [2069, 35318, 15291, 96733, 20051, 63285, 34282, 33387, 93908, 44246, 20774, 76579, 67757, 18802, 4536, 34432, 67542, 497, 81052, 18442, 7635, 69903, 26247, 59455, 13111, 24251, 37194, 1203, 27177, 83941, 12808, 89893, 24138, 74306, 16193, 77880, 12540, 13434, 3302, 88216, 7553], [13617, 14694, 58857, 96331, 72178, 84436, 9749, 12473, 88688, 86412, 5295, 26365, 54020, 9961, 24124, 13730, 99705, 95547, 62459, 44968, 69873, 50430, 65993, 86637, 23581, 77253, 11105, 71951, 57176, 20575, 77176, 89490, 26032, 23590, 22290, 10484, 112, 30273, 90757, 1841, 87943], [92018, 96059, 10110, 5457, 31244, 45691, 14920, 67231, 25392, 94071, 96836, 68860, 69231, 347, 82464, 83648, 47044, 61160, 33698, 19341, 290, 43676, 61022, 34595, 22457, 62106, 22163, 12792, 46664, 30473, 2595, 82793, 22961, 55159, 47450, 95455, 48543, 76545, 68011, 91937, 88620], [9917, 78480, 42337, 40941, 31567, 83049, 38554, 15749, 33837, 31373, 1633, 76201, 95272, 43951, 94469, 16985, 3874, 37238, 1041, 93260, 31188, 23112, 46036, 97149, 44998, 65887, 66837, 14963, 27722, 94133, 17060, 23469, 10688, 57557, 12081, 53794, 73313, 39194, 24279, 80519, 81990], [89025, 25334, 57677, 45742, 35790, 78230, 67877, 67068, 83452, 55543, 58334, 32351, 69080, 66008, 68182, 69642, 16538, 6778, 96000, 78084, 40118, 73013, 2396, 76217, 56189, 47518, 37147, 73338, 47396, 9486, 5586, 24315, 79416, 26234, 79960, 4076, 21106, 73514, 54445, 2480, 24113], [85545, 48895, 53954, 67276, 94007, 17562, 99775, 98304, 81641, 99786, 43915, 34046, 3564, 95871, 69408, 27583, 55485, 47238, 61049, 86619, 34862, 31118, 86057, 41195, 36925, 99497, 11613, 24039, 13394, 93097, 29091, 87306, 24560, 81661, 3631, 9469, 25826, 67764, 83183, 41809, 39561], [75064, 50334, 22459, 3967, 96796, 85027, 41667, 61194, 29175, 30631, 14793, 24327, 83006, 2627, 16745, 52916, 66245, 78969, 12843, 53088, 29516, 33245, 61056, 17387, 8904, 64005, 76583, 96759, 32691, 91617, 17467, 18701, 11101, 96441, 31627, 75405, 95786, 85144, 2652, 95516, 28980], [545, 93669, 43348, 37757, 27698, 77572, 31606, 39535, 61872, 35510, 49222, 85730, 16958, 81017, 85936, 5470, 13966, 56115, 68075, 34133, 77669, 32676, 93385, 9616, 69367, 18326, 44831, 44831, 3736, 81698, 79957, 13643, 84659, 28286, 79286, 36417, 78381, 57363, 11942, 26874, 89257], [77675, 6717, 78123, 84949, 93762, 8817, 71966, 35966, 30790, 32468, 69439, 25035, 24384, 73583, 46178, 80962, 73000, 50361, 86520, 91697, 28071, 38934, 41688, 88052, 55633, 75074, 58267, 41612, 88768, 33861, 2085, 35163, 18524, 27365, 54681, 61452, 4402, 52637, 72446, 25564, 8484], [99408, 73257, 23574, 71571, 48007, 28150, 84762, 62273, 66788, 7245, 48454, 14208, 73238, 72852, 48459, 3391, 60393, 48336, 93511, 97835, 87153, 31375, 81982, 31198, 21566, 96757, 39923, 51272, 19959, 78849, 67542, 70402, 93753, 78398, 18589, 40776, 78320, 96847, 25020, 17170, 13515], [16589, 85945, 38357, 84870, 96192, 99979, 79124, 3989, 43645, 16987, 83209, 12566, 52616, 36679, 92033, 53734, 93051, 82258, 40938, 62664, 23908, 32958, 19507, 1639, 62313, 67418, 11243, 77326, 27791, 73996, 40886, 67881, 92687, 96829, 41814, 45868, 19589, 20071, 63959, 37072, 10919], [86298, 39825, 17502, 36434, 45611, 45230, 89485, 73627, 97113, 38209, 90945, 6758, 78898, 57340, 15611, 24489, 38665, 82797, 95297, 52939, 1875, 2724, 35511, 83138, 54271, 2429, 13394, 68609, 31361, 41545, 33329, 18171, 6419, 44050, 28534, 62180, 23599, 86386, 58002, 95596, 26792], [82971, 17148, 50941, 43289, 75469, 45349, 72369, 95801, 91653, 41752, 67857, 62757, 48313, 29130, 30172, 42233, 58488, 37692, 54009, 52739, 20278, 77786, 68916, 63082, 25777, 89413, 42779, 18480, 43385, 81146, 71119, 67139, 42480, 93414, 47620, 94796, 82678, 6479, 14009, 74806, 88866]]
A = Matrix(IntegerModRing(2^64), 41, 41)
for i in range(41):
for j in range(41):
A[i, j] = coeff[i][i - j]
b = vector(IntegerModRing(2^64), targ)
print([int(i) & 0xff for i in A.solve_right(b)])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment