21.[FlareOn4]login
下载完成后发现是HTML文件,使用VScode打开,也可以直接进入网页F12查看源代码
<!DOCTYPE Html />
<html>
<head>
<title>FLARE On 2017</title>
</head>
<body>
<input type="text" name="flag" id="flag" value="Enter the flag" />
<input type="button" id="prompt" value="Click to check the flag" />
<script type="text/javascript">
document.getElementById("prompt").onclick = function () {
var flag = document.getElementById("flag").value;
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
}
</script>
</body>
</html>
分析代码,发现是rot13加密,使用随波逐流解密
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
得到flag{ClientSideLoginsAreEasy@flare-on.com}
22.CrackRTF
下载完成后,打开查看,然后查壳
得到,没有壳,32位
拖入IDA32分析,
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
DWORD v3; // eax
DWORD v4; // eax
char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
int v7; // [esp+150h] [ebp-20Ch]
char String1[260]; // [esp+154h] [ebp-208h] BYREF
char Destination[260]; // [esp+258h] [ebp-104h] BYREF
memset(Destination, 0, sizeof(Destination));
memset(String1, 0, sizeof(String1));
v7 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", Destination);
if ( strlen(Destination) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v7 = atoi(Destination);
if ( v7 < 100000 )
ExitProcess(0);
strcat(Destination, "@DBApp");
v3 = strlen(Destination);
sub_40100A((BYTE *)Destination, v3, String1);
if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): ");
memset(Str, 0, sizeof(Str));
scanf("%s", Str);
if ( strlen(Str) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(Str, Destination);
memset(String1, 0, sizeof(String1));
v4 = strlen(Str);
sub_401019((BYTE *)Str, v4, String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
{
if ( !(unsigned __int8)sub_40100F(Str) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}
进入sub_40100A中发现是哈希解密,写py脚本爆破
import hashlib
flag="@DBApp"
for i in range(100000,999999):
s=str(i)+flag
x=hashlib.sha1(s.encode())
cnt=x.hexdigest()
if "6e32d0943418c2c33385bc35a1470250dd8923a9"in cnt:
print(cnt)
print(str(i)+flag)
得出
123321@DBApp
然后再进入下一个函数,发现还是哈希加密,这个试了很多最后在在线的哈希解密解出来了
得到 ~!3a@0123321@DBApp ,猜测密码2是~!3a@0。打开下载的文件
依次输入密码得到
Flag{N0_M0re_Free_Bugs}
23.[WUSTCTF2020]level1
下载完成后,打开发现有两个文件,先打开文本文件output查看,发现一堆数字,根据文件名猜测是输出。
另一个level1文件,查壳分析
无壳,直接进入IDA分析,
int __cdecl main(int argc, const char **argv, const char **envp)
{
int i; // [rsp+4h] [rbp-2Ch]
FILE *stream; // [rsp+8h] [rbp-28h]
char ptr[24]; // [rsp+10h] [rbp-20h] BYREF
unsigned __int64 v7; // [rsp+28h] [rbp-8h]
v7 = __readfsqword(0x28u);
stream = fopen("flag", "r");
fread(ptr, 1uLL, 0x14uLL, stream);
fclose(stream);
for ( i = 1; i <= 19; ++i )
{
if ( (i & 1) != 0 )
printf("%ld\n", (unsigned int)(ptr[i] << i));
else
printf("%ld\n", (unsigned int)(i * ptr[i]));
}
return 0;
}
发现代码逻辑非常简单,我们直接写脚本来试试
a=[198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000]
for i in range(1,len(a)+1):
if(i%2==0):
print(chr(a[i-1]//i),end='')
else:
print(chr(a[i-1]>>i),end='')
得到 ctf2020{d9-dE6-20c}
将替换为flag{d9-dE6-20c}
24.[GUET-CTF2019]re
下载完后发现有一个文件和一个文件夹里放着一个文件,查壳re,发现是upx壳
查壳._re,发现好像是空的,先不管它了
用upx工具先脱壳re。
脱壳后拖入IDA分析,找了半天,才找到这个关键的部分,根据代码逻辑,编写脚本,逆它。
_BOOL8 __fastcall sub_4009AE(char *a1)
{
if ( 1629056 * *a1 != 166163712 )
return 0LL;
if ( 6771600 * a1[1] != 731332800 )
return 0LL;
if ( 3682944 * a1[2] != 357245568 )
return 0LL;
if ( 10431000 * a1[3] != 1074393000 )
return 0LL;
if ( 3977328 * a1[4] != 489211344 )
return 0LL;
if ( 5138336 * a1[5] != 518971936 )
return 0LL;
if ( 7532250 * a1[7] != 406741500 )
return 0LL;
if ( 5551632 * a1[8] != 294236496 )
return 0LL;
if ( 3409728 * a1[9] != 177305856 )
return 0LL;
if ( 13013670 * a1[10] != 650683500 )
return 0LL;
if ( 6088797 * a1[11] != 298351053 )
return 0LL;
if ( 7884663 * a1[12] != 386348487 )
return 0LL;
if ( 8944053 * a1[13] != 438258597 )
return 0LL;
if ( 5198490 * a1[14] != 249527520 )
return 0LL;
if ( 4544518 * a1[15] != 445362764 )
return 0LL;
if ( 3645600 * a1[17] != 174988800 )
return 0LL;
if ( 10115280 * a1[16] != 981182160 )
return 0LL;
if ( 9667504 * a1[18] != 493042704 )
return 0LL;
if ( 5364450 * a1[19] != 257493600 )
return 0LL;
if ( 13464540 * a1[20] != 767478780 )
return 0LL;
if ( 5488432 * a1[21] != 312840624 )
return 0LL;
if ( 14479500 * a1[22] != 1404511500 )
return 0LL;
if ( 6451830 * a1[23] != 316139670 )
return 0LL;
if ( 6252576 * a1[24] != 619005024 )
return 0LL;
if ( 7763364 * a1[25] != 372641472 )
return 0LL;
if ( 7327320 * a1[26] != 373693320 )
return 0LL;
if ( 8741520 * a1[27] != 498266640 )
return 0LL;
if ( 8871876 * a1[28] != 452465676 )
return 0LL;
if ( 4086720 * a1[29] != 208422720 )
return 0LL;
if ( 9374400 * a1[30] == 515592000 )
return 5759124 * a1[31] == 719890500;
return 0LL;
}
PY脚本,注意这里少了一个a1[6]的值,得到flag{e65421110ba03099a1c039337},a[6]需要硬猜,所以这里我直接一个个的猜,最后得到正确的flag{e165421110ba03099a1c039337}
a=[102,108,97,103,123,101,54,53,52,50,49,49,49,48,98,97,48,51,48,57,57,97,49,99,48,51,57,51,51,55,125]
for i in range(len(a)):
print(chr(a[i]),end='')
25.[2019红帽杯]easyRE
查壳,无壳64位
拖入IDA64中静态分析,shift+f12查看字串
发现可疑字串,双击查看,猜测是base64加密
丢进随波逐流去解密,刚刚解密发现还是一串看不懂的字符,以为搞错了,后面连续解了很多次,也没去数,最终得到一个网址。
然后进网址去看看,发现了这个,咋也不知道有啥用,就继续分析IDA了
在这个地方多来几次ctrl+x,然后F5反汇编
后面来写脚本,原以为这里就是了,我还是想的太简单了
flag1=''
key1=[0]*37
encode1='Iodl>Qnb(ocy'
a=0
for i in range(len(encode1)):
key1[i]=ord(encode1[i])
a+=1
key1[a]=127
a+=1
encode2='y.i'
for i in range(len(encode2)):
key1[i+13]=ord(encode2[i])
a+=1
key1[a]=127
a+=1
encode3='d`3w}wek9{iy=~yL@EC'
for i in range(len(encode3)):
key1[i+a]=ord(encode3[i])
for i in range(len(key1)):
flag1+=chr(key1[i]^i)
print(flag1)
得到的结果是
Info:The first four chars are flag
$
只是提示我们最开始的四个字母是flag,感觉没什么用
然后继续在IDA里分析,发现了这个
这里的原本只看出,这个for循环是在异或操作,然后找到byte_6CC0A0的值
这里就很清楚了,是一个数组,从40h开始,一直到5bh都是赋值
当我想直接根据这个来写解题脚本时,我却发现我不知到v4的值,根据这里%4推测v4时四位,还有我们前面解出的前四位是flag,猜测v4=‘flag’,再来写脚本解
发现这里也还不对,再仔细观察IDA发现,在这个if里有做异或运算,然后我们再把这里的异或运算写进脚本里,就得到了正确的结果(但其实这里还是不太明白,这里不应该是判断条件吗,怎么会做异或运算)
脚本
flag1=''
key1=[0]*37
encode1='Iodl>Qnb(ocy'
a=0
for i in range(len(encode1)):
key1[i]=ord(encode1[i])
a+=1
key1[a]=127
a+=1
encode2='y.i'
for i in range(len(encode2)):
key1[i+13]=ord(encode2[i])
a+=1
key1[a]=127
a+=1
encode3='d`3w}wek9{iy=~yL@EC'
for i in range(len(encode3)):
key1[i+a]=ord(encode3[i])
for i in range(len(key1)):
flag1+=chr(key1[i]^i)
print(flag1)
key=[0x40,0x35,0x20,0x56,0x5d,0x18,0x22,0x45,0x17,0x2f,0x24,0x6e,0x62,0x3c,0x27,0x54,0x48,0x6c,0x24,0x6e,0x72,0x3c,0x32,0x45,0x5b]
bekey='flag'
flag=''
a=[]
for i in range(len(bekey)):
a.append(ord(bekey[i])^key[i])
for i in range(len(key)):
flag+=chr(key[i]^a[i%4])
print(flag)
最终得到flag{Act1ve_Defen5e_Test}。
26.[MRCTF2020]Transform
查壳,64位无壳
拖入IDA64里面分析,进来就是关键代码,直接f5反编译
直接看代码逻辑,这里的逻辑很简单,关键在于这两个循环,第一个循环是在加密,就是简单的异或,第二个循环是在验证。然后我们双击dword_40F040,byte_40F0E0,找到对应的值
for ( i = 0; i <= 32; ++i )
{
byte_414040[i] = Str[dword_40F040[i]];
byte_414040[i] ^= LOBYTE(dword_40F040[i]);
}
for ( j = 0; j <= 32; ++j )
{
if ( byte_40F0E0[j] != byte_414040[j] )
{
sub_40E640("Wrong!\n");
system("pause");
exit(0);
}
}
这两个的值还是挨着的,我们直接根据这个开始写脚本。这里只需要,先异或再重新排序
PY脚本如下:
a=[0x9,0x0a,0x0f,0x17,0x7,0x18,0x0c,0x6,0x1,0x10,0x3,0x11,0x20,0x1d,0x0b,0x1e,0x1b,0x16,0x4,0x0d,0x13,0x14,0x15,0x2,0x19,0x5,0x1f,0x8,0x12,0x1a,0x1c,0x0e,0x0]
b=[0x67,0x79,0x7b,0x7f,0x75,0x2b,0x3c,0x52,0x53,0x79,0x57,0x5e,0x5d,0x42,0x7b,0x2d,0x2a,0x66,0x42,0x7e,0x4c,0x57,0x79,0x41,0x6b,0x7e,0x65,0x3c,0x5c,0x45,0x6f,0x62,0x4d]
c=[]
s=[0]*33
str=''
for i in range(33):
b[i]^=a[i]
for i in range(33):
s[a[i]]=b[i]
for i in range(33):
str+=chr(s[i])
print(str)
最终得到
MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}
flag就输入flag{Tr4nsp0sltiON_Clph3r_1s_3z}
27.[WUSTCTF2020]level2
查壳,upx加壳
使用upx去壳
之后再拖入IDA中分析
直接就发现了flag
wctf2020{Just_upx_-d}
改为flag{Just_upx_-d}
28.[SUCTF2019]SignIn
查壳,无壳64位程序
拖入IDA中分析,发现以下部分,并且发现两个可疑字符串
这里是很多中方式也没搞清楚这是啥,请假了一下学密码学的队友,像是RSA,但是好像没有p,q,上网找了一个分解因数的工具,yafu,分解因数,得到p,q.
再进入sub_96A当中去分析
之后写脚本
import gmpy2
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
e = 65537
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
d = gmpy2.invert(e, (p - 1) * (q - 1))
m = gmpy2.powmod(c, d, n)
print(hex(m)[2:])
得出,这一串也解了很久,后来试到16进制转字符串才得到结果
最终得到suctf{Pwn_@_hundred_years}
29.[ACTF新生赛2020]usualCrypt
下载完成后,查壳,32位无壳
直接拖入IDA中分析,shift+f12,查看字符串
找到了关键字符串,猜测是base64加密,直接解码却解不出来,继续分析
main函数,分析后,找到关键函数sub_401080,进入分析
发现这段就是在做base64加密,有一个关键函数sub_401000,进入分析,发现这里是在做交换。
继续分析,发现label_9里面还拥有一个函数sub_401030,进入后发现
这是在做大小写的交换。
其他的部分暂时没怎么关注,就围绕着自己找到的这几个关键函数,还有两个关键的字符串来解
因为直接base64解码不行,猜测是码表被修改过,根据找到的函数,要么是在第一个函数中被交换了,要么是大小写交换了,一个一个来。
先试一下第一个函数中的交换。分别查看byte_40E0AA和byte_40E0A0,发现,其实这是在同一个字符串当中,根据使用IDA的经验,这里就是同一个字符转不同位置的转换。
写脚本,找出新的码表
得到
ABCDEFQRSTUVWXYPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
再去解下一个关键字符串。
这里就应该是交换大小写了。
同样写脚本来解
得到
ZmxhZ3tiGNXlXjHfaDTzN2FfK3LycRTpc2L9
然后又找到一个根据码表来编码解码的base64脚本,修改脚本码表,运行脚本来解出结果
base64脚本出处http://t.csdn.cn/kXKdY
得到flag{bAse64_h2s_a_Surprise}
30.[HDCTF2019]Maze
查壳,32位,upx加壳,先脱壳
脱壳完成,为了方便,这里将文件名改成了abc.exe
放入IDA中分析,标红的部分很明显,之后尝试了好几次F5都没有用,应该就是这里的问题,网上查了很多,才知道这里是花指令,找到了两种解决的方法,先说成功的一种
选中call,快捷键u修改为二进制
然后将花指令之后的按键重新分析为代码
之后再选中左边全部红色的地址(我这里是从.text:00401000 到.text:004010FD ),按键p识别为函数,然后就得到的main函数,之后就是正常的步骤走了
F5反汇编,注意观察这段函数,‘wasd’,推测是一道走迷宫的题,双击dword_40807C查看
这里就找到的可疑字符串,再进行简单的排列
从+走到F就是flag了
得到flag{ssaaasaassdddw}
第二种方法请参考http://t.csdn.cn/POGJT
这次发布这篇文章与前两篇隔了很久,题难度在不断提升,当然也有自身的时间安排的原因,之后不会再这样十道题十道题的发,估计以后我也会一道题一道题的发,同时如果有任何问题,大家可以随时私信我,我也是在学习的阶段,想要和大家一起一同学习,一同进步。