比赛的时候只做出来excel_crackme, 赛后复现学到了不少~

VolgaCTF_excel_crackme

前置知识

vba

没遇见过vba语法, 记录一下~

<> 不等于, 相当于!==
Range 引用单元格
CLng(Expression)(将Expression转换为Long自类型, 即长整型, 其取值范围是-2147483648-2147483647)
cells(*).value 单元格的值
Mid()函数返回给定输入字符串中指定数量的字符。
从1开始
asc()函数返回第一个字母的ascii值
INT()向下取证
CInt()是对字符类型的数字, 转换成数值类型, 是类型转换
& 字符串连接
chr(10):换行, 相当于VBLF
chr(13):回车, 相当于VBCR

OLEVBA

安装

pip install -U https://github.com/decalage2/oletools/archive/master.zip

版本要求2.7.9以上

使用

olevba -c *.xmls // 可以获得excel、word等vba代码

之后就可以获得代码了, 如下

核心代码

Private Sub VolgaCTF()
Dim String As String
Dim Long_var1 As Long
Dim Long_var2 As Long
Dim CLAO4r As Long
String = Range(Chr(76) & Chr(&H31) & Chr(Int("53")))
For var3 = 1 To Len( String)
Long_var1 = 0
For hbzugliakq = 1 To Len( String)
Long_var2 = CInt(Cells(99 + var3, 99 + hbzugliakq).Value)
rJ1UnHB = Mid( String, hbzugliakq, 1)
Long_var1 = Long_var1 + Long_var2 * Asc(rJ1UnHB)
Next hbzugliakq
CLAO4r = CLng(Cells(99 + var3, 99 + Len( String) + 1).Value)
If (CLAO4r <> Long_var1) Then
MsgBox mWfDCE1CY0a(Chr(350416 / 2896) & Chr(Int("114")) & Chr(Int("&H72")) & Chr(Int("57")) & Chr(&H56) & Chr(&H75) & "q" & Chr(Int("113")) & Chr(4751 - 4652) & Chr(Int("69")) & Chr(&H54) & Chr(&H67) & Chr(Int("&H59")) & Chr(102) & "V" & Chr(Int("86")))
Exit Sub
End If
Next var3
MsgBox mWfDCE1CY0a(Chr(Int("109")) & "q" & Chr(Int("49")) & Chr(Int("57")) & Chr(&H56) & Chr(&H65) & Chr(76) & Chr(Int("112")) & Chr(Int("86")) & "F" & Chr(Int("114")) & Chr( - 343 + 395) & Chr(&H32) & Chr(72) & Chr(Int("&H31")) & Chr(100))
End Sub

简化代码如下:

string = "input"
const_number = [?][?]
for i in range(len(string)):
sum = 0;
for j in range(len(string)):
sum += (ord(string) * const[i][j])
if sum != const[i][len(string)+1]:
"fail"

根据猜测, excel文件中存在着常数, 将单元格背景变白可以发现常数(截图截取一部分):

UTOOLS1585554738591.png

解题

可以用z3求解满足的的数:

from z3 import *

number = [[620, 340, 895, -39, 945, 321, 586, 487, -935, -641, -233, 553, 546, 389, 764, -199, 577, -539, 547, -50, 134, -722, 134,
571, 629, -775, 499, -633, -928, -103, 975, 961, -275, 136, 165, 170, 257, 559, -656, -207, 403, -414, 371, 885, -885, 490493],
[-19, 85, -456, 228, -127, -777, 191, 605, 292, -181, -652, 801, -801, -890, -75, 214, 22, -52, -4, 750, 678, -300, 82,
965, -889, -342, 933, 736, -677, 945, -191, 408, -96, 916, -739, 454, -941, 72, 414, -373, 150, -535, 742, -376, -285, -7845],
[598, 357, 236, 8, -163, 787, -996, 26, -685, 257, -620, -959, 340, -530, -621, 634, -701, -112, 737, -781, 66, 517, 566, -915,
907, -818, -487, -82, -115, 313, 414, 836, 774, -776, -551, 920, -548, 898, -198, 244, 822, -741, -185, -589, 202, -54593],
[967, -357, -421, -752, -315, 413, 991, 350, 873, -122, 12, -463, -942, 576, 657, -108, -375, 481, 622, -550, -910, 167, -184, -
392, -111, 457, -606, 31, -350, 583, -716, 57, 985, 842, 222, 605, -239, -250, 280, 579, -109, -297, -99, -222, 605, 210672],
[-874, -571, 298, 241, -862, -863, 439, 518, 702, -237, -885, -676, 280, -461, 756, -7, -4, -278, 717, -913, 287, 625, -821,
681, -940, 150, -433, -866, -648, 817, -559, 385, -521, -703, -86, -278, -301, 444, -447, 69, -635, -178, 787, 766, 584, -407144],
[742, 811, 851, 366, -213, 994, 838, -710, 852, 787, -997, 657, -337, 126, 165, 138, 821, 340, 960, -55, -676, -445, -369, -
525, 605, 606, 306, 472, -946, -565, -224, 681, -937, 6, 784, 6, 543, -299, -203, -834, 963, -762, -706, 851, -119, 533417],
[-933, 546, -626, -24, 285, 893, 838, 573, 33, -469, -221, -318, -591, -209, 332, 525, -126, -82, -116, 567, 155, 357, -772, -
951, -349, -472, -774, -979, 346, 115, -45, -132, -795, -161, 373, 344, -910, 747, 469, 105, 159, 985, -77, -262, -225, -320176],
[-913, -741, -707, 915, 754, -495, -685, -931, 131, 347, 372, -343, -406, 783, -910, -77, 28, 283, 685, -649, -392, 446, -12,
568, -918, -849, 984, 747, -447, -781, 837, -484, 758, -434, 425, -631, -154, 858, -630, 563, 670, -328, -428, 530, -443, -83622],
[-853, -767, -218, -405, 147, -605, 319, -586, 907, 971, 531, 465, -803, 271, 608, 801, 982, -962, 446, -637, -436, 980, 51,
758, -746, 796, 448, 536, -483, -288, -917, 980, -365, -490, -265, -620, -142, -939, 919, 821, -934, -646, 791, -546, 921, 147210],
[-972, 556, 289, 522, 407, 376, -533, -433, 22, -227, -951, 6, -347, 536, 290, 195, -146, 129, -576, -444, -15, -405, -55, -270,
745, -35, -611, 238, -800, -840, 614, 632, 321, -597, -420, -849, -996, -881, -367, -113, 614, -654, 286, 427, 5, -344141],
[641, 496, 18, -939, 480, 453, 224, 721, -826, -148, 76, -491, 270, 684, -265, 574, -548, 507, 644, -792, -39, 237, 185, 893,
488, 423, 837, -184, -415, 28, -172, -86, 574, -284, -702, 396, 949, -372, 951, -221, 286, -336, -793, 417, 645, 507384],
[265, 870, -466, -520, -305, -730, 756, -957, -178, 934, 136, 294, 398, 728, 694, -700, -161, -477, -558, 148, 514, 349, 921,
348, 514, -952, -778, 741, -57, -564, 530, -97, -303, 953, 147, -946, 742, 823, 24, -538, -102, 710, 796, 351, 121, 429295],
[-127, 308, -696, -718, 824, 654, -825, -551, -519, -303, -511, 671, -169, -887, 353, -749, -924, 912, 858, 541, -701, 472, -12,
208, -386, 75, 30, 27, 827, 934, 471, 156, 586, -278, 412, -81, -958, -391, -531, -913, -991, -211, -814, -338, 610, -272727],
[-486, 934, 153, 439, 623, 320, 361, -781, 573, 95, 658, -43, -27, -441, -228, 596, 614, 467, -937, -823, -3, -567, -689, -
507, 372, 842, -11, -755, 259, 251, -950, 698, 489, 297, -792, -162, 728, -897, 718, 28, 513, -814, 653, 163, 780, 309196],
[863, 695, -670, -103, 150, -592, -39, 197, -819, -977, -513, -997, -895, 718, 501, 168, -505, 399, -593, 98, 254, 983, -416,
288, 20, -826, -965, 353, -925, 756, 546, -443, 752, 359, 343, 848, -666, -249, -752, -617, 470, 617, 337, -432, 73, -247072],
[-164, -912, 580, -267, -731, 51, 405, 618, 35, -8, 367, -118, -706, -445, 157, -426, -471, -583, -632, 40, 326, 947, -473, -169,
655, -647, 620, 110, -347, -646, 127, -444, -95, -679, 557, -225, -777, -58, -528, -800, 931, -628, 25, -497, 639, -382979],
[900, -14, 496, -465, -910, -724, -460, 158, 452, -2, -547, 682, 588, 968, 915, -304, -146, 743, -632, -511, -488, -840, 436, -
175, 391, -638, -185, 231, 39, 328, -306, 772, 382, -96, -349, -663, -123, 343, 64, -581, 173, 323, 14, 396, -736, -29820],
[-511, -304, 309, -854, -522, -679, -851, -27, -545, 526, 636, 712, 138, 275, 498, 304, 335, -731, -746, -688, -27, 855, -504,
89, -370, 424, -329, -578, 565, -676, 358, -305, -752, -733, -948, 545, 397, -772, -552, -985, 502, 859, -781, 217, -139, -665472],
[390, 295, 479, -890, -961, -351, -994, 256, -82, 577, 41, 202, -568, 476, -489, 785, -802, -870, 193, -694, 440, -511, -639, -
441, 901, 950, 954, -637, 247, -864, 219, 595, -25, 184, 877, -283, -181, -481, 775, 814, 654, -861, 44, -882, -97, -51995],
[-604, -247, -954, -553, -724, -931, 726, 28, -817, 910, -972, 152, 215, 100, -899, -497, -49, 29, 401, 843, 729, -190, -784,
419, 427, -70, -290, 874, -253, 411, -555, 648, -5, -539, -587, -115, -641, 639, 571, 843, -304, 501, 868, 795, -193, -224011],
[766, 781, -561, -776, 962, -659, 804, 490, -408, 671, -348, -65, -214, -993, 392, 964, -547, 242, 479, -165, -54, -55, 323, -
60, -789, -99, -303, 590, -552, -861, 641, 288, -737, -538, 868, 521, 328, -519, -329, 31, 535, -856, 331, -395, -347, -16181],
[769, -981, -650, -516, 573, 208, 478, 522, 707, 574, -418, -899, -218, -597, -573, -936, -95, -497, 221, -94, 208, 602, -599, -
559, 881, -743, -85, 951, -303, -733, -1000, 846, -945, 570, -530, 818, -500, 650, -514, 500, -240, 450, 849, 622, -726, -91699],
[775, -229, 661, -772, -806, 168, -993, 82, -547, -572, -387, -398, -624, 703, -848, -606, -725, -316, 675, -69, 855, -115, -236,
86, 615, 423, -806, -834, -236, 300, 83, -560, 623, -816, -449, -830, -474, 692, 878, 146, 235, 165, 157, -290, -161, -572802],
[959, -549, -704, -833, -783, 454, -544, -314, -843, 637, -607, 916, 851, -84, 991, 329, 500, -202, -656, -240, -772, -953, -204,
312, 354, -169, -539, -241, -827, 385, -735, 459, -756, 162, 467, -246, -837, -505, -304, 879, -149, -251, 484, 367, 331, -440533],
[-22, -708, -43, 11, 81, 47, 1000, -534, 462, -835, -637, -282, 179, -908, 839, 17, -391, 331, -952, 122, -405, -33, -151, -
916, -889, 712, 243, 527, -588, 421, -222, 427, 693, 137, 460, -604, -757, 611, -846, -539, -893, -659, 494, -653, 235, -442324],
[101, 286, 257, -858, 969, -581, 154, 64, 861, 266, 543, 615, 565, -408, -252, -61, 267, -36, 702, -628, -416, -349, -784, -403,
100, -965, 775, 296, 388, -485, -198, 311, -451, 914, -544, 297, -758, -616, -96, -119, 211, -185, -899, -683, -681, -29239],
[739, 78, -359, -917, -264, 717, -670, -301, -657, 36, -545, -425, -544, 969, -659, 367, 240, -354, 720, 501, -466, -822, 386, -
787, 756, -66, -641, -923, -690, 323, 533, -963, -505, 78, 834, -66, -93, 36, -121, 543, -653, 417, -869, 100, -771, -585661],
[-393, -446, -661, 482, -558, -228, 16, 960, 985, 722, 945, -654, 806, 810, 526, -436, -231, -428, -219, -326, 311, -174, -
120, -710, 220, 330, 178, -522, 921, 936, 738, -834, 252, 249, -631, 51, -247, -217, -841, 2, 438, 617, 499, 970, -918, 106807],
[547, -383, -612, -998, -251, -387, -912, -661, 934, -14, 697, 833, -4, 667, -454, 110, -818, 549, 81, 466, 737, 520, 762, -861, -
936, 993, -525, -900, -618, -62, -564, -674, 882, -587, -404, -413, 376, 596, -451, -275, 466, -688, 940, -565, 191, -412046],
[72, -635, 549, 183, 596, 785, -189, 331, 852, 427, 166, -72, 579, 191, 535, 333, -675, 560, 100, 127, 979, 1000, -917,
765, 793, 871, 32, 738, 923, 832, -408, 225, 457, 747, 799, 251, -57, 91, -150, 343, 428, 858, -607, 686, 979, 1312536],
[963, 304, 780, 723, 152, -34, 595, -627, 411, -945, 229, 265, 864, 821, 61, -121, -816, 865, -588, -118, -497, -579, -302, -
348, 812, 145, 86, -689, -134, -615, -348, -744, 601, -31, 36, 193, 27, -514, 600, -338, 644, -936, 80, -925, -658, 44628],
[656, 748, -756, 812, 815, -935, 413, -551, 981, 838, 786, -241, 259, 873, -436, -734, 704, -862, 475, -80, -906, -587, -
202, -4, -776, 452, 906, 510, 674, -370, -714, 118, 99, -889, 81, 526, -995, 496, 109, 395, 38, -19, 406, -254, -245, 232490],
[16, -750, 871, -89, -544, -305, -269, -758, 226, -399, -129, -258, 465, 168, 822, -554, 193, 962, -998, -288, -537, -550, -862, -
1000, -984, -966, 153, -844, -559, -425, -415, 194, 827, 430, 491, -430, 920, -20, 848, -26, -216, -335, -534, -398, 951, -383077],
[511, 391, 944, -920, 163, -189, 58, 116, 417, -538, 360, -60, -749, 537, 899, -469, -644, 89, -861, 619, -833, -61, 244, -
159, 393, 82, 853, -599, 51, 593, -633, 222, 997, 32, 728, -395, 952, 354, -301, -617, 42, 310, 649, 580, 823, 436266],
[-641, -173, 563, 813, 70, 154, 704, -476, -971, 494, 532, -4, 247, -559, 390, 823, -937, -401, 592, 688, 556, 363, -921, -609,
444, -802, -424, -612, 495, -573, 247, -190, 432, 504, 849, -996, 341, 800, 396, -437, -428, 884, -695, -149, 154, 107084],
[-699, 63, 42, 691, 862, 373, 647, 776, -590, 817, -455, -107, -882, -992, -483, 828, 260, 254, 277, -433, -508, 702, 997, -287,
640, -995, -654, -618, -26, 474, -979, 617, -4, -267, -229, -713, -285, -124, -64, -496, -567, 128, -526, 516, 21, -117467],
[-8, -507, 122, 708, -86, 285, 579, -647, 435, -150, -1000, -765, -154, 938, 270, 330, 350, 569, 447, -912, 712, 74, 667,
725, -585, -381, -447, -7, 326, -758, 123, 470, 839, 379, -809, 334, 539, -103, -723, 651, 359, 628, -986, 150, 231, 309109],
[398, 50, 511, -754, -444, 457, 139, 312, -989, 639, 451, -697, 758, -265, 653, 725, 911, 528, -975, -138, -766, 846, 701, -
558, -825, -523, -54, 788, 393, 568, 947, -529, -210, 533, -918, -525, -955, -540, 713, -154, 647, -982, -543, -149, 415, 71961],
[864, 976, 635, 543, -459, 252, -626, -877, -100, -630, -64, 183, 990, -197, 33, 207, 474, -814, 880, -824, -469, 605, -652, 101,
268, 370, 627, -959, -383, 306, -628, -349, -250, 524, -630, 200, 979, 712, -313, -891, -835, -94, -668, 982, -373, 21720],
[784, 408, -868, -457, 433, -231, 621, 859, -359, -821, -217, -306, 675, -33, 260, 248, -442, 179, -469, -794, 860, 242, -53,
650, 966, -886, 254, -546, -130, 945, -365, -797, -550, 225, 233, 591, 248, -548, 185, 328, 755, -719, -845, 550, -811, 49050],
[-822, 364, 723, -221, 585, -883, 47, -455, 565, -156, 369, -422, -32, -381, -420, 826, 84, 204, -470, 366, -204, 570, 428,
195, -759, -69, -250, 508, -35, -720, -352, -525, -426, -586, 854, -471, 900, -529, -917, 143, -352, -46, -52, -889, 560, -84381],
[269, 355, 333, 64, 753, 420, 91, -566, -795, -134, -165, 449, -79, 939, -539, -457, -781, -198, -905, 467, -524, 455, -628, -
562, -345, -872, 217, 808, 341, -801, 128, -797, -736, 592, -43, 197, -657, -316, -809, -548, -797, -280, 733, 388, 219, -302598],
[-295, 180, 330, 37, -176, -387, -833, 611, -663, -131, 513, 733, 994, -673, -647, -935, -65, -811, 211, -331, -899, -741, -206,
37, -863, 227, 162, -374, 801, 448, 370, 887, -136, -775, 636, 794, 526, 590, 991, 880, -687, -416, 436, -234, -508, -52964],
[-962, 600, 191, -32, 859, -106, 544, 698, -198, 170, 898, 591, -239, -125, -465, -80, 545, -292, -14, -775, -841, 775, 553,
720, -411, -753, 347, 197, -922, -481, -183, -564, 913, -142, -220, -889, -302, 567, 954, 193, -853, 637, -13, -143, 356, 209341],
[907, -6, -108, 586, -286, -420, -397, 545, -942, 378, -781, 173, -749, -926, -201, 915, 75, -51, -361, 511, 441, -106, -823,
271, 540, -42, 400, 860, 506, -632, 750, 575, -434, 64, -471, 133, -299, -269, 810, -55, -200, -671, 837, -97, 314, 102350]]

x = IntVector('x', 45)

s = Solver()

for i in range(45):
s.add(x[0] * number[i][0] +
x[1] * number[i][1] +
x[2] * number[i][2] +
x[3] * number[i][3] +
x[4] * number[i][4] +
x[5] * number[i][5] +
x[6] * number[i][6] +
x[7] * number[i][7] +
x[8] * number[i][8] +
x[9] * number[i][9] +
x[10] * number[i][10] +
x[11] * number[i][11] +
x[12] * number[i][12] +
x[13] * number[i][13] +
x[14] * number[i][14] +
x[15] * number[i][15] +
x[16] * number[i][16] +
x[17] * number[i][17] +
x[18] * number[i][18] +
x[19] * number[i][19] +
x[20] * number[i][20] +
x[21] * number[i][21] +
x[22] * number[i][22] +
x[23] * number[i][23] +
x[24] * number[i][24] +
x[25] * number[i][25] +
x[26] * number[i][26] +
x[27] * number[i][27] +
x[28] * number[i][28] +
x[29] * number[i][29] +
x[30] * number[i][30] +
x[31] * number[i][31] +
x[32] * number[i][32] +
x[33] * number[i][33] +
x[34] * number[i][34] +
x[35] * number[i][35] +
x[36] * number[i][36] +
x[37] * number[i][37] +
x[38] * number[i][38] +
x[39] * number[i][39] +
x[40] * number[i][40] +
x[41] * number[i][41] +
x[42] * number[i][42] +
x[43] * number[i][43] +
x[44] * number[i][44]
== number[i][45])

if s.check():
m = s.model()
print(m)

整理结果得flag:

x = [0 for i in range(45)]
x[0] = 86
x[26] = 99
x[33] = 117
x[39] = 95
x[3] = 103
x[29] = 51
x[21] = 104
x[2] = 108
x[1] = 111
x[36] = 86
x[44] = 125
x[5] = 67
x[4] = 97
x[20] = 55
x[23] = 99
x[32] = 48
x[8] = 123
x[7] = 70
x[16] = 55
x[18] = 77
x[11] = 51
x[22] = 95
x[27] = 107
x[28] = 77
x[10] = 104
x[37] = 51
x[35] = 51
x[12] = 95
x[14] = 48
x[42] = 51
x[24] = 114
x[25] = 52
x[40] = 53
x[17] = 95
x[30] = 95
x[13] = 77
x[43] = 78
x[9] = 55
x[34] = 95
x[6] = 84
x[15] = 53
x[19] = 52
x[31] = 121
x[41] = 51
x[38] = 82

print("".join(map(chr,x)))

flag:VolgaCTF{7h3_M057_M47h_cr4ckM3_y0u_3V3R_533N}

f-hash

参考wp

初始分析

先运行一下,发现死循环,且也没有任何回显

IDA打开,动态调试,跟踪到对函数第一次调用

UTOOLS1585581679190.png

进入函数,函数对自身进行了递归调用,

UTOOLS1585581733264.png

查看传入参数

Guessed arguments:
arg[0]: 0x7fffffffddc0 --> 0x0
arg[1]: 0x100
arg[2]: 0x6369757120656854 ('The quic')
arg[3]: 0x206e776f7262206b ('k brown ')

发现递归调用0x100次,递归实现浪费了反复重新计算它们的时间, 因此卡住了~

比如调用fun(6):

UTOOLS1585556049511.png

首先先简化代码流程,用python伪代码表示:

def f(char buf[] ,int i , int x , int  y):
if i == 1:
rdx:rax = other_fun(x, y)
buf[0] = rax
buf[1] = rdx
buf[2] = 0
else if i == 2:
rdx:rax = other_fun(x, y)
buf[0] = rax
buf[1] = rdx
buf[2] = 1
else
int a[3]
int b[3]
f(a , i - 1, x , y)
f(b , i - 2, x , y)
rdx:rax = other_fun(x ^ b[3] + a[3] , y )

/* 其他代码 */

buf[0] = rax
buf[1] = rdx
buf[2] = r13

缺少的代码从全局数组读取数据,并根据对other_fun(暂时不知道在干什么,猜测在计算字符串中每一字符二进制中1的数目)的调用、全局数组数据以及递归调用返回的内容执行一些计算

因此考虑如何优化算法代码

算法优化

由于多次调用里面有大量重复的计算,由此可以考虑用一个数组进行记录,如果已经计算过了的可以直接从数组中取值,这个方法的好处在于:

不需要知道函数具体是怎么执行的就可以知道结果

伪代码如下:

if results[i] is exited:
copy results[i] to buffer
else
/ * 计算代码 */
copy buff to results[i]

因此我们需要至少三块空间来分别存放:results[],copy results[i] to buffer, copy buff to results[i]

1. Code 1

首先我们开辟一个空间用于存放修改代码:

set $cave1 = mmap(0x10000, 0x400, 7, 0x32, -1, 0)

$cave1处代码如下:

mov rax,0x20000 ; address of results
push rsi
shl rsi, 5
add rax,rsi ; rax = &results[i]
cmp byte ptr [rax+24],1 ; 确认第四位是不是1
je cached
pop rsi ; 如果不在数组内,即第四位不为1,就执行原来的操作
push r14
push r13
mov r14, rcx
mov rax, 0x5555555553b7
jmp rax
cached:
mov rsi, [rax] ; 如果在数组内,直接赋值后返回,不需递归计算
mov [rdi], rsi
mov rsi, [rax+8]
mov [rdi+8], rsi
mov rsi, [rax+16]
mov [rdi+16], rsi
pop rsi
ret

2. Results

开辟一个空间来记录结果, results是一个二维数组 ,大小为0x101 * 4, 前三位存放值,最后一位存放标识

set $results = mmap(0x20000, 0x101*32, 3, 0x32, -1, 0)

由于有多次调用sub_565447C9B3B0(首次调用),参数除0x100外其他是不一样的,所以需要清空results数组,清空指令如下:

p (void*)memset($results, 0, 0x101*32)

根据v23 += 2可知while循环大概执行5次,也修改sub_565447C9B3B0参数0x100为0x1,直接测试循环几次.

代码如下:

b *0x000055555555577c ; 断在while循环中调用递归函数处,以便执行清零操作

set $i = 0
while $i < 4
set $results = mmap(0x20000, 0x101*32, 3, 0x32, -1, 0)
c
set $i=$i+1
end

3. Code 2

接着开辟第三个空间

set $cave2 = $cave1+0x200

代码如下:

mov rax, 0x20000
shl rdx, 5
add rax, rdx
mov rdx, [rbp]
mov [rax], rdx
mov rdx, [rbp+8]
mov [rax+8], rdx
mov rdx, [rbp+16]
mov [rax+16], rdx
mov byte ptr [rax+24], 1
mov rax, rbp
add rsp, 0x50
pop rbx
pop rbp
pop r12
pop r13
pop r14
ret

最后可以用pwntools的asm对上述汇编代码进行code:

from pwn import *

context.arch = 'amd64'
context.os = 'linux'
context.endian = 'little'
context.word_size = 64

code = """mov rax,0x20000 ;
push rsi;
shl rsi, 5;
add rax,rsi ;
cmp byte ptr [rax+24],1 ;
je cached;
pop rsi ;
push r14;
push r13;
mov r14, rcx;
mov rax, 0x5555555553b7;
jmp rax;
cached:;
mov rsi, [rax] ;
mov [rdi], rsi;
mov rsi, [rax+8];
mov [rdi+8], rsi;
mov rsi, [rax+16];
mov [rdi+16], rsi;
pop rsi;
ret;"""

code = asm(code)
for i in code:
s = "\\x"
if i in range(0xA):
s += '0'
s += hex(i)[2:]
print(s, end='')

得到Code1:

\x48\xc7\xc0\x00\x00\x02\x00\x56\x48\xc1\xe6\x05\x48\x01\xf0\x80\x78\x18\x01\x74\x14\x5e\x41\x56\x41\x55\x49\x89\xce\x48\xb8\xb7\x53\x55\x55\x55\x55\x00\x00\xff\xe0\x48\x8b\x30\x48\x89\x37\x48\x8b\x70\x08\x48\x89\x77\x08\x48\x8b\x70\x10\x48\x89\x77\x10\x5e\xc3

同理Code2:

\x48\xc7\xc0\x00\x00\x02\x00\x48\xc1\xe2\x05\x48\x01\xd0\x48\x8b\x55\x00\x48\x89\x10\x48\x8b\x55\x08\x48\x89\x50\x08\x48\x8b\x55\x10\x48\x89\x50\x10\xc6\x40\x18\x01\x48\x89\xe8\x48\x83\xc4\x50\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\xc3

接着确定patch位置:

code1可以patch在函数开头,而code2需要patch在下述代码之后UTOOLS1585630028654.png

由于程序开启了canary保护,因此可以利用:

mov     rdx, [rsp+78h+var_30]
xor rdx, fs:28h

处作为patch地址,则用Peda的Patch功能,可以得:

Total

b *0x000055555555577c
r
set $cave1 = mmap(0x10000, 0x400, 7, 0x32, -1, 0)
set $cave2 = $cave1 + 0x200

printf "cave1 at %p\ncave2 at %p\nresults at %p\n", $cave1, $cave2, $results
patch 0x5555555553b0 "\xb8\x00\x00\x01\x00\xff\xe0"
patch 0x0000555555555406 "\xb8\x00\x02\x01\x00\xff\xe0\x90\x90"
patch 0x5555555553d1 "\x48\x89\x74\x24\x48"
patch $cave1 "\x48\xc7\xc0\x00\x00\x02\x00\x56\x48\xc1\xe6\x05\x48\x01\xf0\x80\x78\x18\x01\x74\x14\x5e\x41\x56\x41\x55\x49\x89\xce\x48\xb8\xb7\x53\x55\x55\x55\x55\x00\x00\xff\xe0\x48\x8b\x30\x48\x89\x37\x48\x8b\x70\x08\x48\x89\x77\x08\x48\x8b\x70\x10\x48\x89\x77\x10\x5e\xc3"
patch $cave2 "\x48\xc7\xc0\x00\x00\x02\x00\x48\xc1\xe2\x05\x48\x01\xd0\x48\x8b\x55\x00\x48\x89\x10\x48\x8b\x55\x08\x48\x89\x50\x08\x48\x8b\x55\x10\x48\x89\x50\x10\xc6\x40\x18\x01\x48\x89\xe8\x48\x83\xc4\x50\x5b\x5d\x41\x5c\x41\x5d\x41\x5e\xc3"

set $i = 0
while $i < 4
set $results = mmap(0x20000, 0x101*32, 3, 0x32, -1, 0)
c
set $i=$i+1
end

由于gdb默认关闭ASLR(地址随机化),因此每次调试时基址时不变的

运行结果

UTOOLS1585632244789.png

得flag:VolgaCTF{16011432ba16efc8dcf779477985b3b9}

DontNetMe

参考wp

分析

用dnSpy进行动态调试,可知主要有三个函数进行校验

第1个check

首先获得一个输入text

然后检查 len(text) == 29

然后检查 len(text.split('-')[i]) == 4

且判断每一位c > ' '

因此可以知道key的格式为:YYYY-YYYY-YYYY-YYYY-YYYY-YYYY

第2个check

接着进入另一个函数,对每一个字符进行取整数,逐位异或操作,最后num 要等于41,

num = 0;
for i in range(29):
c = flag[i]
num ^= c;
num == 41

第3个check

接着把原字符串的每一位都进行如下操作, 然后仍是逐位异或,最后等于74

k = 0
for i in range(flag_len):
c = globals()['b%d' % i]
n = c * ord('*')
v = ((n >> 6) + (n >> 5) & 127) ^ (n + ord(key[i]) & 127) ^ ord(key[flag_len - i - 1])
k ^= v

k == 74

如何获得常数

因为二进制文件是打包的,dnspy 不能显示局部变量,所以const没有那么容易获取

我们可以在程序运行过程中把程序内存Dump出来

UTOOLS1585843049425.png

输出命令strings -n29 DotnetmeCLI.DMP > 1.txt ,用python脚本再次过滤

with open("1.txt", "r") as file:
f = file.readline()
while f:
f = file.readline()
if (len(f) == 29 + 1):
print(f)
python3 s2.py > 2.txt

接着搜索我们输入的字符,比如这里我输入的AYBO-9odp-Lp8n-mman-XnXn-mmXn(用z3过1,2个check)

UTOOLS1585844565436.png

3cD1Z84acsdf1caEBbfgMeAF0bObA正是我们需要的常数,接着z3求解即可,find_all_posible_solutions求解所有符合要求的解

求解脚本

from z3 import *
import string
key = '3cD1Z84acsdf1caEBbfgMeAF0bObA'
alp = string.ascii_lowercase + string.ascii_uppercase + string.digits
flag_len = 29
def find_all_posible_solutions(s):
if s.check() == sat:
model = s.model()
block = []
out = ''
for i in range(flag_len):
c = globals()['b%i' % i]
out += chr(model[c].as_long())
block.append(c != model[c])
s.add(Or(block))
print(out)

def main():
s = Solver()
k = 0
for i in range(flag_len):
globals()['b%d' % i] = BitVec('b%d' % i, 32)
c = globals()['b%d' % i]

if (i + 1) % 5 == 0:
s.add(c == ord('-'))
else:
s.add(Or([c == ord(i) for i in alp]))
k ^= c

s.add(k == 41)
k = 0
for i in range(flag_len):
c = globals()['b%d' % i]
n = c * ord('*')
v = ((n >> 6) + (n >> 5) & 127) ^ (n + ord(key[i]) & 127) ^ ord(key[flag_len - i - 1])
k ^= v

s.add(k == 74)
find_all_posible_solutions(s)

if __name__ == "__main__":
sys.exit(main())

解得flag:

$ python3 s.py
vsxs-wvmX-7qD3-66qn-UNro-IXur

根据原wp,该程序存在多解,将find_all_posible_solutions()中if为while即可