buuresevewp

ACTFeasyre

先查壳,是简单的upx脱壳
然后放入ida分析
在这里插入图片描述
主要找这个函数
在这里插入图片描述
得出:让if语句里面的条件,左边的等于右边即可,那么v4+i是已知的,就剩下右边的_data_start__了,点进去
在这里插入图片描述
看见字符串

b = ‘~}|{zyxwvutsrqponmlkjihgfedcba`_^][ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(’&%$# !"’
还有
a = 42,70,39,34,78,44,34,40,73,63,43,64

看ASCII码,v19 = A,HIBYTEv19 = C,v20 = T,v21 = F,v22 = {,v23 = },那么我猜flag的内容就在v16,17,18,23,24,25里,但是为啥是互相等…
有点明白了:
a中的ascii码是flag内容的ascii码-1的值
所以代码

# 无注释
# 因为你啥都不会,快去学!!!
arr = [42,70,39,34,78,44,34,40,73,63,43,64]
flag = ''
crr = ''
brr = '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$# !"'
for i in arr:
    flag += chr(brr.find(chr(i)) + 1)
print(flag)

rsa

题目提示四位数字密码,那么直接爆破
得到两个文件
在这里插入图片描述
题目是rsa,那就说明pub文件里面有钥匙,010打开在这里插入图片描述
得到公钥,放到网站里去
在这里插入图片描述
得到n,那么用n去求解q和p
在这里插入图片描述

拿出工具求解d
d = 81176168860169991027846870170527607562179635470395365333547868786951080991441
那么写一个Python脚本

# 无注释
# 因为你啥都不会,快去学!!!
import rsa
e = 65537
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
d = 81176168860169991027846870170527607562179635470395365333547868786951080991441
key = rsa.PrivateKey(n, e, d, q, p)
with open('E:/CTF/暴力破解/flag.txt','rb') as flag:
    flag = flag.read()
    print(rsa.decrypt(flag,key))


注意key = 这一行,里面的nepdq的顺序不能有错
得出flag
在这里插入图片描述

[ACTF新生赛2020]rome

看题:
在这里插入图片描述
在这里插入图片描述
显然,v5—v9是actf{,然后v14是},那么内容就在v1234,v10、11、12、13、14里,也可能是我ida版本不行,这里反正咋看咋不对,但不影响写题。
首先有

int b[] = {81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108,0};

从后面看,让v1+i = v15 + i,就是让经过前面两个if之后的a[i]的ascii值等于b[i]的值即可,就是爆破思想,强行从可见字符串里面找到flag。
所以前面两个if直接在脚本里照抄就行。然后字符串长度是16.
就加个在128个字符串中,一个一个赋值,然后进行两个if语句,然后再和b数组进行==判断,最后赋值给flag数组,然后输出
脚本:

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

int main()
{
    char Str[16];
    int b[] = {81,115,119,51,115,106,95,108,122,52,95,85,106,119,64,108,0};
    char flag[16];
    int a[16];
    for(int i = 0;i<16;i++){
            for(int j = 0;j < 128;j++){
            a[i] = j;
        if(a[i]>64 && a[i]<=90){
            a[i] = (a[i] - 51)%26+65;
        }
        if(a[i]>96 && a[i]<=122){
            a[i] = (a[i] - 79)%26+97;
        }

        for(int i = 0;i<16;i++){
              if(a[i] == b[i]){
        Str[i] = j;
        }
        }
            }
    }
for(int i = 0;i<16;i++){
    printf("%c",Str[i]);
}
    return 0;
}

在这里插入图片描述

crackRTF

先查壳,32位无壳
用shift+f12查找字符串找到主函数
在这里插入图片描述

大致一看,这个程序是需要输入两个密码,并且有两个函数对密码由操作
进入第一个函数
在这里插入图片描述
看到了0x8004u,那是标识码,不同的标识码代表不同的加密方式,标识符代表加密方式。
这个是sha1加密
在这里插入图片描述
第二个函数是0x8003u是md5加密
上网查阅资料:

SHA1对任意长度明文的预处理和MD5的过程是一样的,即预处理完后的明文长度是512位的整数倍,但是有一点不同,那就是SHA1的原始报文长度不能超过2的64次方,然后SHA1生成160位的报文摘要。SHA1算法简单而且紧凑,容易在计算机上实现。

所以我就想:直接把加密后需要对比的字符串进行MD5解密不就得到密码了吗
在这里插入图片描述

123321是第一个密码
~!3a@0是第二个密码

程序内输入得到rtf文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
打开得到flag
但实际上做没这么简单,属于是抄近道了
第一个函数是sha1加密,直接python用hashlib包,进行爆破

import hashlib
flag2='@DBApp'
for i in range(100000,999999):
     h2 = hashlib.sha1((str(i)+flag2).encode("utf-8"))
     flags = h2.hexdigest()
     if "6e32d0943418c2c33385bc35a1470250dd8923a9" == flags:
              print (str(i)+flag2)
              print(flags)


第二个是md5加密,但是没有给范围,上一个函数是给了范围,数字大于10000
那就往下看
在这里插入图片描述

FindResourceA:找到模块中的资源,这句话是找到AAA类型的叫0x65的资源
SizeRecource:根据名字也容易知道函数返回的是字节数
LockResource:返回资源地址
LoadResource:意思是装载指定资源到全局存储器。 函数功能:该函数装载指定资源到全局存储器。
CreateFileA:函数创建或打开下列对象,并返回一个可以用来访问这些对象的句柄。
WriteFile:将数据写入一个文件或者I/O设备。
CloseHandle:只是关闭了一个线程句柄对象,表示我不再使用该句柄,即不对这个句柄对应的线程做任何干预了。并没有结束线程。

还有一个sub函数
在这里插入图片描述
还像是要读取“AAA”文件里的数据然后跟我们输入的密码2传入sub函数,然后函数就是异或,那么我们逆过来也是异或,现在就是找“AAA”文件里的数据,然后因为我们输入的是六位密码,不出意外的话,“AAA”文件里的数据也应该是六位,启用Resource Hacker:
在这里插入图片描述
因为我们的数据需要通过WriteFile函数写入到文件里,然后产生rtf文件,那么写入什么会产生文件呢,我猜是文件头,于是打开一个rtf文件,取文件头前六位:{\rtf1
写脚本逆一下:

# 无注释
# 因为你啥都不会,快去学!!!
res=[0x05,0x7D,0x41,0x15,0x26,0x01]
rtft = "{\\rtf1"
flag=""
for i in range(len(res)):
    flag+=chr(res[i]^ord(rtft[i]))
print(flag)

得到密码2:~!3a@0

[FlareOn4]login

下载后得到一个html文件

<!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>

关键:

 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);});

分三个部分吧:

(① ? c : c - 26);
① = ② >= ③
② = (c <= “Z” ? 90 : 122)
③ = (c = c.charCodeAt(0) + 13)
第一种:小于等于90且+13依旧,返回本身+13
第二种:小于等于90且+13大于90,本身-13
第三种:大于90且+13小于等于122,返回本身+13
第四种:大于90且+13大于122,本身-13
写出代码:

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

int main()
{
    char flag[37];
     char a[37] = "PyvragFvqrYbtvafNerRnfl@syner-ba.pbz";
    for(int i = 0 ; i<37 ;i++){
        if(a[i]<=90 && (a[i]+13)<=90 && a[i] >= 65){
            flag[i] = a[i]+13;
        }
        else if(a[i]<=90 && (a[i]+13)>90 && a[i] >= 65){
            flag[i] = a[i] - 13;
        }
        else if(a[i]>90 && (a[i]+13)<=122){
            flag[i] = a[i]+13;
        }
        else if(a[i]>90 && (a[i]+13)>122){
            flag[i] = a[i]-13;
        }
        else flag[i] = a[i];
    }
    printf("flag{%s}",flag);
    return 0;
}

在这里插入图片描述

原本我写的前两个条件语句不含>=65,结果我发现出来的@什么的符号都被改变了,看了看别人的wp发现他们都控制了最小ascii值得范围就是大于等于65,虽然对答案没有影响因为给了规范答案,但是还是不严谨,最后给加上了条件,我感觉就是没有闭区间才导致的不完整
然后我发现这道题跟rot13一样:
在这里插入图片描述
在这里插入图片描述

[2019红帽杯]easyRE

这一题对我来说很难,还是看很多大佬的wp才写出来的,还需要加油
拖入ida,shift+f12查看字符串,找到函数
在这里插入图片描述
出现continue,说明有阶段性的解密,那就先解出上面的加密,发现就是个异或,脚本:

   char flag[36];
    char a[36] = {73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67};
    for(int i=0;i<36;i++){
        flag[i] = a[i] ^ i;
    }
    printf("%s",flag);

结果:
在这里插入图片描述
说明flag的前四位是flag。。。。。
接下去看
在这里插入图片描述
sub_400e44是典型的base64加密,调用了10次的base64加密,然后比较,那就解十次
在这里插入图片描述
在这里插入图片描述
发现是个网站,进去有一部分是想方设法坑解题人的,好吧。
那问题来了,到底关键函数在哪里?
在这里插入图片描述
在这里能看到,还有个函数,点进去
在这里插入图片描述
102是f,103是g,这里有在判断fg,感觉flag就住在这里
分两个部分:

①利用byte_6CC0A0的前三位和byte_6CC0A3 的前一位,去和“flag”进行四次循环异或,作为下一个部分的条件,
②将全部25位与①的结果进行25次循环异或,不过①的序号需要%4

代码

char flag1[25];
    char d[4];
    char c[4] = {'f','l','a','g'};
    char e[4] = {0x40,0x35,0x20,0x56};
    char b[25] = {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};
    for(int i=0;i<4;i++){
        d[i] = c[i] ^ e[i];
    }
    for(int i = 0;i<25;i++){
        flag1[i] = b[i] ^ d[i%4];
    }
    printf("%s",flag1);

在这里插入图片描述

在这里插入图片描述
这一步吧,我觉得对我来说疑点很大,就是判断出,v3是四位数组,且跟另一个数组异或后是“flag”,这个我感觉很关键,从而找出了v3
对这道题的部分代码做个解释:
在这里插入图片描述
sub_4406E0:写入数据给v53
LODWORD(v1) = sub_424BA0((const __m128i *)v51):将v53长度给v1
在这里插入图片描述
memset(&v54, 0, 0x40uLL):V54的值设置为零,memset通常是C/C++初始化函数,作用是将一块内存中的内容全部设置为指定的值,这个函数通常为新申请的内存做初始化工作
在这里插入图片描述
HIBYTE()函数的作用是获取高字节也就是数组的最后一位,同时还有BYTE()、BYTE1()、BYTE2()第一个是获取数组的第一位,第二个就是获取第二位,依次类推。
在这里插入图片描述
这一段数据的话,是关键,但是要怎么发现呢?
出题人不会无缘无故给数据,就找找看,看看引用:
在这里插入图片描述
这段数据被函数sub_400D35给用了而且函数的头头是fini段
fini段的解释:

此节区包含了可执行的指令,是进程终止代码的一部分。程序正常退出时,系统将安排执行这里的代码。

所以就很关键

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值