EasyCTF IV 2018 - Reversing
Liar
Diberikan sebuah file binary 64-bit not stripped
Hasil decompile fungsi main()
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@12
__int64 v4; // rdi@12
int n; // [sp+Ch] [bp-14h]@1
int i; // [sp+10h] [bp-10h]@1
int m; // [sp+14h] [bp-Ch]@1
__int64 v8; // [sp+18h] [bp-8h]@1
v8 = *MK_FP(__FS__, 40LL);
__isoc99_scanf(&unk_A64, &n, envp);
f[30] = 160LL;
f[10] = 47LL;
f[13] = 4LL;
f[25] = 205LL;
f[5] = 87LL;
f[24] = 247LL;
f[6] = 76LL;
f[31] = 176LL;
f[7] = 74LL;
f[34] = 154LL;
f[21] = 231LL;
f[32] = 135LL;
f[8] = 75LL;
f[1] = 102LL;
f[9] = 75LL;
f[28] = 232LL;
f[29] = 148LL;
f[3] = 108LL;
f[11] = 33LL;
f[4] = 127LL;
f[14] = 21LL;
f[18] = 89LL;
f[16] = 3LL;
f[26] = 215LL;
f[20] = 211LL;
f[15] = 8LL;
f[17] = 25LL;
f[27] = 217LL;
f[0] = 101LL;
f[33] = 143LL;
f[22] = 245LL;
f[19] = 241LL;
f[12] = 56LL;
f[36] = 129LL;
f[23] = 206LL;
f[2] = 125LL;
f[35] = 202LL;
m = n ^ 0x58EB29;
for ( i = 0; i <= 36; ++i )
g[i] = m * i ^ (unsigned __int64)f[i];
g[i] = 0;
if ( g[0] == 101 && g[1] == 97 && g[2] == 115 && g[3] == 121 && g[4] == 99 && g[5] == 116 && g[6] == 102 )
printf("the flag is %s\n", g);
result = 0;
v4 = *MK_FP(__FS__, 40LL) ^ v8;
return result;
}
Dimana pada potongan code berikut
m = n ^ 0x58EB29;
for ( i = 0; i <= 36; ++i )
g[i] = m * i ^ (unsigned __int64)f[i];
n
adalah inputan user. Yang apabila inputan benar, akan mengeluarkan flag yang benar.
Untuk mencari nilai n
yang benar, saya menggunakan z3
Berikut script nya
from z3 import *
s = Solver()
n = BitVec("X1",32)
f1 = 102
m = n ^ 0x58EB29
g = m * 1 ^ f1
s.add(g == 97)
print s.check()
m = s.model()
print "Valid n {}".format(m[n])
Flag : easyctf{still_wasn’t_too_bad,_right?}
Adder
Diberikan sebuah file binary 64-bit not stripped
Hasil decompile fungsi main()
v7 = 0;
std::operator<<<std::char_traits<char>>(&std::cout, "Enter three numbers!\n", envp);
LODWORD(v3) = std::istream::operator>>(&std::cin, &v9);
LODWORD(v4) = std::istream::operator>>(v3, &v8);
std::istream::operator>>(v4, &v7);
ptr = gen(v8 + v9 + v7);
v5 = (v8 + v9);
if ( v5 + v7 == 1337 )
{
std::operator<<<std::char_traits<char>>(&std::cout, "easyctf{", v5);
print_ptr(ptr);
puts("}");
}
else
{
std::operator<<<std::char_traits<char>>(&std::cout, "nope.\n", v5);
}
v8, v9, v7
adalah inputan user, dan fungsi gen()
adalah fungsi yang menggenerate flag.
ptr = gen(v8 + v9 + v7);
v5 = (v8 + v9);
if ( v5 + v7 == 1337 )
(v8 + v9) + v7
harus ==
1337 untuk mendapatkan Flag.
Berikut script yang digunakan
from z3 import *
N = Ints("N1 N2 N3")
v5 = N[1] + N[2]
solve((v5 + N[0]) == 1337)
Flag : easyctf{y0u_added_thr33_nums!}
EzReverse
Diberikan sebuah file binary 64-bit not stripped
$ file executable
executable: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=eb7a47c52c657a17b5ae730826c4640de86b0dcf, not stripped ```
```C
Hasil decompile fungsi `main()`
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax@2
int v4; // [sp+10h] [bp-20h]@3
int v5; // [sp+14h] [bp-1Ch]@3
int v6; // [sp+18h] [bp-18h]@3
int v7; // [sp+1Ch] [bp-14h]@3
int v8; // [sp+20h] [bp-10h]@3
const char *v9; // [sp+28h] [bp-8h]@3
signal(2, sigintHandler);
target = (char *)*argv;
if ( argc == 2 )
{
v9 = argv[1];
v4 = 1;
v5 = 2;
v6 = 3;
v7 = 4;
v8 = 5;
v4 = *v9 + 1;
v5 = v9[1] + 2;
v6 = v9[2] + 3;
v7 = v9[3] + 4;
v8 = v9[4] + 5;
if ( v7 != 111 || v6 != 125 || v4 != v8 - 10 || v5 != 53 || v8 != v7 + 3 )
{
sleep(2u);
remove(*argv);
puts("successfully deleted!");
result = 2;
}
else
{
printf("Now here is your flag: ", sigintHandler, argv);
print_5(&v4);
result = 1;
}
}
else
{
result = 2;
}
return result;
}
Program tersebut membutuhkan argument
dan apabila argument yang dimasukan salah, program akan di remove()
.
Karakter pada variable v4
dan v8
belum diketahui dengan pasti. Dan untuk karakter pada variable v5, v6, v7
masing2 ditambahkan dengan 2,3,4
.
Dan v4 dan v8
masing-masing ditambahkan dengan 1 dan 5
.
Untuk mendapatkan nilai v4 dan v8
menggunakan persamaan
v4 == v8 - 10
v8 == v7 + 3
Untuk mencari nya saya menggunakan z3
.
Berikut script yang digunakan
from z3 import *
f = [BitVec("f{}".format(i),32) for i in range(5)]
s = Solver()
for i in range(len(f)):
s.add(f[i] <= ord("z"), f[i] >= ord(" "))
v4 = f[0] + 1
v5 = f[1] + 2
v6 = f[2] + 3
v7 = f[3] + 4
v8 = f[4] + 5
s.add(v4 == (v8 - 10))
s.add(v5 == 53)
s.add(v6 == 125)
s.add(v7 == 111)
s.add(v8 == (v7 + 3))
s.check()
m = s.model()
print "".join([ chr(m[i].as_long()) for i in f ])