re题解小结

内涵的软件:

32位无壳,shift+12查看字符串,提交通过,进一步查看原函数。

新年快乐:

32位有upx壳,

UPX是一个著名的压缩壳,主要功能是压缩PE文件(比如exe,dll等文件),有时候也可能被病毒用于免杀.壳upx是一种保护程序。一般是EXE文件的一种外保护措施,主要用途 :

1、让正规文件被保护起来,不容易被修改和破解。

2、使文件压缩变小。

进行脱壳,

提交通过

xor:

f5查看伪代码发现加密代码段,,查看global的数据shift+e查看global的值

编写一个脚本,得出flag,提交通过

helloworld1:

方法一:下载专用软件

打开后缀名是apk,下载专用软件,找到flag提交成功。

APK文件(是Android操作系统使用的一种应用程序包文件格式)

方法二:使用ida

首先更改后缀名为.zip,解压后使用ida64打开

shift+12查找字符串,alt+t快速搜索flag,找到提交

reverse3:

无壳32位,ida打开,f5查看伪代码

(判断是base64加密。判断技巧:①:字符串里有个等号;②:格式是abcdef.....基本可以判断是base64)

v5为Des,if里面strncmp判断Des和Str2是否相等,相等则输出正确的flag,str2内为关键内容

将v4的值赋给Des,然后对Des做了一个for循环运算

第22行的函数显然是输入函数,Str为你输入的flag,23行v3是flag的长度,然后关键点就在第24行的函数sub_4110BE对Str做的变换上

点进去,

输入了一个Str字符串,然后对字符串做了一个base64加密,该加密的值赋给了v4,v4被赋给了Des,Des做了一个for循环,该循环对Des做了变化,最后倘若Des与Str2相等则输出正确的flag

所以写解密脚本思路为:将Str2逆向还原为Des,再对Des做base64解码

使用工具64位解码,得到flag提交成功(水平有限,没能写出直接转码的脚本)

不一样的flag:

无壳32位,ida打开

确实很不一样,上下左右像是走迷宫,_data_start__是一个长度为26的字符串,除去一个空字符,存储的数据为25个,所以猜测是一个5*5的迷宫

关键:*11110100001010000101111#

不能走到1

*1111
01000
01010
00010
1111#,得到结果222441144222,提交成功

simple rev1:

64位无壳,ida64打开,查看原函数

若输入为dD则调用Decry函数,若输入为qQ则退出,所以找一下decry函数

先把key1和scr复制到key中然后对key进行一番操作,然后输入flag到str2中,对str2进行操作后跟text进行比较,比较正确则输出congratulation,我们已经知道了text里的值,我们可以逆向算法,推出输入的flag

(值得注意的是:key3为字符串按照正常顺序大端存储,而v9为数组,采用小端存储,在使用join方法时需要将v9倒过来读取。key1src同理)

text[] = 'killshadow'
key[] = 'ADSFKNDCLS'
脚本编译水平不够gpt也整错了

#include <stdio.h>

char mytolower(char c) {
    if (c >= 'A' && c <= 'Z') {
        return c + ('a' - 'A');
    }
    return c;
}

int main() {
    char key[] = "ADSFKNDCLS";
    int keyLen = sizeof(key) - 1;
    for (int i = 0; i < keyLen; i++) {
        key[i] = mytolower(key[i]);
    }

    char text[] = "killshadow";
    int textLen = sizeof(text) - 1;
    char flag[textLen + 1];

    for (int i = 0; i < textLen; i++) {
        int j = 0;
        while (1) {
            int cnt = (int)text[i] - 'a' + 26 * j + 39 - 'a' + (int)key[i];
            if (cnt >= 'A' && cnt < 'Z') {
                break;
            }
            else {
                j++;
            }
        }
        flag[i] = (char)(((int)text[i] - 'a' + 26 * j + 39 - 'a' + (int)key[i]) % 26) + 'a';
    }
    flag[textLen] = '\0';

    printf("flag{%s}\n", flag);

    return 0;
}

,参考大佬的结果, flag{KLDQCUDFZO}

JAVA逆向解密:

看后缀不一样,使用jd—gui打开:

找到需要逆向的部分:

编写脚本逆向得到答案。

lucky guy:

IDA64打开,找到main函数ctrl+x,f5反汇编

查看关键函数welcome和get flag

怪可爱的,

关键语句,取模之后就是0到200的随机数,case1的时候,输出flag:%s,现在任务来到找s,发现重要的f1和f2,任务来到查找f1和f2。

f1点进去猜测是flag的一半:

f2没有直接后半段,在case4中发现:

给s赋值,将s赋值给f2,f2是9180147350284624745

5次switch操作,for ( i = 0; i <= 4; ++i )

case4给f2赋值->case5对赋值后的f2操作->case1对于f1和f2进行拼接

编写脚本

2020JUST RE:

64位无壳,IDA打开shift+f12发现可疑字符串

ctrl+x查看

f5反汇编,

输出两个%d和那一大堆,把后面的19999和0加起来,得到flag提交通过。

刮开有奖:

无壳32位,IDA打开

找到关键函数f5反汇编sub_4010F0函数和sub_401000函数,分别看看,修改sub_4010F0伪代码为可执行代码输出结果:

双击sub_401000,发现数组byte_407830双击进入,发现为base64编码

v6要与"ak1w"相等,v7要与"V1Ax"相等

v6和v7都是经过base64编码后的字符串,所以我们分别对ak1wV1Ax进行解码即可,分别为jMpWP1

flag的第一位要等于v9的首位加34,为U

即v21为J
所以完整的flag应该为UJWP1jMp

简单注册器:

观察后缀为apk,放入APKIDE反编译

找到注入点以后使用jd—gui打开

v5是关键字段,根据加密过程编写脚本

#include <stdio.h>

void swap(char* a, char* b) {
    char temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    char str[] = {'d', 'd', '2', '9', '4', '0', 'c', '0', '4', '4', '6', '2', 'b', '4', 'd', 'd', '7', 'c', '4', '5', '0', '5', '2', '8', '8', '3', '5', 'c', 'c', 'a', '1', '5'};
    
    str[2] = str[2] + str[3] - 0x32;
    str[4] = str[2] + str[5] - 0x30;
    str[30] = str[0x1f] + str[9] - 0x30;
    str[14] = str[27] + str[28] - 0x61;
    
    for (int i = 0; i < 16; i++) {
        char x = str[0x1f - i];
        str[0x1f - i] = str[i];
        str[i] = x;
    }
    
    for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++) {
        printf("%c", str[i]);
    }
    
    return 0;
}得到flag

pyre:

下载发现是.pyc文件,gpt一下

.pyc文件是Python编译后的字节码文件,通常由Python解释器执行。.pyc文件是经过编译的Python源代码。由于.pyc文件是Python解释器的内部表示形式,因此它们不是直接可读的文本文件。它们是由Python解释器根据源代码生成的二进制文件。

寻找在线工具python反编译 - 在线工具 (tool.lu)

将得到的内容逆向,编写脚本

#include <stdio.h>
#include <string.h>

void reverseXOR(char* code, int length) {
    for (int x = length - 2; x >= 0; x--) {
        code[x] = code[x] ^ code[x + 1];
    }
}

int main() {
    char code[] = { '\x1f', '\x12', '\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13' };
    int length = sizeof(code) / sizeof(code[0]);
    
    reverseXOR(code, length);
    
    char flag[length + 1];
    memset(flag, 0, sizeof(flag));
    
    for (int i = 0; i < length; i++) {
        int num = ((int)code[i] - i + 128) % 128;
        flag[i] = (char)num;
    }
    
    printf("%s\n", flag);
    
    return 0;
}

,得到flag

easyre1:

.par文件扩展名通常用于Parity Archive软件的压缩文件格式。Parity Archive(PAR)是一种冗余数据存储和恢复的技术,用于纠正和修复由于数据损坏或丢失而导致的文件完整性问题。

先解压缩,得到.exe文件,

带upx的壳,脱去后放入ida

ACT{}括号里的值长度为12,v4=byte_402000[输入的数组的每一位值-1]
在ida里可以看到byte_402000数组的值,根据这个算法逆向一下就能得到我们输入的字符串,也就是flag

findit:

查看apk文件使用APKIDA打开

发现了一串16进制数,将求解的16进制数提交不对,观察发现进行了偏移量为10的凯撒加密,逆向写脚本:

#include <stdio.h>
#include <string.h>

void caesarDecrypt(char* encrypted, int offset, char* decrypted) {
    int length = strlen(encrypted);

    for (int i = 0; i < length; i++) {
        char c = encrypted[i];

        if (c >= 'a' && c <= 'z') {
            // 处理小写字母
            c = 'a' + (c - 'a' - offset + 26) % 26;
        } else if (c >= 'A' && c <= 'Z') {
            // 处理大写字母
            c = 'A' + (c - 'A' - offset + 26) % 26;
        }

        decrypted[i] = c;
    }

    decrypted[length] = '\0';
}

int main() {
    char encrypted[] = "m164675262033l4m49lnp7p9mnk28k75";
    int offset = 10;
    char decrypted[sizeof(encrypted)];

    caesarDecrypt(encrypted, offset, decrypted);

    printf("Decrypted: %s\n", decrypted);

    return 0;
}

得到flag

rome1:

解压缩,查壳,

32位无壳,idaf5,func里别有洞天

输入的字符串经过变换后与v12进行比较,相等则输出 You are correct!

v12的值已经知道:Qsw3sj_lz4_Ujw@l,大写和小写分别进行变换,写出脚本

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main()
{
    char v12[]  = "Qsw3sj_lz4_Ujw@l";  //长度为16
    int flag[17] = {0};
    int i;
    for(i = 0 ; i <= 15; i++)
    {
        if(v12[i] <= 90 && v12[i] > 64)  //大写
        {
            flag[i] = v12[i] - 65 + 51;
            while(flag[i] < 65)
            {
                flag[i] += 26;
            }
        }
        else if(v12[i] <= 122 && v12[i] > 96) //小写
        {
            flag[i] = v12[i] - 97 + 79;
            while(flag[i] < 97)
            {
                flag[i] += 26;
            }

        }
        else
        {
            flag[i] = v12[i];
        }
    }
    printf("flag{");
   for(i = 0 ; i < 16 ; i ++)
   {
       printf("%c",flag[i],flag[i]);
   }
  printf("}");
   return 0;

}

rsa:

先了解rsa加密:RSA是一种非对称加密算法,公钥用于加密数据,而私钥用于解密数据

  1. 选择两个不同的质数p和q,并计算它们的乘积n(n = p * q)。
  2. 计算欧拉函数φ(n) = (p - 1) * (q - 1)。
  3. 选择一个加密指数e,满足1 < e < φ(n),且e与φ(n)互质。
  4. 计算解密指数d,使得 (d * e) % φ(n) = 1。
  5. 公钥是(n, e),私钥是(n, d)。
  6. 要加密消息m,使用公钥对m进行模幂运算,得到密文c = m^e mod n。
  7. 要解密密文c,使用私钥对c进行模幂运算,得到原始消息m = c^d mod n。

E=65537 (0x10001)
N=0xC0332C5C64AE47182F6C1C876D42336910545A58F7EEFEFC0BCAAF5AF341CCDD

p= 285960468890451637935629440372639283459
q=304008741604601924494328155975272418463

知道了p和q后我们根据L=lcm(p-1,q-1) (L为p-1、q-1的最小公倍数)就可以算出L,有了L和E可以根据1 < D < L,E*D mod L = 1算出D,有了D和N我们就可以根据明文=密文^D mod N来解密出明文了

写脚本

login:

发现是html文件,直接双击打开

ctrl+U查看源代码

查看特殊字段是是一个简单的凯撒密码(Caesar Cipher)的解密过程。凯撒密码是一种替换密码,通过将字母按照一定的偏移量进行替换来进行加密和解密。

在这段代码中,字符串 flag 是密文,通过替换函数来解密。替换函数使用正则表达式 /[a-zA-Z]/g 匹配所有的字母字符。然后,通过回调函数对每个匹配到的字母进行替换。

具体的转换规则是,将字母的 ASCII 码加上 13,如果超过了字母的范围(大写字母为 65-90,小写字母为 97-122),则减去 26。

最后,将解密后的字符串 rotFlag 与 "PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" 进行比较。如果相等,则表明解密成功。

编写脚本

#include <stdio.h>
#include <string.h>

void decrypt(char* str) {
    int i;
    for (i = 0; i < strlen(str); i++) {
        if (str[i] >= 'A' && str[i] <= 'M') {
            str[i] = str[i] + 13;
        }
        else if (str[i] >= 'a' && str[i] <= 'm') {
            str[i] = str[i] + 13;
        }
        else if (str[i] >= 'N' && str[i] <= 'Z') {
            str[i] = str[i] - 13;
        }
        else if (str[i] >= 'n' && str[i] <= 'z') {
            str[i] = str[i] - 13;
        }
    }
}

int main() {
    char a[] = "PyvragFvqrYbtvafNerRnfl@syner-ba.pbz";
    char flag[100] = "";
    int i;
    
    for (i = 0; i < strlen(a); i++) {
        if (a[i] >= 'A' && a[i] <= 'Z') {
            flag[i] = a[i];
        }
        else if (a[i] >= 'a' && a[i] <= 'z') {
            flag[i] = a[i];
        }
        else {
            flag[i] = a[i];
        }
    }
    
    decrypt(flag);
    
    printf("flag{%s}\n", flag);
    
    return 0;
}

得到flag

level1:

对文件查壳,放入ida

for循环19次,和output.txt里的19个整数相对应,i & 1这里是判断奇偶的意思,即可以理解为i % 2,奇数:右移,偶数:做乘法。编写脚本:

#include <stdio.h>

int key[] = { 198, 232, 816, 200, 1536, 300, 6144, 984, 51200, 570, 92160, 1200, 565248, 756, 1474560, 800, 6291456, 1782, 65536000 };
char flag[20];

void generateFlag() {
    for (int i = 1; i <= 19; i++) {
        if (i & 1) {
            flag[i - 1] = (char)(key[i - 1] >> i);
        } else {
            flag[i - 1] = (char)(key[i - 1] / i);
        }
    }

    flag[19] = '\0';
}

int main() {
    generateFlag();

    printf("%s\n", flag);

    return 0;
}

GUET—CTF2019re:

有upx的壳,脱掉

crackrtf:

32位无壳,

发现需要提交两个password,长度是6个字符,第一个flag使用了hash加密,哈希是很多算法放在一起,然后随机抽一个算法来加密,第二个参数是加密时所用的方法标号。

通过脚本破解得第一串密码123321输入验证正确,查找第二段密码不太会,日后补上

红帽杯easyre:

.elf文件是一种可执行和可链接文件的文件格式,用于存储程序的机器代码和相关信息,以便在操作系统中执行和加载。

64位无壳,ida,发现了base64加密的特征字符串

将密文base64解码后发现是个无用网站,

  • 17
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值