[长安“战疫”网络安全卫士守护赛]combat_slogan

[RE] combat_slogan

flag{We_w11l_f1ght_t0_end_t0_end_cazy}

本题目很简单。按照惯例看到是jar文件,因此拖入jd-gui进行反编译
image

一般而言我们都直接看非公有部分,这也是大部分逆向的基本思路。看到Main.class的第50行,此处可能是一个flag,但是经过测试这是个迷惑选项。观察下面的第二个条件,此处要求str5和后面的字符串相匹配,因此返回查看str5的引用。事实上,对可疑变量进行跟踪观察也是常见的思路之一。

 public static void main(String[] args) {
    //...
    str2 = scan.nextLine();
    //...
    String stringTransformAscii = stringTransformAscii(str2);
    String[] offerCodeString = stringTransformAscii.split(",");
    //...
    for (String s : offerCodeString) {
      str5.append(s);
    //...
    if ((flag == 0) && (str5.toString().compareTo//...
    //...

截取的代码中可见首先从控制台获取用户输入存入str2,然后经过函数stringTransformAscii处理之后再生成数字字典

public static String stringTransformAscii(String value)
  {
    StringBuffer sbu = new StringBuffer();
    char[] chars = value.toCharArray();
    for (int i = 0; i < chars.length; i++) {
      if (i != chars.length - 1)
        sbu.append(chars[i]).append(",");
      else {
        sbu.append(chars[i]);
      }
    }
    return sbu.toString();
  }

此处可以看到这段代码仅仅只是将输入的字符串更换成了对应的ascii数字并且将其再转换为字符串返回,再经过去逗号拼接转换为无符号字符串。这样的话就很简单了。查看双重条件中的第二条件:

str5.toString().compareTo("871019511949491089510249103104116951164895101110100951164895101110100959997122121")

对关键字符串按照范围(23位,65150)进行分组,生成一个数组输出即flag

#include <iostream>

int main(int argc, char** argv)
{
    //if ((flag == 0) && (str5.toString().compareTo("871019511949491089510249103104116951164895101110100951164895101110100959997122121") == 0))
    char flag[] = { 87,101,95,119,49,49,108,95,102,49,103,104,116,95,116,48,95,101,110,100,95,116,
        48,95,101,110,100,95,99,97,122,121 };
    printf("\nflag = %s", flag);
}

有人问ttk是什么,由于str2str5都是来源于一个相同的用户输入,因此相当于给定了一个条件却要满足两个判断,对于逆向而言,只需要选取其中任意一个判断条件进行攻破即可。ttk函数其实是字符串替换加密,比较简单,留给有能力的读者进行练习(逃

posted @ 2022-01-08 21:06  二氢茉莉酮酸甲酯  阅读(47)  评论(0编辑  收藏  举报