ret2dlresolve with unexpected no gadget ahh.

Firstly, we checksec this challenge to know that is the protection and how to approach.
~/ctf/playit/pwn/kukyo
❯ checksec kukyo 13:28:10
[*] '/home/claritys/ctf/playit/pwn/kukyo/kukyo'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
Stripped: No
Yang nyala hanya Partial RELRO (tetep bisa GOT overwrite) dan NX Enabled (nggak bisa shellcode).
Sekarang kita decompile chall ini untuk mengetahui flownya.
//----- (000000000040115F) ----------------------------------------------------
ssize_t __fastcall exact(char *a1, size_t a2)
{
ssize_t result; // rax
ssize_t v4; // [rsp+10h] [rbp-10h]
char *buf; // [rsp+18h] [rbp-8h]
result = (ssize_t)a1;
buf = a1;
while ( a2 != 0 )
{
v4 = read(0, buf, a2);
if ( v4 <= 0 )
_exit(0);
buf += v4;
result = v4;
a2 -= v4;
}
return result;
}
//----- (00000000004011BE) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
char v4[64]; // [rsp+0h] [rbp-40h] BYREF
exact(ledger, 0x40u);
exact(v4, 0xA0u);
close(0);
return 0;
}
Kita mulai dari function main, ada function close(0) yang di mana menjadikan kita nanti nggak bisa dapetin shell tetapi harus langsung direct ke tempat flagnya. Because close(0) dia menutup standard input, so we can’t input some character to run a command like cat /flag.txt when you got the /bin/bash.
For the function exact, dia cara kalau dipanggil nanti parameter pertama menjadi ukuran untuk menaruh inputan kita (tapi nggak ditaruh di situ), untuk parameter kedua itu untuk menentukan berapa byte input kita yang bisa kita masukkan ke function read.
But the catch is, jumlah input kita harus sama dengan paramer kedua (a2), karena a2 != 0. a2 harus = 0. Biar nanti programnya bisa return.
Anyhow, there’s a mysterious function that does nothing at decompiler.
//----- (0000000000401156) ----------------------------------------------------
void handle()
{
;
}