AltRick 发表于 2024-2-29 17:16

2024春节解题红包思路分享

本帖最后由 AltRick 于 2024-2-29 21:08 编辑

前言一年一度的春节解题活动已经结束,许多大佬已经分享了许多解题思路,很多思路还是有很多相似的地方;前几年都参加了活动的部分题目的解答,今年有时间都尝试了所有题目的分析,特把部分分析过程分享给大家,分析过程不需要太高级知识,会简单调试即可。
涉及工具主要有:Exeinfo-查壳,OD-32位调试,x64dbg-64位调试,IDA-查看伪C,MT管理器-修改App

解题二-Windows 初级题运行Exeinfo查壳,C++32位程序,直接拖入OD,程序自动加载运行至入口

多年经验初级题一般比较简单,直接右键搜索ASCII,发现如下字符串,里面包含sucess相关内容,双击跳转

往上查看,发现有个比较命令,猜测输入flag长度和0x25有关,也就是37

F2设定断点运行,随便输入长度为37的数据,结果走到了error,重新运行,输入大于37数据,进入断点后按F8继续

走到这里时,堆栈出现一段字符串,猜测为flag,重新运行输入,提示成功,找到对应flag。
此flag与最开始解答的有区别,查看说明原来调试的是修改版,不是最开始版本。该题本身还是比较简单的,至于说用IDA查看代码分析,感兴趣的可以查看其他分享帖学习。

解题三-Android 初级题
安装App运行,抓小猫,简单玩了一下,没围成功。

直接MT打开查看,之前论坛有抓猫游戏,是网页版调用js,猜测该App也是。查看assets文件夹,发现有个js文件,打开查看找到下面内容
set: function(t)
    {
      switch (t)
      {
            case i.PLAYING:
                break;
            case i.LOSE:
                this.setStatusText(p.default("汗流浃背了吧,老弟!"));
                // 新增
                AndroidInterface.onSolverReturnValue(-1);
                break;
            case i.WIN:
                AndroidInterface.onSolverReturnValue(-1);
                break;
            default:
                return
      }
      this.data.set("state", t)
    }失败时提示“汗流浃背了吧,老弟!”,下面一行是成功,直接将WIN内容复制到上方,重新运行,失败后运行播放视频,结束显示正确flag。
再次用MT打开assets文件夹,发现里面有个视频,猜测flag与视频有关,反编译dex查看代码可知,flag藏在了视频文件结尾。相关代码详细分析和其他解决思路可查看其他分享帖。

解题四-Android 初级题
运行,抽奖游戏,试抽一下,没成功,提示需要生成纠缠之缘才能抽。

打开MT查看dex,找到主运行Activity,结合界面第一次显示的10个纠缠之缘,找到smail中10的值0x0a,改为较大值,比如0xffff

重新安装运行,连抽多次,出现flag,但是乱码,猜测有签名验证,MT去签后重新运行,出现正确flag。分析逻辑还可以通过修改时间,让生成速率变快。其他代码分析及思路参考其他分享帖。

解题五-Android 中级题

玄天帝题,运行没有什么提示,直接MT查看,发现包中存在lib文件,再查看代码,发现了native方法,猜测可能和so文件相关,随便拷贝一个文件,用IDA打开,JNI_OnLoad及导出函数可直接看到,F5查看代码,分析方法基本都是用来检测frida的,反正我不会,直接dex中删除加载so文件及方法定义,保存编译,为避免出现读取签名异常,修改前先用MT去除签名校验。
bool sSS()
{
_BOOL8 result; // x0

result = detect_frida();
if ( result )
    _exit(0);
return result;
}接着查看代码进行分析,程序有个checkpassword方法,大概率是得到flag关键,该方法会加载assets中classes.dex到程序内部路径,并通过反射调用相应C类中的isValidate方法,那就使用MT的注入文件提供器功能查看(若已root可直接查看),编译重新安装,然后添加本地存储,查看内部文件,最终也找到生成的1.dex;由于外部会调用1.dex里的isValidate方法,则再次分析该方法
public static String isValidate(Context context, String str, int[] iArr) throws Exception {
      try {
            return (String) getStaticMethod(context, iArr, "com.zj.wuaipojie2024_2.A", "d", Context.class, String.class).invoke(null, context, str);
      } catch (Exception e) {
            Log.e(TAG, "咦,似乎是坏掉的dex呢!");
            e.printStackTrace();
            return "";
      }
    }查看方法引用,首先会获取一个decode.dex文件,根据传入值修复生成2.dex,然后调用里面的d方法,删除掉生成的文件,转化过程进行了字节文件的处理。此时查看文件并未找到decode.dex,由于assets中只存在一个classes.dex文件,猜测和该文件相关,将该文件改名放入相应路径,为避免程序删除生成的2.dex,将相关删除文件代码屏蔽并重新编译安装,此时通过构造的本地存储发现了生成的2.dex,将该dex与1.dex比较,发现方法A.d内容不一样,猜测应该是相关方法对类进行了修复。
public static String d(Context context, String str) {
      MainActivity.sSS(str);
      String signInfo = Utils.getSignInfo(context);
      if (signInfo == null || !signInfo.equals("fe4f4cec5de8e8cf2fca60a4e61f67bcd3036117")) {
            return "";
      }
      StringBuffer stringBuffer = new StringBuffer();
      int i = 0;
      while (stringBuffer.length() < 9 && i < 40) {
            int i2 = i + 1;
            String substring = "0485312670fb07047ebd2f19b91e1c5f".substring(i, i2);
            if (!stringBuffer.toString().contains(substring)) {
                stringBuffer.append(substring);
            }
            i = i2;
      }
      return !str.equals(stringBuffer.toString().toUpperCase()) ? "" : "唉!哪有什么亿载沉睡的玄天帝,不过是一位被诅咒束缚的旧日之尊,在灯枯之际挣扎的南柯一梦罢了。有缘人,这份机缘就赠予你了。坐标在B.d";
    }查看该方法调用了so中的sSS方法,接着从一段字符串中截取输出内容,分析可得是取前9位,猜测为解锁密码。走到这并没有发现flag。
在返回的说明中有一句“坐标在B.d”,在查看checkpassword方法时,其中调用了资源文件获取了一个A_offset数组,而资源文件中还存在一个B_offset数组,且1.dex中A/B类中都存在一个d方法,里面输出都是空字符串,前一步A中d修复后是存在实际逻辑的。那么结合坐标B.d,是否传入B_offset,即可获取方法呢?直接修改验证。
<?xml version='1.0' encoding='utf-8' ?>
<resources>
    <integer-array name="A_offset">
      <item>0</item>
      <item>3</item>
      <item>7908</item>
    </integer-array>
    <integer-array name="B_offset">
      <item>1</item>
      <item>1</item>
      <item>8108</item>
    </integer-array>
</resources>public class B {
    public static String d(String str) {
      return "?" + str + "?";
    }
}修改运行后,打开2.dex获取到修复后的方法
public class B {
    public static String d(String str) {
      return "机缘是{" + Utils.md5(Utils.getSha1("password+你的uid".getBytes())) + "}";
    }
}可知该方法即为flag关键,查看引用,只调用了Utils类中内容,将类B和Utils提取出来与classes.dex合并,在checkpassword方法中调用B.d方法,将密码048531267与uid输入修改到B.d方法中,运行即可得到flag。
public boolean checkPassword(String str) {
      this.tvText.setText(B.d(str));
      this.myunlock.setVisibility(8);
      return true;
    }Smail
method public checkPassword(Ljava/lang/String;)Z
    .registers 11
    const/4 v0, 0x1
    invoke-static {p1}, Lcom/zj/wuaipojie2024_2/B;->d(Ljava/lang/String;)Ljava/lang/String;
    move-result-object p1
    .line 74
    iget-object v1, p0, Lcom/zj/wuaipojie2024_2/MainActivity;->tvText:Landroid/widget/TextView;
    invoke-virtual {v1, p1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
    .line 75
    iget-object p1, p0, Lcom/zj/wuaipojie2024_2/MainActivity;->myunlock:Lcom/example/gesturelock/GestureUnlock;
    const/16 v1, 0x8
    invoke-virtual {p1, v1}, Lcom/example/gesturelock/GestureUnlock;->setVisibility(I)V
    return v0
.end method

解题六-Windows 高级题
程序有两个,一个客户端,一个服务端,两者之间应该是进行了通信交互,最终获取的flag,尝试解一下该题。
查壳,客户端upx64位程序

服务端数据段,themida加密32位程序

用x64dbg打开运行crackme2024.exe,到入口后,直接F9运行,右键搜索当前模块的字符串

选择"   Enter your uid: "进入,查看上下逻辑,需要注册服务端,参照提示cmd输入命令注册,继续运行,程序运行起来抛出异常

切到线程窗口,选择运行的非主线程,右键挂起线程,不让它执行

设置断点,随便输入UID和Serial,暂停分析输入,可知序列号长度是35,然后判断服务端是否运行,并校验数据,然后不知道怎么处理了。
查看服务端,尝试脱壳,之前在论坛发布的虚拟机2.0中使用ARImpRec.dll脱壳成功过一个软件,尝试了一下,走到esto进行不下去了,也放弃了。

解题七-Android 高级题
用MT直接查看代码,分析最终调用so中checkSn方法,用IDA打开该so,查看根本找不到该方法,全部混淆成O0OO.2这种,网上查了一下好像是ollvm混淆,看网上说还要搭环境,没弄过,直接放弃。


解题九-Web 题
第一次尝试解web题,开始看视频都不知道干啥,基于编程人思想,变化的肯定有问题,然后发现了flag1和3,还合成了二维码,扫码发现了其他flag获取入口。最终找到了一半flag。结合其他分享帖,自己又把其他flag验证了一遍。
解题思路与其他分享帖差不多,此处不再赘述,可参考其他帖学习,主要分享一下flag8与flagB的计算,根据v50提示溢出,然后输入很大的值,找到数据存储类型为有符号64位整数,范围是-2^63-1~2^63,那么单价*购买数量溢出后的值大于等于0并且小于拥有金币数量即可购买成功。编写一个循环,判断溢出多次后的负到正的分界处的值,可以找到所需最少金币的购买数量。
decimal mod = ulong.MaxValue;
            long price = 999063388;// 单价

            // 遍历循环,截止的次数为价格的一半
            for (int i = 1; i < (price / 2) + 1; i++)
            {
                long a1 = (long)(mod * i / price);
                long a2 = (long)(mod * i % price);
                // 当遍历结束时,价格被整除,余数为0
                if (a1 < 0 && a2 == 0)
                {
                  break;
                }
                // 计算分界处溢出后价格
                for (long j = a1; j <= a1 + 1; j++)
                {
                  long newPrice = j * price;
                  // 此处判断溢出>0 并且金币在0-50以内,可找到最小的价格对应的数量,甚至可以0元购
                  if (newPrice >= 0 && newPrice < 50)最多金币数
                  {
                        Console.WriteLine("溢出次数:" + i.ToString() + " 数量:" + j.ToString() +" 所需价格:" + newPrice.ToString());
                  }
                }
            }输入不同的价格可获取所需数量及所需价格
所需最少金币数:
100金币:溢出次数:25 数量:4611686018427387904 金币:0
50金币:溢出次数:3 数量:1106804644422573097 金币:2
10000金币:溢出次数:625 数量:1152921504606846976 金币:0
999063388金币:溢出次数:249765847 数量:4611686018427387904 金币:0

最多50金币完整数据列表
100金币:
溢出次数:4 数量:737869762948382065 所需价格:36
溢出次数:5 数量:922337203685477581 所需价格:20
溢出次数:6 数量:1106804644422573097 所需价格:4
溢出次数:10 数量:1844674407370955162 所需价格:40
溢出次数:11 数量:2029141848108050678 所需价格:24
溢出次数:12 数量:2213609288845146194 所需价格:8
溢出次数:16 数量:2951479051793528259 所需价格:44
溢出次数:17 数量:3135946492530623775 所需价格:28
溢出次数:18 数量:3320413933267719291 所需价格:12
溢出次数:22 数量:4058283696216101356 所需价格:48
溢出次数:23 数量:4242751136953196872 所需价格:32
溢出次数:24 数量:4427218577690292388 所需价格:16
溢出次数:25 数量:4611686018427387904 所需价格:0
溢出次数:29 数量:5349555781375769969 所需价格:36
溢出次数:30 数量:5534023222112865485 所需价格:20
溢出次数:31 数量:5718490662849961001 所需价格:4
溢出次数:35 数量:6456360425798343066 所需价格:40
溢出次数:36 数量:6640827866535438582 所需价格:24
溢出次数:37 数量:6825295307272534098 所需价格:8
溢出次数:41 数量:7563165070220916163 所需价格:44
溢出次数:42 数量:7747632510958011679 所需价格:28
溢出次数:43 数量:7932099951695107195 所需价格:12
溢出次数:47 数量:8669969714643489260 所需价格:48
溢出次数:48 数量:8854437155380584776 所需价格:32
溢出次数:49 数量:9038904596117680292 所需价格:16
50金币:
溢出次数:1 数量:368934881474191033 所需价格:34
溢出次数:2 数量:737869762948382065 所需价格:18
溢出次数:3 数量:1106804644422573097 所需价格:2
溢出次数:4 数量:1475739525896764130 所需价格:36
溢出次数:5 数量:1844674407370955162 所需价格:20
溢出次数:6 数量:2213609288845146194 所需价格:4
溢出次数:7 数量:2582544170319337227 所需价格:38
溢出次数:8 数量:2951479051793528259 所需价格:22
溢出次数:9 数量:3320413933267719291 所需价格:6
溢出次数:10 数量:3689348814741910324 所需价格:40
溢出次数:11 数量:4058283696216101356 所需价格:24
溢出次数:12 数量:4427218577690292388 所需价格:8
溢出次数:14 数量:5165088340638674453 所需价格:26
溢出次数:15 数量:5534023222112865485 所需价格:10
溢出次数:17 数量:6271892985061247550 所需价格:28
溢出次数:18 数量:6640827866535438582 所需价格:12
溢出次数:20 数量:7378697629483820647 所需价格:30
溢出次数:21 数量:7747632510958011679 所需价格:14
溢出次数:24 数量:8854437155380584776 所需价格:16
10000金币:
溢出次数:99 数量:182622766329724561 所需价格:16
溢出次数:198 数量:365245532659449122 所需价格:32
溢出次数:297 数量:547868298989173683 所需价格:48
溢出次数:625 数量:1152921504606846976 所需价格:0
溢出次数:724 数量:1335544270936571537 所需价格:16
溢出次数:823 数量:1518167037266296098 所需价格:32
溢出次数:922 数量:1700789803596020659 所需价格:48
溢出次数:1250 数量:2305843009213693952 所需价格:0
溢出次数:1349 数量:2488465775543418513 所需价格:16
溢出次数:1448 数量:2671088541873143074 所需价格:32
溢出次数:1547 数量:2853711308202867635 所需价格:48
溢出次数:1875 数量:3458764513820540928 所需价格:0
溢出次数:1974 数量:3641387280150265489 所需价格:16
溢出次数:2073 数量:3824010046479990050 所需价格:32
溢出次数:2172 数量:4006632812809714611 所需价格:48
溢出次数:2500 数量:4611686018427387904 所需价格:0
溢出次数:2599 数量:4794308784757112465 所需价格:16
溢出次数:2698 数量:4976931551086837026 所需价格:32
溢出次数:2797 数量:5159554317416561587 所需价格:48
溢出次数:3125 数量:5764607523034234880 所需价格:0
溢出次数:3224 数量:5947230289363959441 所需价格:16
溢出次数:3323 数量:6129853055693684002 所需价格:32
溢出次数:3422 数量:6312475822023408563 所需价格:48
溢出次数:3750 数量:6917529027641081856 所需价格:0
溢出次数:3849 数量:7100151793970806417 所需价格:16
溢出次数:3948 数量:7282774560300530978 所需价格:32
溢出次数:4047 数量:7465397326630255539 所需价格:48
溢出次数:4375 数量:8070450532247928832 所需价格:0
溢出次数:4474 数量:8253073298577653393 所需价格:16
溢出次数:4573 数量:8435696064907377954 所需价格:32
溢出次数:4672 数量:8618318831237102515 所需价格:48
999063388金币:
溢出次数:1 数量:18464037713 所需价格:28
溢出次数:35680836 数量:658812301535368067 所需价格:20
溢出次数:35680837 数量:658812319999405780 所需价格:48
溢出次数:71361671 数量:1317624584606698421 所需价格:12
溢出次数:71361672 数量:1317624603070736134 所需价格:40
溢出次数:107042506 数量:1976436867678028775 所需价格:4
溢出次数:107042507 数量:1976436886142066488 所需价格:32
溢出次数:142723342 数量:2635249169213396842 所需价格:24
溢出次数:178404177 数量:3294061452284727196 所需价格:16
溢出次数:178404178 数量:3294061470748764909 所需价格:44
溢出次数:214085012 数量:3952873735356057550 所需价格:8
溢出次数:214085013 数量:3952873753820095263 所需价格:36
溢出次数:249765847 数量:4611686018427387904 所需价格:0
溢出次数:249765848 数量:4611686036891425617 所需价格:28
溢出次数:285446683 数量:5270498319962755971 所需价格:20
溢出次数:285446684 数量:5270498338426793684 所需价格:48
溢出次数:321127518 数量:5929310603034086325 所需价格:12
溢出次数:321127519 数量:5929310621498124038 所需价格:40
溢出次数:356808353 数量:6588122886105416679 所需价格:4
溢出次数:356808354 数量:6588122904569454392 所需价格:32
溢出次数:392489189 数量:7246935187640784746 所需价格:24
溢出次数:428170024 数量:7905747470712115100 所需价格:16
溢出次数:428170025 数量:7905747489176152813 所需价格:44
溢出次数:463850859 数量:8564559753783445454 所需价格:8
溢出次数:463850860 数量:8564559772247483167 所需价格:36

完结

wangjinhao123 发表于 2024-2-29 18:21

强学习了

执念i_ 发表于 2024-2-29 18:59

厉害的,{:1_921:}

nannan5411 发表于 2024-2-29 20:07

服了,我大受震撼啊

guhuishou 发表于 2024-2-29 20:17

学习了,争取复现,先熟练使用工具

Xczb 发表于 2024-2-29 20:17

{:1_911:}很强,但我不懂

bobxie 发表于 2024-2-29 20:30

厉害&#128077;&#127995;厉害&#128077;&#127995;大牛就是不一样

adm471808 发表于 2024-2-29 20:35

厉害,大佬。学习学习

starh 发表于 2024-2-29 20:40

学习学习

gaoluoluo 发表于 2024-2-29 21:20

大佬,牛!膜拜
页: [1] 2 3 4 5 6
查看完整版本: 2024春节解题红包思路分享