国城杯RE部分题解
类似于一个登录系统,username+password组成了flag,username被base64加密成了"c9m1bRmfY5Wk"不过这个加密做了一些小动作
import string
def find_flag():
sbox = [924, 967, 912, 973, 921, 936, 916, 926, 942, 963, 930, 927, 912, 971, 924, 961, 909, 956, 896, 906, 946,
991, 958, 899, 900, 991, 904, 981, 897, 944, 908, 902, 902, 1003, 906, 951, 952, 995, 948, 1001, 949, 900,
952, 946, 906, 999, 902, 955, 940, 1015, 928, 1021, 937, 920, 932, 942, 926, 1011, 914, 943, 928, 1019, 940,
1009, 989, 1004, 976, 986, 994, 911, 1006, 979, 980, 911, 984, 901, 977, 992, 988, 982, 1014, 923, 1018,
967, 968, 915, 964, 921, 965, 1012, 968, 962, 1018, 919, 1014, 971, 1020, 935, 1008, 941, 1017, 968, 1012,
1022, 974, 931, 962, 1023, 1008, 939, 1020, 929, 1005, 988, 992, 1002, 978, 959, 990, 995, 996, 959, 1000,
949, 993, 976, 1004, 998, 806, 843, 810, 791, 792, 835, 788, 841, 789, 804, 792, 786, 810, 839, 806, 795,
780, 855, 768, 861, 777, 824, 772, 782, 830, 851, 818, 783, 768, 859, 780, 849, 829, 780, 816, 826, 770,
879, 782, 819, 820, 879, 824, 869, 817, 768, 828, 822, 790, 891, 794, 807, 808, 883, 804, 889, 805, 788,
808, 802, 794, 887, 790, 811, 860, 775, 848, 781, 857, 872, 852, 862, 878, 771, 866, 863, 848, 779, 860,
769, 845, 892, 832, 842, 882, 799, 894, 835, 836, 799, 840, 789, 833, 880, 844, 838, 838, 811, 842, 887,
888, 803, 884, 809, 885, 836, 888, 882, 842, 807, 838, 891, 876, 823, 864, 829, 873, 856, 868, 878, 862,
819, 850, 879, 864, 827, 876, 817, 669, 684, 656, 666, 674, 719, 686, 659, 660, 719, 664, 709, 657, 672,
668, 662, 694, 731, 698, 647, 648, 723, 644, 729, 645, 692, 648, 642, 698, 727, 694, 651, 700, 743, 688,
749, 697, 648, 692, 702, 654, 739, 642, 703, 688, 747, 700, 737, 685, 668, 672, 682, 658, 767, 670, 675,
676, 767, 680, 757, 673, 656, 684, 678, 742, 651, 746, 727, 728, 643, 724, 649, 725, 740, 728, 722, 746,
647, 742, 731, 716, 663, 704, 669, 713, 760, 708, 718, 766, 659, 754, 719, 704, 667, 716, 657, 765, 716,
752, 762, 706, 687, 718, 755, 756, 687, 760, 677, 753, 704, 764, 758, 726, 699, 730, 743, 744, 691, 740,
697, 741, 724, 744, 738, 730, 695, 726, 747, 540, 583, 528, 589, 537, 552, 532, 542, 558, 579, 546, 543,
528, 587, 540, 577, 525, 572, 512, 522, 562, 607, 574, 515, 516, 607, 520, 597, 513, 560, 524, 518, 518,
619, 522, 567, 568, 611, 564, 617, 565, 516, 568, 562, 522, 615, 518, 571, 556, 631, 544, 637, 553, 536,
548, 558, 542, 627, 530, 559, 544, 635, 556, 625, 605, 620, 592, 602, 610, 527, 622, 595, 596, 527, 600,
517, 593, 608, 604, 598, 630, 539, 634, 583, 584, 531, 580, 537, 581, 628, 584, 578, 634, 535, 630, 587,
636, 551, 624, 557, 633, 584, 628, 638, 590, 547, 578, 639, 624, 555, 636, 545, 621, 604, 608, 618, 594,
575, 606, 611, 612, 575, 616, 565, 609, 592, 620, 614, 422, 459, 426, 407, 408, 451, 404, 457, 405, 420,
408, 402, 426, 455, 422, 411, 396, 471, 384, 477, 393, 440, 388, 398, 446, 467, 434, 399, 384, 475, 396,
465, 445, 396, 432, 442, 386, 495, 398, 435, 436, 495, 440, 485, 433, 384, 444, 438, 406, 507, 410, 423,
424, 499, 420, 505, 421, 404, 424, 418, 410, 503, 406, 427, 476, 391, 464, 397, 473, 488, 468, 478, 494,
387, 482, 479, 464, 395, 476, 385, 461, 508, 448, 458, 498, 415, 510, 451, 452, 415, 456, 405, 449, 496,
460, 454, 454, 427, 458, 503, 504, 419, 500, 425, 501, 452, 504, 498, 458, 423, 454, 507, 492, 439, 480,
445, 489, 472, 484, 494, 478, 435, 466, 495, 480, 443, 492, 433, 285, 300, 272, 282, 290, 335, 302, 275,
276, 335, 280, 325, 273, 288, 284, 278, 310, 347, 314, 263, 264, 339, 260, 345, 261, 308, 264, 258, 314,
343, 310, 267, 316, 359, 304, 365, 313, 264, 308, 318, 270, 355, 258, 319, 304, 363, 316, 353, 301, 284,
288, 298, 274, 383, 286, 291, 292, 383, 296, 373, 289, 272, 300, 294, 358, 267, 362, 343, 344, 259, 340,
265, 341, 356, 344, 338, 362, 263, 358, 347, 332, 279, 320, 285, 329, 376, 324, 334, 382, 275, 370, 335,
320, 283, 332, 273, 381, 332, 368, 378, 322, 303, 334, 371, 372, 303, 376, 293, 369, 320, 380, 374, 342,
315, 346, 359, 360, 307, 356, 313, 357, 340, 360, 354, 346, 311, 342, 363, 156, 199, 144, 205, 153, 168,
148, 158, 174, 195, 162, 159, 144, 203, 156, 193, 141, 188, 128, 138, 178, 223, 190, 131, 132, 223, 136,
213, 129, 176, 140, 134, 134, 235, 138, 183, 184, 227, 180, 233, 181, 132, 184, 178, 138, 231, 134, 187,
172, 247, 160, 253, 169, 152, 164, 174, 158, 243, 146, 175, 160, 251, 172, 241, 221, 236, 208, 218, 226,
143, 238, 211, 212, 143, 216, 133, 209, 224, 220, 214, 246, 155, 250, 199, 200, 147, 196, 153, 197, 244,
200, 194, 250, 151, 246, 203, 252, 167, 240, 173, 249, 200, 244, 254, 206, 163, 194, 255, 240, 171, 252,
161, 237, 220, 224, 234, 210, 191, 222, 227, 228, 191, 232, 181, 225, 208, 236, 230, 38, 75, 42, 23, 24, 67,
20, 73, 21, 36, 24, 18, 42, 71, 38, 27, 12, 87, 0, 93, 9, 56, 4, 14, 62, 83, 50, 15, 0, 91, 12, 81, 61, 12,
48, 58, 2, 111, 14, 51, 52, 111, 56, 101, 49, 0, 60, 54, 22, 123, 26, 39, 40, 115, 36, 121, 37, 20, 40, 34,
26, 119, 22, 43, 92, 7, 80, 13, 89, 104, 84, 94, 110, 3, 98, 95, 80, 11, 92, 1, 77, 124, 64, 74, 114, 31,
126, 67, 68, 31, 72, 21, 65, 112, 76, 70, 70, 43, 74, 119, 120, 35, 116, 41, 117, 68, 120, 114, 74, 39, 70,
123, 108, 55, 96, 61, 105, 88, 100, 110, 94, 51, 82, 111, 96, 59, 108, 49]
checknum = [352, 646, 752, 882, 65, 0, 122, 0, 0, 7, 350, 360]
def round_op(sbox, char, index):
for _ in range(32):
op_type = (((sbox[index] ^ char) % 5) + 5) % 5
if op_type == 0: # add
char = (((char + sbox[index]) % 1024) + 1024) % 1024
elif op_type == 1: # sub
char = (((char - sbox[index]) % 1024) + 1024) % 1024
elif op_type == 2: # xor
char = (sbox[index] ^ char) % 1024
elif op_type == 3: # shl
char = (char >> 3) % 1024
elif op_type == 4: # shr
char = (char << 3) % 1024
index = (index + char) % 1024
return char, index
def try_password(index=33, depth=0, pwd=''):
if depth == len(checknum):
print(pwd)
return
for c in string.ascii_letters + '_':
result, next_index = round_op(sbox, ord(c), index)
if result == checknum[depth]:
try_password(next_index, depth + 1, pwd + c)
try_password()
if __name__ == "__main__":
find_flag()
得到_rounD_we_go,所以flag就是
就是一个键盘keyboard的驱动
替换了就行
keys = [32, 42, 11, 34, 4, 45, 34, 42, 46, 42, 26, 42, 30, 7, 7, 48, 3, 4, 5, 3, 12, 11, 5, 32, 5, 12, 5, 7, 9, 30, 12, 10, 10, 32, 4, 12, 8, 18, 32, 48, 30, 5, 46, 10, 11, 11, 2, 33, 27, 42]
key = {0x1E: "A", 0x30: "B", 0x2E: "C", 0x20: "D", 0x12: "E", 0x21: "F", 0x22: "G", 0x23: "H", 0x17: "I", 0x24: "J", 0x25: "K", 0x26: "L", 0x32: "M", 0x31: "N", 0x18: "O", 0x19: "P", 0x10: "Q", 0x13: "R", 0x1F: "S", 0x14: "T", 0x16: "U", 0x2F: "V", 0x11: "W", 0x2D: "X", 0x15: "Y", 0x2C: "Z", 0x02: "1", 0x03: "2", 0x04: "3", 0x05: "4", 0x06: "5", 0x07: "6", 0x08: "7", 0x09: "8", 0x0A: "9", 0x0B: "0", 0x2a: "[shift]", 0xc: "-"}
mapped_keys = [key.get(i, '') for i in keys]
output_string = ''.join(mapped_keys)
print(output_string)
#得到:D[shift]0G3XG[shift]C[shift][shift]A66B2342-04D4-468A-99D3-7EDBA4C9001F[shift]
把多余的去除里面的换成小写就行,标头根据题目与就行了
找到关键点
交叉引用
大概可以猜出是一个TEA,查看一下sub_41110E函数
这应该是一个SMC加密了,看一下导入表
交叉引用
直接选择动调解密然后dump出解密后的,最后编写解密脚本即可
#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t v, uint32_t k) {
uint32_t sum = 0xC6EF3720;
uint32_t delta = 0x9E3779B9;
for(int i = 0; i < 32; i++) {
uint32_t e = (sum >> 2) & 3;
v[1] -= ((v[0] >> 5 ^ v[0] << 2) + (v[0] >> 3 ^ v[0] << 4)) ^ ((sum ^ v[0]) + (k[(1&3)^e] ^ v[0]));
v[0] -= ((v[1] >> 5 ^ v[1] << 2) + (v[1] >> 3 ^ v[1] << 4)) ^ ((sum ^ v[1]) + (k[(0&3)^e] ^ v[1]));
sum -= delta;
}
}
int main() {
uint32_t data[] = {
0x5a764f8a, 0x05b0df77, 0xf101df69, 0xf9c14ef4,
0x27f03590, 0x7df3324f, 0x2e322d74, 0x8f2a09bc,
0xabe2a0d7, 0x0c2a09fe, 0x35892bb2, 0x53abba12
};
uint32_t key[] = {0x05201314, 0x52013140, 0x05201314, 0x52013140};
for(int i = 0; i < 12; i += 2) {
decrypt(&data[i], key);
}
printf("%sn", (char*)data);
return 0;
}
注:鼎星安全有对此文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。
原文始发于微信公众号(鼎新安全):国城杯RE部分题解
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论