NSSCTF Round17 Reverse & Crypto WriteUp(全)

Reverse

一. snake

  • go1.19写的,直接找到main函数,下断点动调

  • 以下为输入函数(输入wasd):

  • for ( i = 0LL; i < 1; i = v11 + 1 )
    {
      v11 = i;
      snake_pkg_app_Run();
      v22 = v1;
      v3 = runtime_convT64();
      *(_QWORD *)&v22 = &unk_50C3C0;
      *((_QWORD *)&v22 + 1) = v3;
      fmt_Fprintf();
    }
    
  • 这里找到汇编代码,直接patch

  • .text:0000000000503301
    .text:0000000000503301 loc_503301:
    .text:0000000000503301 cmp     rax, 1
    .text:0000000000503305 jl      short loc_50328D
    
    
    
  • 以下为输出及check函数

  • if ( i == 1 && !qword_5C9E78 )
    {
      v20 = &unk_50CB00;
      v21 = &off_545D98;
      fmt_Fprintln();
      v18 = snake_pkg_game_All_rand;
      v4 = qword_5C9E78;
      v13 = qword_5C9E78;
      v5 = 0LL;
      v6 = 0LL;
      while ( v5 < v4 )
      {
        v12 = v5;
        v17 = v6;
        v23 = v1;
        v7 = runtime_convT64();
        *(_QWORD *)&v23 = &unk_50C3C0;
        *((_QWORD *)&v23 + 1) = v7;
        fmt_Sprintf();
        v8 = runtime_concatstring2();
        v4 = v13;
        v9 = v8;
        v5 = v12 + 1;
        v6 = v9;
      }
      *((_QWORD *)&v14 + 1) = *((_QWORD *)&v1 + 1);
      sub_4BF36B();
      *((_QWORD *)&v14 + 1) = 0x1032547698BADCFELL;
      v15 = -1009589776;
      v16 = v1;
      runtime_stringtoslicebyte();
      crypto_sha1___digest__Write();
      crypto_sha1___digest__Sum();
      v19 = v1;
      v10 = runtime_convTslice();
      *(_QWORD *)&v19 = &unk_50BAC0;
      *((_QWORD *)&v19 + 1) = v10;
      fmt_Fprintf();
    }
    
  • 把score为400改成0:

  • .text:000000000050330D cmp     cs:qword_5C9E78, 0
    .text:0000000000503318 jnz     short loc_50338B
    
  • 然后一直动调到最后就行

  • flag{da39a3ee5e6b4b0d3255bfef95601890afd80709}

二. can_can_need_pxory

  • 解包后反编译

  • # uncompyle6 version 3.9.0
    # Python bytecode version base 3.6 (3379)
    # Decompiled from: Python 3.6.12 (default, Feb  9 2021, 09:19:15) 
    # [GCC 8.3.0]
    # Embedded file name: can_can_need_pxory.py
    print('ccccccccccccccccccccccccccccccccccc!')
    print('D0 U know C?')
    print('\n#include <NSSCTF.h>\nv01d bnssst(int FTC[], int lenggggggg) {\n    int i, j, SSN;\n')
    print('This is CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC')
    print('6L+Z5piv5L2g6KaB55qEZmxhZ+WQl++8nwpOU1NDVEZ7YjVlMzlkMDktODg3Yy1hZGI0LTE4OWMtMWI0OGEwNWJmOTY2fQ==')
    A = {'flag': 'NSSCTF{a81c0d5e-ec6d-2b80'}
    print('\n                SSN = FTC[j];\n                printf("flag");\n            }\n}\nint mian() {\n    int FTC[] = [ -,\n')
    print('ccccccccccccccccccc')
    print('\nb, 2, 6, 7, -, d, 5, 8, 4, -, 6, 8, 7, 4, -, f, 1, 2, 6, e, 3, a, 5, 1, 0, 6, 1, }];\n    int lenggggggg = (int) sizeof(FTC) / sizeof(*FTC);\n    bnsScrt(FTC, lenggggggg);\n    int i;\n    for (i = 0; i < lenggggggg; i++)\n        printf("%d ", FTC[i]);\n    remake 0;\n}\n')
    print('----------------------------------------------------')
    import base64
    flag = '************************************'
    r = ''
    for x in range(len(flag)):
        if (x + 1) % 4 == 0:
            res = str(ord(chr(ord(flag[x]) ^ 2421)))
        else:
            res = str(ord(chr(ord(flag[x]) << 6 << 7 >> 2 >> 1 ^ 92)))
        r = r + res + ','
    
    print(base64.b64encode(base64.b16encode(base64.b32encode(r.encode('utf-8')))).decode('utf-8'))
    
  • 写脚本

  • r='NDc1NTMyNTQ0NzRGNDI1OTQ2NTEzMjU0NDc0RDVBNTU0NzQxNTc0NDQzNEQ0QTUzNDczNDVBNTQ0NTRDNDI1MzQ3NEQ1OTU0NEQ0QzQyNTI0NzQ1MzM1NDUxNEU0QTUzNDY1MTMyNDQ1MzRENTI1NTQ3NTE1NzQ0NEI0RDRBNTM0ODQ1NUE0MzU5NEQ1MjU0NDczNDM0NDM1OTRFNDI1NzQ3NDUzMzU0NDU0QzQyNTI0NzQxMzM1NDRENEQ0QTUzNDY1MTU5NTQ0MzRGNDI1OTQ3MzQzMzQzNTk0RDUyNTQ0NzQ5MzM0MzU5NEQ0QTUyNDczNDM0NDQ0QjRENTI0RDQ3NTEzMzQ0NDM0RTVBNTM0NjUxNTk1NDQ1NEQ0MjVBNDc0OTMyNDM1OTRENTI1NDQ3NEQ1OTQzNTk0RDRBNTI0NzU5MzQ0NDQ1NEY0MjRENDc0NTVBNDQ0NzRGNEE1QTQ3NTk1NzQ0NDk0RTUyNTI0NzM0NUE0MzU5NEQ1MjU0NDc0OTM0NTM1OTRENEE1MjQ4NDUzNDU0NDE0RDQyNEQ0NzQ1NTk1NDQ1NEU1QTU0NDc0OTU3NDQ0MzRENEE1MzQ3MzQ1QTU0NDU0QzQyNTM0NzREMzQ0NDRENEM0MjUyNDc0OTVBNTQ1MzRGNEE1NzQ2NTEzMjU0NDE0RDUyNTc0ODQxNTc0NDRCNEY0MjU1NDc1OTU5NDM1OTRENTI1NDQ3NDUzNDUzNTk0RDRBNTM0NzREMzQ1NDUzNEU1MjRENDc0NTU5NDQ0MzRFNDI1NzQ4NDE1NzQ0NDM0RDUyNTQ0ODQ1MzQ1NDRENEM0MjUzNDc0RDU5NTQ1MzRDNDI1NTQ4NDU1QTQ0NDk0RTQyNEQ0NzU1MzM1NDQ5NEQ1QTU3NDY1MTMyNTQ0RDRFNDI1MjQ3NDk1NzQ0NDU0RDVBNTQ0NzQ1NTc0MTNEM0QzRDNE'
    rr=base64.b32decode(base64.b16decode(base64.b64decode(r.encode('utf-8')))).decode('utf-8')
    print(rr)
    rr=[55388,53340,112732,2316,117852,49244,51292,2378,46172,107612,118876,2326,117852,46172,120924,2330,116828,123996,46172,2329,119900,112732,112732,2386,123996,50268,58460,2319,123996,101468,123996,2319,49244,57436,56412,2331]
    
    for s in range(36):
        for i in range(32, 128):
            if (s + 1) % 4 == 0:
                res = ord(chr(i ^ 2421))
            else:
                res = ord(chr(i << 6 << 7 >> 2 >> 1 ^ 92))
    
            if res == rr[s]:
                print(chr(i), end='')
    
    
  • 得到64nys02?-itcs-vory-lunn'y19zycyz087n

  • 还是不对的,我看到very和itis这两个词,然后猜了一下,发现是异或10,然后就得到

  • NSSCTF{64nss025-itis-very-funn-y19pycyp087d}

  • 纯纯谜语题,不做评价

Crypto

一. Level1

  • 签到,共模攻击

  • import libnum
    import gmpy2
    
    n = 22517647586235353449147432825948355885962082318127038138351524894369583539246623545565501496312996556897362735789505076324197072008392656511657262430676945685471397862981216472634785622155317188784494912316440866051402627470561626691472280850273482836308002341429493460677206562201947000047718275995355772707947408688836667011206588727438261189233517003341094758634490421007907582147392858070623641389171229435187248184443645883661560636995548332475573072064240073037558031928639832259001407585962782698021735648128101459118863015844905452823095147248865104102562991382119836061161756978764495337874807458182581421229
    c1 = 1432393096266401187029059077791766305797845826173887492889260179348416733820890797101745501984437201566364579129066414005659742104885321270122634155922766503333859812540068278962999824043206496595825886026095484801291802992082454776271149083516187121160475839108002133113254134626407840182541809478892306748590016896975053434021666376203540725254480252049443975835307793528287818262102688334515632062552114342619781840154202525919769192765621085008206581226486157149883898548933475155236509073675387541466324512294079413938239828341890576923100769181401944289365386552139418728492565319685207500539721582552448971814
    c2 = 13299679392897297864252207869444022461237574801991239380909482153705185317634241850084078027230394830079554676426505967970943836811048777462696506309466535820372917756458083553031417406403895116557560548183674144457502601887632495739472178857537011190162283185735114683172731936834993707871636782206418680404006299140864001776588991141011500807549645227520128216130966268810165946959810884593793452437010902774726405217517557763322690215690606067996057037379898630878638483268362526985225092000670251641184960698506349245915816808028210142606700394584541282682338561482561343076218115042099753144875658666459825545602
    e1 = 155861690390761931560700906834977917646203451142415617638229284868013723431003139974975998354830978765979365632120896717380895021936387027045347260400512396388028781862427862974453223157509702913026222541667006325100878113871620322023188372501930117363623076837619478555007555970810681502521309925774889678793
    e2 = 144471983652821947847253052623701746810204736865723159569786739658583884214397562204788127484897909964898113250509653721265240138487697822089282456150238116811225975640330930854549232972314642221382625614304415750165289831040623741828600283778523993251940904896081111235859249916040849697146542311990869696453
    
    def exp_def(e1,e2,c1,c2,n):
        s,s1,s2 = gmpy2.gcdext(e1, e2)
        m = (pow(c1,s1,n) * pow(c2 ,s2 ,n)) % n
        return int(m)
    
    m=exp_def(e1,e2,c1,c2,n)
    print(libnum.n2s(m))
    
  • NSSCTF{Y0u_Hav3_S01v3d_Crypt0_Leve1_i}

二.Level2

  • 读取文件,猜e=65537

  • f=open("C:\\Users\\lenovo\\Desktop\\ps.txt")
    data = f.readlines()
    f.close()
    for i in range(len(data)):
        p=int(data[i],10)
        q=145721736470529261146573065574028992352505611489859183763269215489708531333597694809923949026781460438320576519639268582565188719134157402292313959218961804213310847081787824780075530751842057663327444602428455144829447776271394663729996984613471623158126083062443634493708467568220146024273763894704649472957
        c=17441814714407189483380175736850663249578989775568187792928771544069162420510939242665830363276698262009780462912108642025299275146709817979705069095332726251759039923303627023610865046363171692163473939115438686877494878334016463787558794121885354719336139401336137097548305393030069499625065664884238710759260231321106291200849044147840392021931720902340003746946851806025722944795391356835342258387797980787437188976704677008092850181043891802072500430200735973581081228711070923822341261809453662427341958883142789220800541626034573952425948295446202775198692920613709157662831071515700549093766182579873408465779
        e=65537
        n=p*q
        phi=(p-1)*(q-1)
        d=inverse(e,phi)
        m=long_to_bytes(pow(c,d,n))
        if b'NSSCTF{' in m:
            print(m)
    
  • NSSCTF{Y0u_g0t_1t!!!}

三. Level3

  • 利用pwn库写个交互脚本

  • from pwn import *
    from Crypto.Util.number import *
    def func(a, b):
        if a == 0:
            return b, 0, 1
        else:
            g, x, y = func(b % a, a)
            return g, y - (b // a) * x, x
    
    io = remote("node1.anna.nssctf.cn",28458)
    for i in range(666):
        lines = io.recvuntil("Pl Give Me flaag :").decode().split('\n')
        
        if i < 2:
            n=int(lines[12].split('=')[1])
            e1=int(lines[13].split('=')[1])
            e2=int(lines[14].split('=')[1])
            c1=int(lines[15].split('=')[1])
            c2=int(lines[16].split('=')[1])
        elif i >=2:
            n=int(lines[13].split('=')[1])
            e1=int(lines[14].split('=')[1])
            e2=int(lines[15].split('=')[1])
            c1=int(lines[16].split('=')[1])
            c2=int(lines[17].split('=')[1])
        g, b1, b2 = func(e1, e2)
    
        if g != 1:
            raise ValueError("e1 and e2 are not coprime")
    
        m = pow(c1, b1, n) * pow(c2, b2, n) % n
        flag = long_to_bytes(m)
        io.sendline(flag.decode("utf-8"))
        print(f"count{i}")
    io.recvuntil("You get flag!")
    print(io.recvlines(2))
    #NSSCTF{220b5065-4e42-47b2-ac83-6656d77fa102}
    
    
  • NSSCTF{220b5065-4e42-47b2-ac83-6656d77fa102}