RE (RE)2025 SWPU-NSSCTF 秋季招新入门训练赛 GHSC 2025-09-21 2026-04-13 1.Xor Xor是一種可反編的加密方式
打開ida
可以看見flag在c語言下做了Xor
說明要==enc_0[i]
導出enc_0[i] 的值
**要先從HEX轉回string 再做Xor , key為0x7A
2.Base64
一眼就看見了base64 的表和文了
3.ida使用
string1: NSSCTF{
在shift+f12就可以在第一行找到string2了
string2:IDA_1s_4_VeRy_Impo
需要debug 查看flag3的值(因為在有一部分在擬偽代碼沒有寫出來的,要轉匯編才能看出來)
在flag() tab 一下在nap 下一個斷點(F2)
可以用R來看data
R之前:
R之後:
運行程式到斷點位
string3: rTant_t0
string4: rever5e_en8ine3ring} (直接把代碼抄去運行都可以(
看看string4的是要用上patch的功能,
看看左邊有一個print_flag4()函數 , 利用patch method 調用 , 按下print_nothing() + tab 找出flag4 call 的地址
在x86-64架構, call 指令通常使用相對地址, 在ida 中你可以打開opcode查看該部分
看看兩函數的地址的 偏移量 = 目標地址 - (下一條指令的地址)
目標地址: 0x7FF733631473** ( print_flag4(void) )**
當前指令地址: 0x7FF73363160D** (print_nothing(void))**
下一條命令的地址: 0x7FF733631612
偏移量 = hex(0x07FF733631473 - 0x7FF733631612 ) = -0x19f
1 2 >>> hex (0x7FF733631473 - 0x7FF733631612 )'-0x19f'
下一條指令的地址: 0x7FF73363160D+ 5 (當前指令地址+匯編字節[E8占1字節 ,** rel32占4字節**])
偏移量 = hex(0x07FF733631473 - (0x7FF73363160D+ 5)) = -0x19f
1 2 >>> hex (0x07FF733631473 - (0x7FF73363160D + 5 ))'-0x19f'
把-0x19f 補碼 :
1 2 >>> print (hex (-0x19f & 0xffffffff ))0xfffffe61
機械碼: 61feffff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def hex_to_machine_code (hex_value ): """ 將十六進位值轉換為機械碼 (little-endian 格式) Args: hex_value (int): 十六進位值,例如 0xfffffe61 Returns: str: 機械碼的十六進位字符串 """ result_bytes = hex_value.to_bytes(4 , byteorder='little' ) return result_bytes.hex () if __name__ == "__main__" : test_value = 0xfffffe61 machine_code = hex_to_machine_code(test_value) print (f"0x{test_value:08x} 的機械碼: {machine_code} " )
*我們可以驗算一下本來的地址是否為3E FE FF FF
目標地址:** 0x7FF733631450** ( print_nothing(void) )
下一條命令的地址: 0x7FF733631612
1 2 3 4 >>> print (hex ((0x7FF733631450 - 0x7FF733631612 )& 0xFFFFFFFF ))0xfffffe3e 3E FE FF FF
所以是對的 , 這裹是在要下 E8 3E FE FF FF 下斷點 , debug一下
右鍵patch 把3E 改成 61 , F8一下就出現了
steing4 : rever5e_en8ine3ring
flag : NSSCTF{rever5e_en8ine3ring}
4.debug
下一個斷點 debugger , 找到v4的棧 , 按一下A鍵可在匯編中查看。
NSSCTF{you_know_debug!!}
5.RC4 用cyber
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 flag[i] != enc_0[i] int __fastcall main(int argc, const char **argv, const char **envp) { unsigned int v3; // eax unsigned int v4; // eax char flag[112]; // [rsp+20h] [rbp-60h] BYREF _BYTE v7[264]; // [rsp+90h] [rbp+10h] BYREF int i; // [rsp+198h] [rbp+118h] int v9; // [rsp+19Ch] [rbp+11Ch] _main(argc, argv, envp); printf("please input flag:"); scanf("%s", flag); v3 = strlen("SakuraiCora"); rc4_init(v7, "SakuraiCora", v3); v4 = strlen(flag); rc4_crypt(v7, flag, v4); v9 = 1; for ( i = 0; i <= 23; ++i ) { if ( flag[i] != enc_0[i] ) { v9 = 0; break; } } if ( v9 ) printf("You get flag!\n"); else printf("Wrong flag!\n"); return 0; }
Rc4 key 是 : "SakuraiCora"
看看flag的數據 flag[i] != enc_0[i] 看看enc_0
0xe8, 0x2b, 0x33, 0x25, 0xb2, 0x55, 0xe9, 0xd, 0x5d, 0xaa, 0x69, 0xfd, 0x1b, 0x47, 0xd1, 0x7c, 0xa6, 0xff, 0x52, 0xe1, 0x6c, 0xe8, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
在cyber 先 HEX 一下再 RC4
flag : NSSCTF{y0u_solved_Rc4!}
6.认识asm 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 text:00000001400014A1 public enc .text:00000001400014A1 enc proc near .text:00000001400014A1 .text:00000001400014A1 .text:00000001400014A1 i = dword ptr -14h .text:00000001400014A1 flag = qword ptr 10h .text:00000001400014A1 .text:00000001400014A1 push rbp .text:00000001400014A2 push rbx .text:00000001400014A3 sub rsp, 38h .text:00000001400014A7 lea rbp, [rsp+30h] .text:00000001400014AC mov [rbp+10h+flag], rcx .text:00000001400014B0 mov [rbp+10h+i], 0 .text:00000001400014B7 jmp short loc_1400014F6 .text:00000001400014B9 ; --------------------------------------------------------------------------- .text:00000001400014B9 .text:00000001400014B9 loc_1400014B9: .text:00000001400014B9 mov eax, [rbp+10h+i] .text:00000001400014BC cdqe .text:00000001400014BE mov rdx, [rbp+10h+flag] .text:00000001400014C2 add rax, rdx .text:00000001400014C5 movzx eax, byte ptr [rax] .text:00000001400014C8 mov ecx, eax .text:00000001400014CA mov eax, [rbp+10h+i] .text:00000001400014CD cdqe .text:00000001400014CF lea rdx, [rax+1] .text:00000001400014D3 mov rax, [rbp+10h+flag] .text:00000001400014D7 add rax, rdx .text:00000001400014DA movzx eax, byte ptr [rax] .text:00000001400014DD add eax, 1 .text:00000001400014E0 xor ecx, eax .text:00000001400014E2 mov edx, ecx .text:00000001400014E4 mov eax, [rbp+10h+i] .text:00000001400014E7 cdqe .text:00000001400014E9 mov rcx, [rbp+10h+flag] .text:00000001400014ED add rax, rcx .text:00000001400014F0 mov [rax], dl .text:00000001400014F2 add [rbp+10h+i], 1 .text:00000001400014F6 .text:00000001400014F6 loc_1400014F6: .text:00000001400014F6 mov eax, [rbp+10h+i] .text:00000001400014F9 movsxd rbx, eax .text:00000001400014FC mov rcx, [rbp+10h+flag] ; Str .text:0000000140001500 call strlen .text:0000000140001505 sub rax, 2 .text:0000000140001509 cmp rbx, rax .text:000000014000150C jb short loc_1400014B9 .text:000000014000150E nop .text:000000014000150F nop .text:0000000140001510 add rsp, 38h .text:0000000140001514 pop rbx .text:0000000140001515 pop rbp .text:0000000140001516 retn .text:0000000140001516 enc endp enc_flag db 0x1a,0x7,0x17,0x16,0x13,0x3a,0x39,0x15,0x1d,0x2d,0x35,0x1d,0x13,0x3b,0x10,0x4 db 0x11,0x9,0xb,0xc,0xc,0x2a,0x4,0xf,0x1c,0x28,0x6,0xc,0x12,0x8,0x6,0x7e db 0x7d
補充:
在匯編中,變量名通常為:
1 2 3 [基址+偏移量+變量名] [rbq+10h+flag] #flag字符串的地址 [rbq+10h+i] #i的值
Windows x64 調用約定(_fastcall):
1 2 3 4 5 6 7 四個整數或指針參數(從左到右)通過 rcx , rdx , r8 , r9 寄存器 例如 func(arg1, arg2 , arg3 , arg4)會將arg1 放入 rcx , arg2 放入 rdx... 多於四個會則其余用棧傳遞。 浮點數參數用 xmm0 , xmm1 , xmm2 , xmm3 寄存器傳遞。 .text:00000001400014FC mov rcx, [rbp+10h+flag] ; Str .text:0000000140001500 call strlen .text:0000000140001505 sub rax, 2
可參考:https://www.bilibili.com/video/BV17TaCzJEqp/?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=b128d59725d91ecef706ce0b01795a8f
跳轉邏輯:
1 2 3 4 5 6 7 8 9 10 11 .text:0000000140001509 cmp rbx, rax .text:000000014000150C jb short loc_1400014B9 #j = jump #e = equal #z = zero #a = above (>) #g = greater (>) #b = below (<) #l = less (<) #n = not
問一問 ai 寫出了python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 enc_flag = [ 0x1a , 0x7 , 0x17 , 0x16 , 0x13 , 0x3a , 0x39 , 0x15 , 0x1d , 0x2d , 0x35 , 0x1d , 0x13 , 0x3b , 0x10 , 0x4 , 0x11 , 0x9 , 0xb , 0xc , 0xc , 0x2a , 0x4 , 0xf , 0x1c , 0x28 , 0x6 , 0xc , 0x12 , 0x8 , 0x6 , 0x7e , 0x7d ] flag = list (enc_flag) for i in range (len (flag) - 3 , -1 , -1 ): flag[i] = flag[i] ^ (flag[i+1 ] + 1 ) flag_str = '' .join(chr (c) for c in flag) print (flag_str)
flag : NSSCTF{ASM_is_crucial_to_Binary~}