zoukankan      html  css  js  c++  java
  • 2019UNCTF竞技赛部分writeup

    Reverse

    unctf_babyre2

    这题flag分为两部分,第一部分每四个字符一组打包成int后,每次把四个int传入函数,后三个参数异或后先以每位为索引查表,将新数据进行循环移位、异或,将结果与第一个参数异或。此操作进行了26次,通过最后的一组结果可以慢慢倒推回去。第二部分是对字符串进行常规的异或操作与目标串比较。

    脚本:

    #include<stdio.h>
    
    #include<strings.h>
    
    int main(){
    
    int i,j;
    
    unsigned int v40,v41,v42,v43,v44,v39,v1,v1a,v1b,v1c,v1d,part1d,index,v1rop;
    
    int v5[]={1,5,4,2,3,0};
    
    char part2[32]={0};
    
    char part1[17]={0};
    
    char c[]={0x2C,0x21,0x1e,0x73,0x32,0x12,0x72,0x37,0x10,0x38,0x38,0x1,0x1D,0x6B,0x66,0x79,0x79,0x26};
    
    unsigned int road[30]={0};
    
    unsigned int map[]={0X1B,0X5D,0X42,0X2B,0X0D,0X05,0X48,0XE6,0X35,0X16,0X9E,0XB5,0XBB,0XE3,0X24,0X0F,0X13,0XC0,0X59,0X96,0X5A,0X12,0X2B,0XE0,0X8F,0X21,0X8C,0X52,0XDE,0X92,0X12,0X84,0XA3,0XE2,0X6E,0X7B,0X76,0XA2,0X0F,0X51,0X93,0XA9,0X78,0XAB,0X5F,0X5E,0X16,0X82,0X72,0X82,0X26,0XD1,0X26,0XD4,0X09,0XBF,0X74,0XDA,0XA7,0X3E,0X99,0X02,0X65,0XC3,0XB3,0XAD,0XE0,0X5A,0XAB,0X7A,0X83,0X93,0X3F,0XA4,0X11,0X3D,0X8E,0X0D,0XDF,0X5A,0X71,0X08,0X3A,0XC8,0XF4,0X90,0X16,0X1B,0X88,0XC6,0X50,0X6F,0XD1,0XA4,0XB3,0X73,0X7B,0X82,0XBF,0XB2,0X5F,0X94,0XDE,0XCA,0X5A,0X5E,0XAB,0X25,0XBE,0X8C,0X1B,0X80,0X65,0X9E,0XEC,0X5A,0X37,0X2A,0X75,0X2C,0X2D,0XBA,0X56,0XD0,0XBA,0X3A,0XB6,0X94,0X81,0X70,0X87,0X75,0X3D,0X48,0X63,0X7D,0X52,0X81,0X39,0XB5,0X23,0XD4,0XD3,0XDD,0X4B,0XD9,0XB8,0X35,0XA3,0XCA,0X40,0X77,0X52,0X7C,0X9E,0X6C,0X42,0XD8,0X53,0X6F,0XEA,0X2E,0X0C,0X9A,0XF3,0X2A,0X6A,0XD5,0XEA,0X6B,0X93,0X2F,0X18,0X5C,0XBE,0X96,0XB4,0X26,0X0F,0XDB,0X9F,0X07,0X30,0XAF,0X93,0X34,0X27,0X8E,0X0A,0XCA,0X53,0XB7,0XC9,0X8F,0X9B,0X40,0X87,0X54,0X50,0X53,0X1E,0X55,0X06,0X04,0X87,0XC9,0X5E,0X78,0XA0,0X3F,0X66,0X08,0XB0,0X09,0X6E,0X83,0XE5,0X6C,0X23,0XE6,0X74,0X83,0X01,0XA4,0X7F,0X62,0X39,0X09,0X94,0X32,0XD3,0X88,0X93,0X61,0XC2,0XC6,0X61,0X6B,0X28,0XC7,0X61,0XDD,0XDB,0X90,0XA9,0XD5,0XD8,0X8A,0XA4,0XA0,0X65,0XC1,0X35,0X41,0XBA,0XCF,0X4A,0X47,0XCA,0XAF,0X51,0XE1,0X72,0X5A,0XBF,0X1E,0XB3,0X7A,0X80,0XF2,0X7A,0XCB,0X25,0XE6,0X98,0X96,0X1B,0X53,0X44,0XD8,0X3C,0XAC,0X12,0XB1,0X64,0X47,0X35,0X00,0XFF,0XFF,0XFF,0XFF};
    
    for(i=0;i<18;i++){
    
    c[i]^=0x45;
    
    }
    
    for (j=17;j>=0;j--){
    
    part2[6*(j/6)+v5[j%6]]=c[j];
    
    }
    
    for (j=0;j<18;j++){
    
    part2[j]^=j;
    
    }
    
    //part1:
    
    road[26]=0XCC227F52;
    
    road[27]=0X5227AA48;
    
    road[28]=0X34725FD0;
    
    road[29]=0X0F276B39;
    
    for(i=25;i>=0;i--){
    
    index=road[i+1]^road[i+2]^road[i+3];
    
    v1=(map[index>>24]<<24)|(map[(index>>16)&0xFF]<<16)|(map[(index>>8)&0xFF]<<8)|map[index&0xFF];
    
    v1rop=((v1>>6)|(v1<<26))^((v1>>8)|(v1<<24))^((v1<<10)|(v1>>22))^((v1<<12)|(v1>>20));
    
    road[i]=road[i+4]^v1rop;
    
    }
    
    strncpy(part1,(char *)road,16);
    
    printf("UNCTF{%s-%s}",part1,part2);
    
    return 0;
    
    }

    UNCTF{1_th1nk_re_e4sy!-Wh4t_aB0ut_yoU233?}

     

    666

    输入18位串,经过变换后和目标串izwhroz""w"v.K".Ni对比,这个可以逆推回去。

     

    #include<stdio.h>
    
    int main(){
    
    char i;
    
    char target[]="izwhroz""w"v.K".Ni";
    
    for(i=0;i<18;i+=3){
    
        target[i]=(target[i]^18)-6;
    
        target[i+1]=(target[i+1]^18)+6;
    
        target[i+2]=(target[i+2]^18)^6;
    
    }
    
    puts(target);
    
    return 0;
    
    }

    输出:unctf{b66_6b6_66b}

     

    BabyXor

    这个需要用到一些动态调试技巧。

    用OD载入,先运行起来,在待输入时按暂停。点击K查看堆栈调用,发现了ReadConsoleA这个函数,但这是系统api,没有价值,所以右击,显示调用,再右击选择执行到返回,再稍微往下走出retn,就能见到程序的调用代码。选中的call就是刚才的api。下面就是对输入的处理了。

     

    紧接着有段代码读取输入:

     

     再往后rern出去,有三个函数生成了flag:

     

     

     

    flag{2378b077-7d6e-4564-bdca-7eec8eede9a2}

     

    unctf_easy_Maze

    IDA分析得知main里有三个主要函数,step0和step1用来生成一张7X7的地图,step2读取键位,并且判断当前地图是否为1.

     

    生成地图的函数算法过于复杂,但可以通过动态调试看数据来直接看到结果。

    在step2下断,程序运行到这里后进call,找到a1的地址,在数据窗口找到,把49个字节复制出来,转换成地图即可。

     

    UNCTF{ssddwdwdddssaasasaaassddddwdds}

     

    奇怪的数组

    IDA查看后得知要求输入格式为flag{32位数据},其中32位数据为0-9和a-f。每次两个数字转成16进制数后和checkbox里的数比较,循环15次。所以把checkbox的数翻译成小写即可。

    flag{ad461e203c7975b35e527960cbfeb06c}

    easyvm

    vm把函数入口和调用过程做的很复杂,经过判断后下图黄色代码原本是一个函数,功能是提供其他函数的入口。

    把里面全部函数下断,看得出程序源码大概是这样的:

    #include<stdio.h>
    
    int main(){
    
    int i;
    
    unsigned char a16=0,a17=0;
    
    char input[]="66666666666666666666666666666666";
    
    unsigned char c[32]={0xF4,0x0A,0xF7,0x64,0x99,0x78,0x9E,0x7D,
    
                0xEA,0X7B,0X9E,0X7B,0X9F,0X7E,0XEB,0X71,
    
                0XE8,0X00,0XE8,0X07,0X98,0X19,0XF4,0X25,
    
                0XF3,0X21,0XA4,0X2F,0XF4,0X2F,0XA6,0X7C};
    
    for(i=0;i<32;i++){
    
      a16=input[i];
    
      a16-=i;
    
      a17=a16 ^ a17;
    
      a16=-51;
    
      a16=a16^a17;
    
      if(a16==c[i]){
    
        puts("YES");
    
        a17=a16;
    
      }
    
      else{
    
        puts("NO");
    
        break;
    
      }
    
    }
    
    return 0;
    
    }

    写出相应的解密脚本:

    #include<stdio.h>
    
    int main(){
    
    int i;
    
    unsigned char a16=0,a17=0;
    
    unsigned char c[32]={0xF4,0x0A,0xF7,0x64,0x99,0x78,0x9E,0x7D,
    
                0xEA,0X7B,0X9E,0X7B,0X9F,0X7E,0XEB,0X71,
    
                0XE8,0X00,0XE8,0X07,0X98,0X19,0XF4,0X25,
    
                0XF3,0X21,0XA4,0X2F,0XF4,0X2F,0XA6,0X7C};
    
    printf("9");
    
    for(i=1;i<32;i++){
    
    printf("%c",(c[i]^(-51)^c[i-1])+i);
    
    }
    
    return 0;
    
    }

    UNCTF{942a4115be2359ffd675fa6338ba23b6}

     

     

     

     

    WEB

     checkin

    右键查看源代码,查看app.03bc1faf.js,发现聊天窗提供了一些指令,尝试/flag无效果后又看到了/calc指令,可以进行数学计算,尝试了一些命令后发现fs部分命令可用,进行同步读取目录:
    /calc require('fs').readdirSync('../')
    发现根目录下有flag,再用readdirSync('../flag')查看目录时报错,说明flag不是目录是文件。
    所以进行同步读取文件:
    /calc require('fs').readFileSync('../flag'),返回了一个文件对象,重新用burp抓包可以看到对象的具体内容,ascii解码后就是flag

     

    #!python3
    
    flag=[102,108,97,103,123,48,101,52,100,49,57,56,48,101,102,54,102,56,97,56,49,52,50,56,102,56,51,101,56,101,49,99,54,101,50,50,98,125,10]
    
    for i in flag:
    
        print(chr(i),end='')

    flag{0e4d1980ef6f8a81428f83e8e1c6e22b}

     

     

     

    MISC

    信号不好我先挂了

    用stegsolve打开apple.png, 选择data extract,在rgb最低位有位隐写,把它提取出后得到一个压缩包,但这个压缩包后面还有一段垃圾数据,使得无法解压,直接用binwalk强制解压,得到一张图片pen。想到了PPAP这首歌,应该是把两张图片结合,stegsolve尝试了imege_combiner的xor, and ,add 后都不行,想到盲水印也是需要两张图,用工具BlindWaterMark,得出flag:

    unctf{9d0649505b702643}

    快乐游戏题

     

    亲爱的

    用binwalk扫一下得知文件隐写了一个zip,zip有密码,旁边的提示写着qq音乐和一个日期,猜测是在那个时间点的一条评论。先找到李现唱的海阔天空https://c.y.qq.com/base/fcgi-bin/u?__=YTLCV4E,翻评论发现密码,解压后是一张图片,图片也有隐写内容,提取后在里面的word/media里有张图片,写着flag.

    UNCTF{W3_L0v3_Unctf}

     

     

    Think

    这题是一个python的混淆代码,没有完全读懂,但可以看一些关键操作。解密代码是

    chr((ord(__l['key'][(__l['i'] % len(__l['key']))]) ^ ord(__l['encrypted'][__l['i']].decode('base64').decode('hex')),可以看到是把后面的base64解密后和key循环异或,i是索引。据此写出代码:

    #!python2
    
    import sys
    
    enc=['MTM=', 'MDI=', 'MDI=', 'MTM=', 'MWQ=', 'NDY=', 'NWE=', 'MDI=', 'NGQ=', 'NTI=', 'NGQ=', 'NTg=', 'NWI=', 'MTU=', 'NWU=', 'MTQ=', 'MGE=', 'NWE=', 'MTI=', 'MDA=', 'NGQ=', 'NWM=', 'MDE=', 'MTU=', 'MDc=', 'MTE=', 'MGM=', 'NTA=', 'NDY=', 'NTA=', 'MTY=', 'NWI=', 'NTI=', 'NDc=', 'MDI=', 'NDE=', 'NWU=', 'MWU=']
    
    key='unctf'
    
    for i in range(38):
    
        sys.stdout.write(chr(ord(key[i%5])^ord(enc[i].decode('base64').decode('hex'))))

    flag{34a94868a8ad9ff82baadb326c513d40}

     

    不仅仅是RSA

    对公钥提取出N1, N2, E,摩斯电码用morse code reader识别出C1,C2,把N在http://www.factordb.com/ 分解,得

    P1=95652716952085928904432251307911783641637100214166105912784767390061832540987

    Q1=107527961531806336468215094056447603422487078704170855072884726273308088647617

    P2=89485735722023752007114986095340626130070550475022132484632643785292683293897

    Q2=95652716952085928904432251307911783641637100214166105912784767390061832540987

    写脚本:

    #!python2
    
    import gmpy2
    
    from Crypto.Util.number import *
    
    from Crypto.PublicKey import RSA
    
    f = open("pubkey1.pem", "r")
    
    key = RSA.importKey(f.read())
    
    n1=key.n
    
    e1=key.e
    
    print ('N1=',n1)
    
    print ('E1=',e1) #然后分解N
    
    f = open("pubkey2.pem", "r")
    
    key = RSA.importKey(f.read())
    
    n2=key.n
    
    e2=key.e
    
    print ('N2=',n2 )
    
    print ('E2=',e2)
    
    p1=95652716952085928904432251307911783641637100214166105912784767390061832540987
    
    q1=107527961531806336468215094056447603422487078704170855072884726273308088647617
    
    p2=89485735722023752007114986095340626130070550475022132484632643785292683293897
    
    q2=95652716952085928904432251307911783641637100214166105912784767390061832540987
    
     
    
    phi1=(p1-1)*(q1-1)
    
    c1=4314251881242803343641258350847424240197348270934376293792054938860756265727535163218661012756264314717591117355736219880127534927494986120542485721347351L
    
    d1=gmpy2.invert(e1,phi1)
    
    m1=gmpy2.powmod(c1,d1,n1)
    
    print hex(m1)[2:].decode('hex')
    
     
    
    phi2=(p2-1)*(q2-1)
    
    c2=485162209351525800948941613977942416744737316759516157292410960531475083863663017229882430859161458909478412418639172249660818299099618143918080867132349L
    
    d2=gmpy2.invert(e2,phi2)
    
    m2=gmpy2.powmod(c2,d2,n2)
    
    print hex(m2)[2:].decode('hex')

    UNCTF{ac01dff95336aa470e3b55d3fe43e9f6}

     

     

  • 相关阅读:
    连接mysql慢或者多台服务器ping不通mysql
    java8 Stream
    Idea 提示xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
    sublime Text的使用
    BigDecimal 加减乘除 比较大小 setScale(精度处理)
    kubectl 命令
    mac brew命令的使用
    mysql json
    idea open打开项目之后,project里没有目录结构。
    mac 多显示器焦点快速切换
  • 原文地址:https://www.cnblogs.com/cnnnnnn/p/11824564.html
Copyright © 2011-2022 走看看