2021-09-24

攻防世界EasyRE & Guess-the-Number

EasyRE

可执行文件运行让用户“input”
Shift+Fn+F12 打开IDA中字符串视图,定位“input”在函数sub_401080中
主函数
主函数源码如下:

int sub_401080()
{
  unsigned int v0; // kr00_4
  signed int v1; // edx
  char *v2; // esi
  char v3; // al
  unsigned int v4; // edx
  int v5; // eax
  __int128 v7; // [esp+2h] [ebp-24h]
  __int64 v8; // [esp+12h] [ebp-14h]
  int v9; // [esp+1Ah] [ebp-Ch]
  __int16 v10; // [esp+1Eh] [ebp-8h]

  sub_401020((int)&unk_402150);
  v9 = 0;
  v10 = 0;
  v7 = 0i64;
  v8 = 0i64;
  sub_401050((const char *)&unk_402158, &v7);
  v0 = strlen((const char *)&v7);
  if ( v0 >= 0x10 && v0 == 24 )
  {
    v1 = 0;
    v2 = (char *)&v8 + 7;
    do
    {
      v3 = *v2--;
      byte_40336C[v1++] = v3;
    }
    while ( v1 < 24 );
    v4 = 0;
    do
    {
      byte_40336C[v4] = (byte_40336C[v4] + 1) ^ 6;
      ++v4;
    }
    while ( v4 < 0x18 );
    v5 = strcmp(byte_40336C, "xIrCj~<r|2tWsv3PtI\x7Fzndka");
    if ( v5 )
      v5 = -(v5 < 0) | 1;
    if ( !v5 )
    {
      sub_401020((int)"right\n");
      system("pause");
    }
  }
  return 0;
}

顺着right往上看,条件是strcmp对比字符串"xIrCj~<r|2tWsv3PtI\x7Fzndka"显然byte_40336C[]为flag数组,有个简单异或运算

byte_40336C[v4] = (byte_40336C[v4] + 1) ^ 6;
++v4;

直接逆推出flag,这里注意解密需要逆转加密字符串

v3 = *v2--;
byte_40336C[v1++] = v3;

字符长度为24,除了反汇编中的代码中可以获得,加密字符串也可以数出来,注意“\x7F”是一个十六进制字符,解密如下:

#coding:utf-8
en_flag = "xIrCj~<r|2tWsv3PtI\x7Fzndka"
de_flag = [0]*24
flag = ''
for i in range(24):
  de_flag[i] = (ord(en_flag[i])^6)-1
  flag += chr(de_flag[i])
print(flag[::-1])

flag

Guess-the-Number

jar小程序,jd-gui查看反汇编代码

import java.math.BigInteger;

public class guess
{
  static String XOR(String _str_one, String _str_two) {
    BigInteger i1 = new BigInteger(_str_one, 16);
    BigInteger i2 = new BigInteger(_str_two, 16);
    BigInteger res = i1.xor(i2);
    return res.toString(16);
  }

  
  public static void main(String[] args) {
    int guess_number = 0;
    int my_num = 349763335;
    int my_number = 1545686892;
    int flag = 345736730;
    
    if (args.length > 0) {
      try {
        guess_number = Integer.parseInt(args[0]);
        if (my_number / 5 == guess_number) {
          String str_one = "4b64ca12ace755516c178f72d05d7061";
          String str_two = "ecd44646cfe5994ebeb35bf922e25dba";
          my_num += flag;
          String answer = XOR(str_one, str_two);
          
          System.out.println("your flag is: " + answer);
        } else {
          System.err.println("wrong guess!");
          System.exit(1);
        } 
      } catch (NumberFormatException e) {
        System.err.println("please enter an integer \nexample: java -jar guess 12");
        System.exit(1);
      } 
    } else {
      System.err.println("wrong guess!");
      int num = 1000000;
      num++;
      System.exit(1);
    } 
  }
}

本质就是str_one和str_two的异或,直接拿flag

#coding:utf-8
str_one = "4b64ca12ace755516c178f72d05d7061"
str_two = "ecd44646cfe5994ebeb35bf922e25dba"
print(hex(int(str_one,16)^int(str_two,16)))

#0xa7b08c546302cc1fd2a4d48bf2bf2ddb

回头审一下代码,只要满足if语句就直接返回flag,条件是小学算术(可我用的计算器):

int my_number = 1545686892;
……
……
if (my_number / 5 == guess_number)
……

所以执行jar,输入309137378就可返回flag
flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值