Reverse
unctf_babyre2
这题flag分为两部分,第一部分每四个字符一组打包成int后,每次把四个int传入函数,后三个参数异或后先以每位为索引查表,将新数据进行循环移位、异或,将结果与第一个参数异或。此操作进行了26次,通过最后的一组结果可以慢慢倒推回去。第二部分是对字符串进行常规的异或操作与目标串比较。
脚本:
#include
#include
int main(){
int i,j;
unsigned int v40,v41,v42,v43,v44,v39,v1,v1a,v1b,v1c,v1d,part1d,index,v1rop;
int v5[]={,,,,,};
char part2[]={};
char part1[]={};
char c[]={0x2C,0x21,0x1e,0x73,0x32,0x12,0x72,0x37,0x10,0x38,0x38,0x1,0x1D,0x6B,0x66,0x79,0x79,0x26};
unsigned int road[]={};
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=;i<;i++){
c[i]^=0x45;
}
for (j=;j>=;j--){
part2[*(j/)+v5[j%]]=c[j];
}
for (j=;j<;j++){
part2[j]^=j;
}
//part1:
road[]=0XCC227F52;
road[]=0X5227AA48;
road[]=0X34725FD0;
road[]=0X0F276B39;
for(i=;i>=;i--){
index=road[i+]^road[i+]^road[i+];
v1=(map[index>>]<<)|(map[(index>>)&0xFF]<<)|(map[(index>>)&0xFF]<<)|map[index&0xFF];
v1rop=((v1>>)|(v1<<))^((v1>>)|(v1<<))^((v1<<)|(v1>>))^((v1<<)|(v1>>));
road[i]=road[i+]^v1rop;
}
strncpy(part1,(char *)road,);
printf("UNCTF{%s-%s}",part1,part2);
return ;
}
UNCTF{1_th1nk_re_e4sy!-Wh4t_aB0ut_yoU233?}
666
输入18位串,经过变换后和目标串izwhroz""w"v.K".Ni对比,这个可以逆推回去。
#include
int main(){
char i;
char target[]="izwhroz\"\"w\"v.K\".Ni";
for(i=;i<;i+=){
target\[i\]=(target\[i\]^)-;
target\[i+\]=(target\[i+\]^)+;
target\[i+\]=(target\[i+\]^)^;
}
puts(target);
return ;
}
输出: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
int main(){
int i;
unsigned char a16=,a17=;
char input[]="";
unsigned char c[]={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=;i<;i++){
a16=input[i];
a16-=i;
a17=a16 ^ a17;
a16=-;
a16=a16^a17;
if(a16==c[i]){
puts("YES");
a17=a16;
}
else{
puts("NO");
break;
}
}
return ;
}
写出相应的解密脚本:
#include
int main(){
int i;
unsigned char a16=,a17=;
unsigned char c[]={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("");
for(i=;i<;i++){
printf("%c",(c[i]^(-)^c[i-])+i);
}
return ;
}
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=[,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,]
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():
sys.stdout.write(chr(ord(key\[i%\])^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=
q1=
p2=
q2=
phi1=(p1-)*(q1-)
c1=4314251881242803343641258350847424240197348270934376293792054938860756265727535163218661012756264314717591117355736219880127534927494986120542485721347351L
d1=gmpy2.invert(e1,phi1)
m1=gmpy2.powmod(c1,d1,n1)
print hex(m1)[:].decode('hex')
phi2=(p2-)*(q2-)
c2=485162209351525800948941613977942416744737316759516157292410960531475083863663017229882430859161458909478412418639172249660818299099618143918080867132349L
d2=gmpy2.invert(e2,phi2)
m2=gmpy2.powmod(c2,d2,n2)
print hex(m2)[:].decode('hex')
UNCTF{ac01dff95336aa470e3b55d3fe43e9f6}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章