EASYHOOK
exe,查壳,没有壳,32位,运行发现是输入flag形式
拖入ida,看主函数,分析伪代码
调用了系统函数,创建文件和往文件里面写东西
先追踪sub_401240函数
sub_401240函数里面的while循环条件是一个变化的,所以是用来混淆的,不用看了(这是一种经验)
打开创建的文件,不知道什么意思
只剩下sub_401220函数没有分析了
不过多关注系统函数,所以主要追踪sub_4010D0函数
查询,问ai知道了这里执行到WriteFile函数的时候就会变成一个跳转语句,跳转到目标地址跟踪该函数:所以真加密函数是sub_401140
写脚本
flag=list("-------------------")
print(len(flag))
key1="ajygkFm.\x7f_~-SV{8mLn"
flag[18]=chr(ord(key1[18])^19)
for i in range(18):
v3=ord(key1[i])^i
if i%2==1: #把18的判断条件抽出去后里面就只有一层条件了,简便很多。
flag[i]=chr(v3+i)
else:
flag[i+2]=chr(v3)
print(''.join(flag))
gametime
通过名字和运行程序知道这是道游戏题,一般思路都是找判断改汇编条件
分不清哪些条件,那就全改
汇编,改je
Replace
查壳,有upx壳
脱完壳,拖入ida,看main
跟踪sub_401090
有三个参数
byte_402150
byte_402151
byte_4021A0
用lazyida的convert功能
32h
61h
[0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16]
编写脚本
list1=[50, 97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list2=[97, 52, 57, 102, 54, 57, 99, 51, 56, 51, 57, 53, 99, 100, 101, 57, 54, 100, 54, 100, 101, 57, 54, 100, 54, 102, 52, 101, 48, 50, 53, 52, 56, 52, 57, 53, 52, 100, 54, 49, 57, 53, 52, 52, 56, 100, 101, 102, 54, 101, 50, 100, 97, 100, 54, 55, 55, 56, 54, 101, 50, 49, 100, 53, 97, 100, 97, 101, 54]
list3=[99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
v4=0
flag=""
for i in range(35):
v8=list1[2*i]
if v8 < 48 or v8 > 57:
v9=v8 - 87
else:
v9=v8 - 48
v10=list2[2*i]
v11=16*v9
if v10 <48 or v10 > 57:
v12=v10-87
else:
v12=v10-48
v4=((v11+v12)^25)
flag+=chr(list3.index(v4)) //直接取下标索引
print(flag)
toddler_regs
很简单啊,ida看主函数,发现没有什么东西
shift+f12看见了flag{
交叉引用后就是发现就是strcat链接了几个字符串
其中两个是地址
在一个函数中发现 dword_14001FB90 = 23,事实上我一开始每看到flag字符串,先进入的这个函数
计算一下
flag{Xp0int_1s_n1c3_but_Xp0intJNU_is_we1rd}
[WUSTCTF2020]Cr0ssfun-buuctf
固定查壳,拖入64位ida,看主函数,一开始追踪了一次check函数,发现没什么东西,后来分析完整个主函数发现没什么东西了
查找了一下字符串,发现check是个间接函数,在进一步追踪一下
然后进两步进三步,分析完所有条件就可以写脚本了
#include<stdio.h>
int main()
{
int a1[50]={0};
int i;
a1[10] =112;
a1[13]=64;
a1[3]=102;
a1[26]=114;
a1[20]=101;
a1[7]=48;
a1[16]=95;
a1[11]=112;
a1[23]=101;
a1[30]=117;
a1[0]=119;
a1[6]=50;
a1[22]=115;
a1[31]=110;
a1[12]=95;
a1[15]=100;
a1[8]=123;
a1[18]=51;
a1[28]=95;
a1[21]=114;
a1[2]=116;
a1[9]=99;
a1[32]=125;
a1[19]=118;
a1[5]=48;
a1[14]=110;
a1[4]=50;
a1[17]=114;
a1[29]=102;
a1[17]=114;
a1[24]=95;
a1[1]=99;
a1[25]=64;
a1[27]=101;
for(i=0;i<50&&a1[i]!=0;i++)
printf("%c",a1[i]);
}
wctf2020{cpp_@nd_r3verse_@re_fun}
[ACTF新生赛2020]SoulLike
还是老样子,查壳,拖入64位ida,看main
关键函数是sub_84A,但是打不开,看了网上的教程,发现是函数长度太长了
找到ida目录中的cfg的hexrays.cfg点击进去将MAX_FUNCSIZE 由64修改为1024,在打开ida点击sub_83A就可以了。
然后打开函数时间可能有点长,等一下就好了
函数非常长,但全是单次简单运算,一直反着写脚本不太现实
两种方法
一.直接复制粘贴到word或者excal用全局替换
二.这种情况直接考虑爆破
from pwn import *
flag="actf{"
k=0
for n in range(12):
for i in range(33,127):
p=process("./SoulLike")
_flag=flag+chr(i)
print(_flag)
p.sendline(_flag)
s=p.recvline().decode()
if "on #" in s:
r=int(s.split("on #")[1].split("\n")[0])
if r==k+1:
print(s)
flag+=chr(i)
k+=1
p.close()
print(flag)
flag{b0Nf|Re_LiT!}
[SUCTF2018]babyre
老样子,查壳,拖入ida,先看到左边一堆函数,我在想会不会让程序无法运行或者反调试、
找不到主函数,shift+f12看字符串,好像有base64编码
跟踪一下,说实话,看了半天没看明白,网上搜了一下,发现自己方向错了,base64只是一小部分,重要的是you found me,跟踪进去,这个函数有点恐怖,后面基本都是跟着其他厉害的师傅走的
那就一点一点来
第一部分分析完后写脚本
v17[1] = 111
v17[2] = 100
v17[3] = 108
v17[4] = 62
v17[5] = 81
v17[6] = 110
v17[7] = 98
v17[8] = 40
v17[9] = 111
v17[10] = 99
v17[11] = 121
v17[12] = 127
v17[13] = 121
v17[14] = 46
v17[15] = 105
v17[16] = 127
v17[17] = 100
v17[18] = 96
v17[19] = 51
v17[20] = 119
v17[21] = 125
v17[22] = 119
v17[23] = 101
v17[24] = 107
v17[25] = 57
v17[26] = 123
v17[27] = 105
v17[28] = 121
v17[29] = 61
v17[30] = 126
v17[31] = 121
v17[32] = 76
v17[33] = 64
v17[34] = 69
v17[35] = 67
flag=""
for i in range(36):
flag+=chr(v17[i]^i)
print(flag)
Info:The first four chars are `flag`
继续走
后面结合之前的base64编码,猜测是base64编码,而且编码了10次,结果居然是个网站,但是我不知道为啥访问不了,看别的师傅好像是看雪的博客
import base64
lis ="Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=="
for i in range(10):
lis = base64.b64decode(lis)
print(lis)
继续走,已经要看晕了,简单来说
发现此函数的逻辑就是将byte_6CC0A0字符串进行异或,还可以发现if语句中,有判断是否等于‘f’和‘g’的条件,根据已有信息猜测这个字符数组就是‘flag’。v12和v15是一样的一个数组,HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()、BYTE1()、BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。所以可以知道v15这个数组就只有四个字符而且和byte_6CC0A0
前4个字符异或后就==字符“flag”。
脚本
enc = [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]
key = ""
flag = ""
en = "flag"
for i in range(4):
key+=chr(enc[i]^ord(en[i]))
print(key)
for j in range(len(enc)):
flag+=chr(enc[j]^ord(key[j%4]))
print(flag)
flag为flag{Act1ve_Defen5e_Test}
[SUCTF2018]babyre
一样,查壳,拖入ida,已经有点晕了,看了别人的分析
直接上脚本把
#include<stdio.h>
#include<string.h>
int main()
{
char v4[300];
char flag[100]={0};
int v9,v10;
v4[0] = 2;
v4[1] = 3;
v4[2] = 2;
v4[3] = 1;
v4[4] = 4;
v4[5] = 7;
v4[6] = 4;
v4[7] = 5;
v4[8] = 10;
v4[9] = 11;
v4[10] = 10;
v4[11] = 9;
v4[12] = 14;
v4[13] = 15;
v4[14] = 12;
v4[15] = 13;
v4[16] = 16;
v4[17] = 19;
v4[18] = 16;
v4[19] = 17;
v4[20] = 20;
v4[21] = 23;
v4[22] = 22;
v4[23] = 19;
v4[24] = 28;
v4[25] = 25;
v4[26] = 30;
v4[27] = 31;
v4[28] = 28;
v4[29] = 25;
v4[30] = 26;
v4[31] = 31;
memcpy(&v4[32], "$!\"'$!\"#().+$-&/81:;4=>7092;<567HIBBDDFGHIJJMMONPPRSUTVWYYZ[\\]^^``ccdeggiikklmnnpprstuwwxy{
{}}", 94);
v4[126] = 0x7F;
v4[127] = 0x7F;
v4[128] = 0x81;
v4[129] = 0x81;
v4[130] = 0x83;
v4[131] = 0x83;
v4[132] = 0x8C;
v4[133] = 0x8D;
v4[134] = 0x8E;
v4[135] = 0x8F;
v4[136] = 0x88;
v4[137] = 0x89;
v4[138] = 0x8A;
v4[139] = 0x8B;
v4[140] = 0x8C;
v4[141] = 0x8D;
v4[142] = 0x8E;
v4[143] = 0x87;
v4[144] = 152;
v4[145] = -111;
v4[146] = 0x92;
v4[147] = 147;
v4[148] = 0x94;
v4[149] = 0x95;
v4[150] = 0x96;
v4[151] = -105;
v4[152] = -104;
v4[153] = -103;
v4[154] = -102;
v4[155] = -102;
v4[156] = -100;
v4[157] = -100;
v4[158] = -98;
v4[159] = -98;
v4[160] = -96;
v4[161] = -96;
v4[162] = -94;
v4[163] = -94;
v4[164] = -92;
v4[165] = -92;
v4[166] = -90;
v4[167] = -90;
v4[168] = -88;
v4[169] = -88;
v4[170] = -86;
v4[171] = -86;
v4[172] = -84;
v4[173] = -84;
v4[174] = -82;
v4[175] = -82;
v4[176] = 0xB0;
v4[177] = 0xB1;
v4[178] = 178;
v4[179] = 179;//这里将v4与v5连起来,首先它们共处一个寄存器,其次我发现如果单独用一个v4或者v5是不可得到flag的
for(int k=0;k<0x10000;k++)
{
memset(flag, 0, 0x1F);
flag[30]=8;
while(flag[30])
{
--flag[30];
for(int i=22;i;flag[i]|=v10<<flag[30])
{
v9=v4[22*flag[30]+--i];
v10=(v9>>((k>>(2*flag[30]))&3))&1;
}
}
if (flag[0] == 'S' && flag[1] == 'U' && flag[2] == 'C' && flag[3] == 'T' && flag[4] == 'F')//这里根据 sub_140011159(std::cout, "flag format: SUCTF{xxxxxxxxxxxxxxx}\n");得出的
{
for (int j = 0; j < 22; j++)
printf("%c", flag[j]);
}
}
}
//SUCTF{Flag_8i7244980f}
flag是SUCTF{Flag_8i7244980f}