吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2820|回复: 12
收起左侧

[CTF] 【2023春节】菜鸟记录的第一次解题过程与感受

[复制链接]
jackyyue_cn 发表于 2023-2-6 15:25
【前言】
其实一直在关注52pojie 大概零几年注册id学习了一会crackme就停了
去年重新上线 作为新手也是第一次知道还有这个活动 大概是初八在公众号刷到,看着满满的CB 忍不住要来试一下
下面是我个人对于解题过程的记录,可以看出有许多不熟悉的地方,供大家避坑~
请大家一定要多看几位大神的解题帖子,跟着他们的思路走,以达到事半功倍的效果。

【正文】
一、首先是Windows初级题。
先运行了一下,提示长度错误。然后就一个一个长度试,得到29个字符换成提示“Wong,please try again."

启动x32dbg,载入程序进行调试
点击字符串工具,找到几个提示信息下断点
02-step1.jpg
再次运行,可以看到有个比较,确认是长度29
02-step2.jpg
继续往下会断在Wrong那里。往上翻了一会儿,看到一个“Success”,并且上面有个cmp的比较
下断电跟踪几次 发现bl里依次是 f、l、a、g等字符,前面是我输入的字符 确认是和正确答案的字符串比较
02-step3.jpg
突然想到能不能直接把答案输出来 于是在cmp上按空格汇编,改成mov
同时把下面的jne全部改成nop不跳转
02-step5.jpg
02-step6.jpg
02-step7.jpg
然后右键edx,在内存中显示
02-step4.jpg
接下来就是取消cmp处的断点,F9运行,可以看到内存中直接出现了flag
程序也输出了Success
02-step8.jpg

二、Windows中级题(未解出)
又试了一下中级题,用x64dbg打开不能调试 先用老工具peid查没查到 换用DIE查到是UPX+modified
于是上论坛找类似crackme的解法,学习了RSP大法、scylla大法和固定ASLR大法,终于得到一个可以运行的去壳程序
然而进x64dbg还是闪退(没有其它插件) 一番折腾后 改用附加方式进行调试
断GetDlgItemTextW,找到获取uid和key的代码,又上IDA分析
无奈加密过程有点复杂 放弃
【感想】由此题学到更多脱壳和64位程序的分析思路

三、Android初级题1、2
特意看了几篇题目给的教程(时间紧没全部看完)
一边搭建模拟器环境 找出以前的AndroidKiller
第1题直接暴力连点器。。没怎么分析
第2题用killer解包,分析代码,发现有个校验签名的函数,修改代码后重新打包,发现点击的按钮没有了
折腾了一阵还是没有结果
又找到教程中的jadx工具解出代码
分析后终于发现了加密算法代码,于是又从论坛上学到一个在线java调试的方法
将原来的代码进行了一些修改(对java不熟悉 可能有不对的地方 但是结果对了)  弄上去运行算出key
[Java] 纯文本查看 复制代码
import java.util.Base64;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/* Online Java Compiler and Editor */
class C0838B {
    public static String encode(String str) {
        int length = str.length();
        char[] cArr = new char[length];
        int i = length - 1;
        while (i >= 0) {
            int i2 = i - 1;
            cArr[i] = (char) (str.charAt(i) ^ '5');
            if (i2 < 0) {
                break;
            }
            i = i2 - 1;
            cArr[i2] = (char) (str.charAt(i2) ^ '2');
        }
        return new String(cArr);
    }
}

final class C0839C {
    public static final C0839C INSTANCE = new C0839C();

    private C0839C() {
    }

    private final char cipher(char c, int i) {
        char c2 = Character.isUpperCase(c) ? 'A' : 'a';
        return (char) (((char) (((((char) (c - c2)) + (i % 26)) + 26) % 26)) + c2);
    }

    public final String cipher(String str, int i) {

        StringBuilder sb = new StringBuilder();
        int length = str.length();
        for (int i2 = 0; i2 < length; i2++) {
            if ( ((int) str.charAt(i2) >= 65)  && ( (int)str.charAt(i2)<= 90)) {
                sb.append(cipher(str.charAt(i2), i));
            } else if ( ((int)str.charAt(i2) < 97) || ((int)str.charAt(i2) > 122) ) {
                sb.append(str.charAt(i2));
            } else {
                sb.append(cipher(str.charAt(i2), i));
            }
        }
        String sb2 = sb.toString();

        return sb2;
    }
}
final class Base64Utils {
    public static final Base64Utils INSTANCE = new Base64Utils();
    final Base64.Decoder decoder = Base64.getDecoder();
    final Base64.Encoder encoder = Base64.getEncoder();
    private Base64Utils() {
    }

    public final byte[] encodeToBytes(byte[] bArr) {
        byte[] encode = encoder.encode(bArr);
        
        return encode;
    }

    public final String encodeToString(byte[] bArr) {
        String encodeToString = encoder.encodeToString(bArr);
       
        return encodeToString;
    }

    public final byte[] decode(byte[] bArr) {
        byte[] decode = decoder.decode(bArr);
        
        return decode;
    }

    public final byte[] decode(String str) {
        byte[] decode = decoder.decode(str);
        
        return decode;
    }
}

final class MD5Utils {
    public static final MD5Utils INSTANCE = new MD5Utils();

    private MD5Utils() {
    }

    public final String MD5(String sourceStr) {
        
        try {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] bytes = sourceStr.getBytes();
            messageDigest.update(bytes);
            byte[] digest = messageDigest.digest();
            
            StringBuffer stringBuffer = new StringBuffer("");
            int length = digest.length;
            for (int i = 0; i < length; i++) {
                int i2 = digest[i];
                if (i2 < 0) {
                    i2 += 256;
                }
                if (i2 < 16) {
                    stringBuffer.append("0");
                }
                stringBuffer.append(Integer.toHexString(i2));
            }
            String stringBuffer2 = stringBuffer.toString();
            
            return stringBuffer2;
        } catch (Exception e) {
            System.out.println(e);
            return "";
        }
    }
}

public class Test
{
    public static void main(String[] args)
    {
        String str = "11111";
        String str1;
        String str2 = "flag{123}";
        String str3;

        if ( 1==1 ){

            C0839C c0839c = C0839C.INSTANCE;
            MD5Utils mD5Utils = MD5Utils.INSTANCE;
            Base64Utils base64Utils = Base64Utils.INSTANCE;
            String encode = C0838B.encode(str + "Wuaipojie2023");
            System.out.println("encode:"+encode);
            byte[] bytes = encode.getBytes();
            str1 = base64Utils.encodeToString(bytes);
            System.out.println("B64:"+str1);
            str3 = c0839c.cipher(mD5Utils.MD5(str1), 5);
            
            System.out.println("final:"+str3);

        }
    }
}

【感受】学习到了新的工具jadx使用,新的java代码在线调试方法

四、Android中级题(未解出)
先是运行后要求大声喊 然而声音最高到90dB
jadx看代码需要到100dB
又学习了一会儿教程 搭建起frida环境,使用hook方法修改volume为直接返回100
运行显示快去找flag
再次分析代码,发现write_img代码,写了一个aes.png文件
到app目录中找到文件打开,似乎是一串b64加密的数据,直接b64解密后是乱码,不是png数据
又查看代码,发现有从52pj.so中引入decrypt、encrypt和get_RealKey三个函数

并找到一个可疑的16位字符串,尝试用hook代码进行解密,数据仍然不对,放弃
【感受】学习到frida工具的使用及hook代码的编写,了解了AES加密的知识

五、Web题
这道题是我觉得很有趣的题目,涉及的知识和方法很广泛
1、首先按键音能听出来是6个数字,利用百度DTMF频率,再用goldwave频谱中的Waterfall图,
将频率调整到600-1500Hz之间 根据每个音的高低频率解出数字,得到flag6
*但这里我却完美地错过了flag8,因为flag8的频率在4kHz-8kHz之间,导致我的图上没显示出来
2、第二个是直接显示在视频上的flag1
3、第三个解出来的是摩斯密码flag5,这个谍战剧看多了都比较熟
4、第四个解出来的是二维码,找个在线识别工具可识别flag2
5、第五个解出来的是视频右下角的水印,iodj3经过分析发现就是flag3
6、第六个解出来的是flag7,就是上面那串01100110...(先是反复数0101 后来发现在隐藏网页中有代码,不用数)
7、第七个解出来的是最后那段语音,听着怪怪的像倒放 用goldwave反向一下,能听到flag9
到这里我基本上没什么头绪了,但是又多看了几遍视频,发现了线索
8、第八个解出来的是flag11,看下面一堆++++号 百度一下发现疑似是一种brainf**k的加密方式 找个在线工具解出来了
静态中只找到这八个了,剩下的4、8、10、12没找到
9、然后是动态码
根据提示,将视频显示的网站用hosts解析到IP上,成功进入网站,发现登录后无权限
搜索cookie发现jwt_token,百度学习一番,来到jwt.io解密发现"role":"user"字样,将user改为admin后改掉cookie,拿到flagC
接下来分析源代码、HTTP头等各种信息,突然发现在一个响应头中有flagA字样,不过后面提示header中没有uid信息
用python的urllib构造一个header带uid信息的请求过去,拿到flagA
反复研究源码 看到提示“从DNS中找到一些信息” 于是学习了一下DNS解析的知识

使用nslookup -qt=txt 2023challenge.52pojie.cn 4.4.4.4找到提示
[Shell] 纯文本查看 复制代码
非权威应答:
2023challenge.52pojie.cn        text =
""_52pojie_2023_happy_new_year=flagB{substr(md5(uid+\"_happy_new_year_\"+floor(timestamp/600)),0,8)}""

使用python编辑代码并运行,得到flagB
[Python] 纯文本查看 复制代码
import hashlib, time, math
hashlib.md5(('1581363_happy_new_year_'+str(math.floor(time.time()/600))).encode('utf8')).hexdigest()[0:8]

由于每个难度的flag都不够,最后只有在难度下调后才提交成功
【感受】通过Web题,了解了更多的信息加密和传递方式,认识了Web中使用的一些信息传递和验证技术。

总的说来,参与此次活动总体是快乐的,过程是紧张的,学习是充实的,感谢论坛和各位的付出。
祝大家2023新年大吉!

免费评分

参与人数 5威望 +1 吾爱币 +24 热心值 +4 收起 理由
turbodog + 1 用心讨论,共获提升!
yyb414 + 1 + 1 热心回复!
yjn866y + 1 + 1 谢谢@Thanks!
Sp1ral + 1 + 1 我很赞同!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

darksied 发表于 2023-2-6 15:51
咱们一样,中级题目基本没折腾出来
liujitao911 发表于 2023-2-6 16:11
侃遍天下无二人 发表于 2023-2-6 16:11
按我的步骤试试看能不能解出来,正好帮我验证下记录的是否足够清楚
mkami 发表于 2023-2-6 16:33
仍然是一脸蒙懵逼
m066061 发表于 2023-2-6 17:17
只能点赞大佬了
skyward 发表于 2023-2-6 17:59
都好厉害啊
Hmily 发表于 2023-2-6 18:03
哈哈,大家玩的开心,学到知识这个活动就值得。
Sp1ral 发表于 2023-2-6 18:37
可以感觉很好
受伤的小猪 发表于 2023-2-6 20:58
膜拜大神啊
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 23:43

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表