109_[FlareOn6]FlareBear
java这东西看着也费劲,就没有一种一看就明白的语言吗
题目是一个apk的文件,安装到雷电上是个小游戏,有3个选项,吃、玩、铲屎
再看代码,这个danceWithFlag是结果,通过调用关系找到他的上级setMood这里边用isEcstatic()检查是否成功,检查内容是3个变量为72,30,0
public final void dance(@NotNull Drawable drawable, @NotNull Drawable drawable2) {
Intrinsics.checkParameterIsNotNull(drawable, "drawable");
Intrinsics.checkParameterIsNotNull(drawable2, "drawable2");
this.handler.removeCallbacksAndMessages(null);
((ImageView) _$_findCachedViewById(R.id.flareBearImageView)).setImageDrawable(drawable);
((ImageView) _$_findCachedViewById(R.id.flareBearImageView)).setTag("ecstatic");
Handler handler = new Handler();
handler.postDelayed(new FlareBearActivity$dance$r$1(this, handler, drawable2, drawable), 500);
}
public final void danceWithFlag() {
InputStream openRawResource = getResources().openRawResource(R.raw.ecstatic);
Intrinsics.checkExpressionValueIsNotNull(openRawResource, "ecstaticEnc");
byte[] readBytes = ByteStreamsKt.readBytes(openRawResource);
InputStream openRawResource2 = getResources().openRawResource(R.raw.ecstatic2);
Intrinsics.checkExpressionValueIsNotNull(openRawResource2, "ecstaticEnc2");
byte[] readBytes2 = ByteStreamsKt.readBytes(openRawResource2);
String password = getPassword();
try {
readBytes = decrypt(password, readBytes);
readBytes2 = decrypt(password, readBytes2);
dance(new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(readBytes, 0, readBytes.length)), new BitmapDrawable(getResources(), BitmapFactory.decodeByteArray(readBytes2, 0, readBytes2.length)));
} catch (Exception unused) {
}
}
public final void setMood() {
if (isHappy()) {
((ImageView) _$_findCachedViewById(R.id.flareBearImageView)).setTag("happy");
if (isEcstatic()) {
danceWithFlag();
return;
}
return;
}
((ImageView) _$_findCachedViewById(R.id.flareBearImageView)).setTag("sad");
}
public final boolean isEcstatic() {
int state = getState("mass", 0);
int state2 = getState("happy", 0);
int state3 = getState("clean", 0);
if (state == 72 && state2 == 30 && state3 == 0) {
return true;
}
return false;
}
再看怎么改变这3项
public final void feed(@NotNull View view) {
Intrinsics.checkParameterIsNotNull(view, "view");
saveActivity("f");
changeMass(10);
changeHappy(2);
changeClean(-1);
incrementPooCount();
feedUi();
}
public final void play(@NotNull View view) {
Intrinsics.checkParameterIsNotNull(view, "view");
saveActivity("p");
changeMass(-2);
changeHappy(4);
changeClean(-1);
playUi();
}
public final void clean(@NotNull View view) {
Intrinsics.checkParameterIsNotNull(view, "view");
saveActivity("c");
removePoo();
cleanUi();
changeMass(0);
changeHappy(-1);
changeClean(6);
setMood();
}
简单列个方程计算一下,结果是吃8次玩4次铲屎2次
from z3 import *
x,y,z = Ints('x y z')
s = Solver()
s.add([10*x - 2*y == 72, 2*x+4*y-z==30, z*6-x-y==0])
s.check()
d = s.model()
print(d)
#[z = 2, y = 4, x = 8]
#flag{th4t_was_be4rly_a_chall3nge@flare-on.com}
110_[INSHack2018]Tricky-Part1
这个比较入门了
直接在main里输入然后就检查
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx
char v4; // bl
__int64 v5; // rax
char v7[16]; // [rsp+0h] [rbp-30h] BYREF
char v8[32]; // [rsp+10h] [rbp-20h] BYREF
if ( ptrace(PTRACE_TRACEME, 0LL, 1LL, 0LL) >= 0 )
{
std::string::string((std::string *)v7);
std::operator<<<std::char_traits<char>>(&std::cout, "Enter your flag : ");
std::operator>><char>(&std::cin, v7);
stack_check();
v4 = std::operator==<char>(v7, v8);
std::string::~string(v8);
if ( v4 )
v5 = std::operator<<<std::char_traits<char>>(
&std::cout,
"Correct but this is just the first one\nValidate with the flag");
else
v5 = std::operator<<<std::char_traits<char>>(&std::cout, "Sooo bad. Are you trying to trick me ?");
std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
v3 = 0;
std::string::~string(v7);
}
else
{
std::operator<<<std::char_traits<char>>(&std::cout, "Oh no, don't debug me plz\n");
return 42;
}
return v3;
}
stack_check()负责将存的数据加密(与GDB异或)
std::string *__fastcall stack_check(std::string *a1)
{
unsigned __int64 v1; // rbx
unsigned __int64 v2; // rax
_BYTE *v3; // rax
unsigned __int64 v4; // rbx
char v6; // [rsp+1Bh] [rbp-25h] BYREF
int i; // [rsp+1Ch] [rbp-24h]
char v8[32]; // [rsp+20h] [rbp-20h] BYREF
std::allocator<char>::allocator(&v6);
std::string::string(v8, &unk_4011D8, &v6);
std::allocator<char>::~allocator(&v6);
for ( i = 0; ; ++i )
{
v4 = i;
if ( v4 >= std::string::size((std::string *)&base) )
break;
v1 = i;
v2 = std::string::size((std::string *)v8);
LOBYTE(v1) = *(_BYTE *)std::string::operator[](v8, v1 % v2);
v3 = (_BYTE *)std::string::operator[](&base, i);
*v3 ^= v1;
}
std::string::string(a1, (const std::string *)&base);
std::string::~string(v8);
return a1;
}
只是这个base的值在哪还不清楚,于是找引用发现变动之处,它是直接复制的unk_401278的值
int __fastcall __static_initialization_and_destruction_0(int a1, int a2)
{
int result; // eax
char v3[17]; // [rsp+1Fh] [rbp-11h] BYREF
if ( a1 == 1 && a2 == 0xFFFF )
{
std::ios_base::Init::Init((std::ios_base::Init *)&std::__ioinit);
__cxa_atexit(std::ios_base::Init::~Init, &std::__ioinit, &_dso_handle);
std::allocator<char>::allocator(v3);
std::string::string(&base, &unk_401278, v3);
std::allocator<char>::~allocator(v3);
return __cxa_atexit(std::string::~string, &base, &_dso_handle);
}
return result;
}
写脚本处理一下
a = bytes.fromhex('0E0A11063F011F1C1D76371D2F7030237730182272351B3133703676271D732A762B75313E371D302C71291B26742637202371351B2473752E3439')
b = b'GDB'
print(bytes([a[i]^b[i%3] for i in range(len(a))]))
#INSA{CXX_1s_h4rd3r_f0r_st4t1c_4n4l1sys_wh3n_d3bugg3r_f41ls}
#flag{CXX_1s_h4rd3r_f0r_st4t1c_4n4l1sys_wh3n_d3bugg3r_f41ls}