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}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM