Berikut deskripsi soal
Diberikan koneksi untuk melakukan koneksi dari local ke server melalui adb.
Beberapa command adb diblacklist seperti shell.
Beberapa fungsi seperti pull berhasil dilakukan
Kami lalu mencoba untuk melakukan recon terhadap apa saja perintah adb yang dapat dilakukan dengan framework ghost
https://github.com/EntySec/Ghost
Ghost dapat digunakan untuk beberapa hal seperti ditampilkan pada menu.
Setelah mencoba beberapa fungsi. Kami menemukan bahwa fungsi list dapat digunakan untuk melakukan directory listing pada server
Namun ada beberapa kondisi janggal saat mengakses beberapa file atau folder, contohnya saat kami mencoba mengakses /data, aplikasi akan hang dan timeout. Kami lalu mencoba melihat traffic yang dilakukan saat proses adb berlangsung.
Saat ditelusuri menggunakan wireshark, saat melakukan proses listing, client akan mengirim packet berikut. Terlihat juga bahwa server mengirim packet yang berisi "The Path cannot contain ./ ../data".
Kami lalu mengecek isi environtment dari process adb yang digunakan. Salah satunya cmdline yang di eksekusi
Terlihat bahwa adbd yang digunakan menggunakan adb custom dan berada pada /data/local/tmp/adbd_sctf
Karena saat eksekusi adb, kami ada didalam proses adb, maka kita dapat mengunduh binary adb dengan melakukan pull terhadap file /proc/self/exe untuk dianalisa di local.
Saat kami menganalisis binary, kami menemukan hal yang menarik. Berikut beberapa string yang sebelumnya kita temui di traffic.
Terdapat juga string berikut yang kemungkinan berhubungan dengan flag.
Setelah menganalisis lebih jauh ada beberapa hal yang dapat disimpulkan dari binary adbd modif berikut
Beberapa command ADB di block dari sisi service.
Command sync ADB tidak dapat dilakukan untuk mengakses file / folder dengan string berisi ../ , ./ ataupun data, sehingga tidak dimungkinkan untuk mengakses flag (sejauh yang kami coba).
Terdapat custom command bernama flag di server yang akan mengeksekusi thread flag_service.
Terdapat input validation saat mengakses flag_service.
berikut adalah psudocdeo dari fungsi flag_service
unsigned __int64 __fastcall flag_service(int *a1)
{
int v1; // eax
int v2; // edx
int v3; // ecx
int v4; // er9
char *pointerloop; // rbx
__int64 i; // rbp
int v7; // ebx
const char *v8; // rsi
int v9; // ebx
int v10; // eax
int *v12; // r14
int v13; // ebp
__int64 v14; // rax
int *v15; // r14
int v16; // ebp
__int64 v17; // rax
__int64 v18; // rbx
size_t v19; // rax
char v20; // [rsp+0h] [rbp-A8h]
char v21[8]; // [rsp+8h] [rbp-A0h] BYREF
__int128 INPUTKITA[2]; // [rsp+10h] [rbp-98h] BYREF
char hash[16]; // [rsp+30h] [rbp-78h] BYREF
__int128 v24; // [rsp+40h] [rbp-68h]
char v25; // [rsp+50h] [rbp-58h]
__int128 md5hasil; // [rsp+60h] [rbp-48h] BYREF
unsigned __int64 v27; // [rsp+70h] [rbp-38h]
v27 = __readfsqword(0x28u);
md5hasil = 0LL;
if ( android::base::ShouldLog(2LL, 0LL) )
{
v12 = __errno(2LL, 0LL);
v13 = *v12;
android::base::LogMessage::LogMessage(hash, "system/core/adb/daemon/sctf_service.cpp", 55LL, 2LL, 0LL, 0xFFFFFFFFLL);
v14 = android::base::LogMessage::stream(hash);
std::__put_character_sequence<char,std::char_traits<char>>(v14, "adb Flag Service", 16LL);
android::base::LogMessage::~LogMessage(hash);
*v12 = v13;
}
v24 = 0LL;
*hash = 0LL;
v25 = 0;
INPUTKITA[1] = 0LL;
INPUTKITA[0] = 0LL;
WriteFdExactly(*a1, "An example of the flag looks like 'SCTF{FAKE_FLAG}'. Please enter the password.\n");
v1 = ReadLineFd(*a1, INPUTKITA, 0x20LL);
MD5(INPUTKITA, v1, &md5hasil);
pointerloop = hash;
for ( i = 0LL; i != 16; ++i )
{
snprintf(pointerloop, -1, v2, v3, *(&md5hasil + i), v4, v20);
LODWORD(pointerloop) = pointerloop + 2;
}
if ( android::base::ShouldLog(2LL, 0LL) )
{
v15 = __errno(2LL, 0LL);
v16 = *v15;
android::base::LogMessage::LogMessage(v21, "system/core/adb/daemon/sctf_service.cpp", 65LL, 2LL, 0LL, 0xFFFFFFFFLL);
v17 = android::base::LogMessage::stream(v21);
v18 = std::__put_character_sequence<char,std::char_traits<char>>(v17, "MD5: ", 5LL);
v19 = strlen(hash);
std::__put_character_sequence<char,std::char_traits<char>>(v18, hash, v19);
android::base::LogMessage::~LogMessage(v21);
*v15 = v16;
}
v7 = *a1;
if ( *hash ^ 0x33323130 | *&hash[3] ^ 0x36353433 )
{
v8 = "Wrong..";
}
else
{
getFlag();
v8 = &getFlag(void)::FLAG;
}
WriteFdExactly(v7, v8);
v9 = *a1;
v10 = fcntl(*a1, 1);
if ( (v10 & 0x80000001) == 0 )
fcntl(v9, 2, v10 | 1u);
return __readfsqword(0x28u);
}
Terlihat pada fungsi flag_service, kita harus mengisi string yang apabila dihash, hash depannya memiliki nilai 0123456. Setelah melakukan bruteforce didapati string yang yang memenuhi nilai berikut adalah string 0000AFf006
.
Setelah didapati string yang memenuhi value tersebut. Kita diharuskan untuk mengisi custom packet agar adb mengeksekusi service flag dan melakukan validasi terhadap packet parameter.
Untuk ini kami menggunakan framework adb_shell di python dan menggunakan device._open
untuk mengeksekusi custom command dan menggunakan AdbMessage
dengan parameter WRTE
untuk crafting payload yang akan di write.
from time import *
from adb_shell.adb_device import AdbDeviceTcp
import adb_shell.constants as constants
from adb_shell.adb_message import *
device1 = AdbDeviceTcp('adbaby.sstf.site', 6666, default_transport_timeout_s=9.)
device1.connect()
adb_info = device1._open(b"flag:", 1, 1, 1)
sleep(0.2)
msg = AdbMessage(constants.WRTE, adb_info.local_id, adb_info.remote_id, b"0000AFf006\n")
device1._io_manager.send(msg, adb_info)
sleep(0.2)
response1 =device1._io_manager.read([constants.OKAY], adb_info)
device1._okay(adb_info)
print(response1)
Jalankan script tersebut dan lihat pada wireshark aplikasi akan menampilkan flag pada traffic.