长安“战疫”逆向WP

长安"战疫"逆向WP

1.0 - combat_slogan

解压ctftest.jar文件后,在ctftest\com\xaut路径找到Main.class文件,用java反编译得到java代码

package com.xaut;

import java.util.Scanner;

public class Main {

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

   public static String ttk(String input) {
      StringBuilder sb = new StringBuilder();

      for(int i = 0; i < input.length(); ++i) {
         char c = input.charAt(i);
         if(c >= 97 && c <= 109) {
            c = (char)(c + 13);
         } else if(c >= 65 && c <= 77) {
            c = (char)(c + 13);
         } else if(c >= 110 && c <= 122) {
            c = (char)(c - 13);
         } else if(c >= 78 && c <= 90) {
            c = (char)(c - 13);
         }

         sb.append(c);
      }

      return sb.toString();
   }

   public static void main(String[] args) {
      System.out.println("Please input your keyword锛�");
      Scanner scan = new Scanner(System.in);
      String str2 = "ddd";
      if(scan.hasNextLine()) {
         str2 = scan.nextLine();
      }

      scan.close();
      String stringTransformAscii = stringTransformAscii(str2);
      String[] offerCodeString = stringTransformAscii.split(",");
      StringBuffer str5 = new StringBuffer();
      String[] flag = offerCodeString;
      int var7 = offerCodeString.length;

      for(int var8 = 0; var8 < var7; ++var8) {
         String s = flag[var8];
         str5.append(s);
      }

      int var10 = ttk(str2).compareTo("Jr_j11y_s1tug_g0_raq_g0_raq_pnml");
      if(var10 == 0 && str5.toString().compareTo("871019511949491089510249103104116951164895101110100951164895101110100959997122121") == 0) {
         System.out.println("Your keyword is correct!");
      } else {
         System.out.println("Your keyword is wrong!");
      }

   }
}

一个很简单的类似单表代换的操作,写exp的时候记得改一下条件就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char a[100]="Jr_j11y_s1tug_g0_raq_g0_raq_pnml";

int main()
{
    for(int i = 0; i < strlen(a); ++i)
    {
        char c = a[i];
        if(c >= 97 + 13 && c <= 109 + 13)
        {
            c = (char)(c - 13);
        } else if(c >= 65 + 13 && c <= 77 + 13)
        {
            c = (char)(c - 13);
        } else if(c >= 110 - 13 && c <= 122 - 13)
        {
            c = (char)(c + 13);
        } else if(c >= 78 - 13 && c <= 90 - 13)
        {
            c = (char)(c + 13);
        }
        printf("%c",c);
    }
}

运行得到

flag{We_w11l_f1ght_t0_end_t0_end_cazy}

2.0 - cute_doge

解压后发现一个.exe文件,打开以后

获得提示,先打开IDApro直接进入动态调试。

在这一步的时候点击OK发现直接弹出了

得到

flag{Ch1na_yyds_cazy}

3.0 - hello_py

一道python反编译题,用uncompyle6指令反编译得到python代码

# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: C:\Users\Administrator\Desktop\easy_py.py
# Compiled at: 2021-12-28 15:45:17
# Size of source mod 2**32: 1099 bytes
import threading, time

def encode_1(n):#简单异或
    global num#global的意思就是在子函数内也可以更改全局变量,也没什么用,一开始num是等于9的
    while True:
        if num >= 0:
            flag[num] = flag[num] ^ num
            num -= 1
            time.sleep(1)
        if num <= 0:
            break


def encode_2(n):#简单异或
    global num
    while True:
        if num >= 0:
            flag[num] = flag[num] ^ flag[(num + 1)]
            num -= 1
            time.sleep(1)
        if num < 0:
            break


while True:
    Happy = [
     44, 100, 3, 50, 106, 90, 5, 102, 10, 112]
    num = 9
    f = input('Please input your flag:')
    if len(f) != 10:
        print('Your input is illegal')
    else:
        flag = list(f) #list() 方法用于将元组或字符串转换为列表。
        j = 0
        for i in flag:#把flag通过ASCII码变成数字
            flag[j] = ord(i)
            j += 1
        else:
            print("flag to 'ord':", flag)
            t1 = threading.Thread(target=encode_1, args=(1, ))
            t2 = threading.Thread(target=encode_2, args=(2, ))
            t1.start()
            time.sleep(0.5)
            t2.start()
            t1.join()
            t2.join()
            #这个threading就是多线程跑代码的意思,先用t1.start(),再用t2.start()先后加密flag
        if flag == Happy:
            print('Good job!')
        else:
            print('No no no!')

代码理解已贴注释,放上c++exp:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char flag[10]={ 44, 100, 3, 50, 106, 90, 5, 102, 10, 112};

int main()
{
	for(int i=0;i<10;i+=2)flag[i]=flag[i]^flag[i+1];
	for(int i=1;i<10;i+=2)flag[i]=flag[i]^i;
	cout<<flag;
}

运行得到

flag{He110_cazy}

4.0 - lemon

这签到题属实给我整不会了,第一次见到字节码概念,感觉跟汇编差不多,本题应该是python字节码,需要硬看字节码还原代码,我人麻了,下面放上缩进+注释版字节码

0: const 60 ; <module 'main'> 
5: module 9 592
11:   const 26 ; 83 
16:   const 27 ; 69 
21:   const 28 ; 65 
26:  array 3
31: store 0 0//var_00数组,里面存的65,69,83(小端序,可能是入栈顺序的原因?)
34:    const 30 ; 101 
39:    const 31 ; 108 
44:    const 32 ; 111 
49:    const 33 ; 117 
54:    const 34 ; 122 
59:    const 30 ; 101 
64:    const 35 ; 105 
69:    const 36 ; 98 
74:    const 30 ; 101 
79:    const 31 ; 108 
84:    const 33 ; 117 
89:    const 35 ; 105 
94:    const 37 ; 113 
99:    const 33 ; 117 
104:   const 35 ; 105 
109:   const 37 ; 113 
114:  array 16
119: store 0 1//var_01数组,里面倒序存了16个值
122:  const 39 ; 0 
127: store 0 2//var_02变量=0
130:  array 0
135: store 0 3//var_03数组为空
138:  load 0 2//将var_02入栈
141:  const 42 ; 256 //常数256
146: lt//var_02 less than 256
147: jz 184//不成立就跳到184行
152:   load 0 3//将var_03入栈
155:   const 43 ; append//对var_03调用append方法
160:  getattr
161:  load 0 2//将var_02入栈
164: call 1//对将栈顶往下的一个值var_02使用append方法
166: pop//append结束
167:   load 0 2//var_02入栈
170:   const 44 ; 1//常数1
175:  add//和var_02相加
176: store 0 2//更新var_02的值
179: jmp 138//循环语句,跳转至138行
184:  const 39 ; 0//常数0
189: store 0 4//更新var_04=0
192:  load 0 4//var_04入栈
195:  const 42 ; 256 //常数256
200: lt//var_04<256
201: jz 271//跳转271行
206:      load 0 3//var_03数组
209:      load 0 4
212:     getitem//将var_04作为下标
213:      load 0 0//var_00数组
216:       load 0 4
219:       const 46 ; 3//常数3 
224:      mod
225:     getitem//将var_04 % 3作为下标
226:    add//将上面两个下标对应的值做加法
227:     load 0 1//var_01数组
230:      load 0 4
233:      const 47 ; 16 
238:     mod
239:    getitem//var_04 % 16作为下标
240:   add//将上面两个下标对应的值做加法
241:   const 42 ; 256 
246:  mod//结果%256
247:  load 0 3//var_03
250:  load 0 4//下标为var_04
253: setitem//更新var_03[var_04]的值
254:   load 0 4
257:   const 44 ; 1 
262:  add
263: store 0 4//var_04+=1
266: jmp 192//循环语句
271:  const 39 ; 0 
276: store 0 5//var_05=0
279:  load 0 5
282:  const 46 ; 3 
287: lt//var_05 less than 3
288: jz 448//跳转
293:  const 39 ; 0 
298: store 0 6//var_06=0
301:  load 0 6
304:  const 42 ; 256 
309: lt//var_06 less than 256
310: jz 366//跳转
315:    load 0 3
318:    load 0 6
321:   getitem//var_03[var_6]
322:    load 0 3
325:      load 0 6
328:      const 44 ; 1 
333:     add
334:     const 42 ; 256 
339:    mod
340:   getitem//var_03[(var_06+1)%256]
341:  bxor//将上面两个值异或
342:  load 0 3
345:  load 0 6
348: setitem//更新var_03[var_06]
349:   load 0 6
352:   const 44 ; 1 
357:  add
358: store 0 6//var_06+=1
361: jmp 301//内循环结束
366:  const 39 ; 0
371: store 0 7//var_07=0
374:  load 0 7
377:  const 42 ; 256 
382: lt//var_07 < 256
383: jz 431
388:     load 0 3
391:     load 0 7
394:    getitem//var_03[var_07]
395:    const 44 ; 1 
400:   add//var_03[var_07]+1
401:   const 42 ; 256 
406:  mod//%256
407:  load 0 3
410:  load 0 7
413: setitem//更新
414:   load 0 7
417:   const 44 ; 1 
422:  add
423: store 0 7//var_07+=1
426: jmp 374//内循环结束
431:   load 0 5
434:   const 44 ; 1 
439:  add
440: store 0 5//var_05+=1
443: jmp 279//外循环结束
448:  const 39 ; 0 
453: store 0 5
456:  const 39 ; 0 
461: store 0 8//var_05=var_08=0
464:  load 0 5
467:  const 42 ; 256 
472: lt//var_05 < 256
473: jz 509
478:   load 0 8
481:    load 0 3
484:    load 0 5
487:   getitem
488:  add
489: store 0 8//var_08+=var_03[var_05]
492:   load 0 5
495:   const 44 ; 1 
500:  add
501: store 0 5//var_05+=1
504: jmp 464//循环结束
509:    load 0 8
512:    const 51 ; 20 
517:   mul//var_08*20
518:   const 52 ; 5 
523:  add//+5
524: store 0 8//更新
527:    load 0 8
530:    const 54 ; 30 
535:   mul
536:   const 52 ; 5 
541:  sub
542: store 0 8//var_08*=30,var_08-=5
545:    load 0 8
548:    const 56 ; 40 
553:   mul
554:   const 52 ; 5 
559:  sub
560: store 0 8//var_08*=40,var_08-=5
563:     load 0 8
566:     const 58 ; 50 //var_08*=50,var_08-=5
571:    mul
572:   const 59 ; 6645 
577:  add
578: store 0 8//var_08+=6645
581:  const 23 ; <function 'print'> 
586:  load 0 8
589: call 1
591: pop//print(var_08);

注释已经非常详尽,然而我捏妈打个ctf还遇到爆int然后调long long调了半小时这就有点说不过去了吧

#include<iostream>
#include<cstdio>
using namespace std;
int var_00[3]={65,69,83};
int var_01[16]={113,105,117,113,105,117,108,101,98,105,101,122,117,111,108,101};
int var_02=0;
int var_03[256];
int main()
{
	while(var_02<256)
	{
		var_03[var_02]=var_02;
		var_02++;
	}
	int var_04=0;
	while(var_04<256)
	{
		var_03[var_04]=(var_03[var_04]+var_00[var_04%3]+var_01[var_04%16])%256;
		var_04++;
	}
	int var_05=0;
	while(var_05<3)
	{
		int var_06=0;
		while(var_06<256)
		{
			var_03[var_06]^=var_03[(var_06+1)%256];
			var_06++;
		}
		int var_07=0;
		while(var_07<256)
		{
			var_03[var_07]=(var_03[var_07]+1)%256;
			var_07++;
		}
		var_05++;
	}
	var_05=0;
	long long var_08=0;
	while(var_05<256)
	{
		var_08+=var_03[var_05];
		var_05++;
	}
	var_08*=20;
	var_08+=5;
	var_08*=30;
	var_08-=5;
	var_08*=40;
	var_08-=5;
	var_08*=50;
	var_08+=6645;
	cout<<var_08;
}

运行得到

flag{23075096395}
原文地址:https://www.cnblogs.com/THRANDUil/p/15805724.html