[长安“战疫”网络安全卫士守护赛]combat_slogan
[RE] combat_slogan
flag{We_w11l_f1ght_t0_end_t0_end_cazy}
本题目很简单。按照惯例看到是jar
文件,因此拖入jd-gui
进行反编译
一般而言我们都直接看非公有部分,这也是大部分逆向的基本思路。看到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
是什么,由于str2
和str5
都是来源于一个相同的用户输入,因此相当于给定了一个条件却要满足两个判断,对于逆向而言,只需要选取其中任意一个判断条件进行攻破即可。ttk
函数其实是字符串替换加密,比较简单,留给有能力的读者进行练习(逃
作者发布、转载的任何文章中所涉及的技术、思路、工具仅供以安全目的的学习交流,并严格遵守《中华人民共和国网络安全法》、《中华人民共和国数据安全法》等网络安全法律法规。
任何人不得将技术用于非法用途、盈利用途。否则作者不对未许可的用途承担任何后果。
本文遵守CC BY-NC-SA 3.0协议,您可以在任何媒介以任何形式复制、发行本作品,或者修改、转换或以本作品为基础进行创作
您必须给出适当的署名,提供指向本文的链接,同时标明是否(对原文)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示作者为您或您的使用背书。
同时,本文不得用于商业目的。混合、转换、基于本作品进行创作,必须基于同一协议(CC BY-NC-SA 3.0)分发。
如有问题, 可发送邮件咨询.