攻防世界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])
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