Setelah menemukan kerentanan dalam mobile banking bank Ukraina (
pos ), saya ingin mengubah arah sedikit dan beralih dari layanan keuangan ke yang lain.
Sebuah artikel iklan tentang aplikasi taksi seluler yang diperbarui menarik perhatian saya, dan saya memilihnya sebagai eksperimen.
Di sini alatnya sama: PC, Fiddler, Android-smartphone - instal aplikasi dan lacak permintaannya.
Saya secara khusus tidak mempertimbangkan permintaan dan jawaban saat mendaftar atau masuk (misalnya, saya tidak memeriksa kemungkinan kata sandi brute force), tetapi beralih ke fungsi yang tersedia setelah pendaftaran.
Karena saya tidak memiliki riwayat perjalanan menggunakan layanan ini, dan saya tidak ingin melakukan perjalanan nyata untuk pengujian, saya memerlukan data dari salah satu klien lain. Saya memutuskan untuk meminta akun pada teman di layanan. Di antara kenalan ada klien taksi ini, tetapi mereka memanggilnya dengan cara kuno - dengan bantuan panggilan.
Kemudian saya mulai mencari nomor telepon di antara informasi yang tersedia untuk umum di Internet - misalnya, di situs web resmi dan di antara ulasan di jejaring sosial (
sering kali pelanggan tidak puas, menggambarkan keluhan, meninggalkannya di komentar untuk dilihat publik alih-alih mengirim perusahaan ke PM pribadi mereka ). Akibatnya, saya menemukan beberapa telepon di salah satu situs pencarian pekerjaan. Saya menggantikan salah satu dari mereka dalam permintaan berikutnya dan menerima informasi yang seharusnya tidak dapat diakses oleh siapa pun dari luar.

Ini adalah masalah-masalah berikut:
1. Kami mendapatkan id klien, namanya, telepon, email, dan kota (taksi berfungsi di beberapa kota).
Ketika aplikasi memuat profil, permintaan POST berikut dijalankan:
https://sometaxi/mobile3/templateAll.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 37 func=loadMyInfo&phone=%2B380671234567
Mengganti nomor telepon orang lain di fungsi
loadMyInfo&phone
, sebagai respons saya menerima id klien, nama lengkap, telepon, email, dan kota:
[{"id":14014,"varFirstName":" ","varLastName":"","varSurName":" ","varTel":"+380671234567","varTel2":"","varEmail":"Sergey_ivan@some.mail","city":1,"cityName":""}]
2) Informasi tentang kartu pembayaran pelangganDalam permintaan kedua, saya bisa mendapatkan informasi tentang kartu pembayaran yang ditambahkan oleh klien ke akun pribadi saya:
https://sometaxi/mobile3/ClientCard.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 58 data={"Task":"GetClientCardsData","phone":"+380671234567"}
Jawabannya adalah:
{"data":[{"masked_card":"512345XXXXXX6789","rectoken":"ccaffe873a0e88caf49bc65bbef2390329","card_type":"MASTERCARD","default":true,"card_name":""}]}
Di sini tersedia: nomor kartu terpotong, semacam token, jenis kartu, apakah kartu dipasang secara default dan namanya.
3) Mendapatkan informasi tentang perjalanan klienPermintaan ketiga - loadHistory - diharapkan memberi saya jumlah informasi terbesar dan paling penting (seperti yang saya pikirkan):
https://sometaxi/mobile3/templateAll.php?PHPSESSID=4cmdlokh4luo209d88kv6uh7 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: User Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 38 func=loadHistory&phone=%2B380671234567
Sebagian dari jawabannya
(seperti sebelumnya, data berubah) :
{"id":454875,"From":"- ., 1","To":"і ., 13","When":"10-01-2019 15:55","WhenDate":1569942900,"Price":"160","Rate":0,"preorder":0,"status":1,"orderid":"11174445","additionalServices":"[]","classAvto":2,"callsignid":6426,"Car":" ,Toyota Corolla,, 3733 ","city":1,"cityName":"ї","distance":"0.00"} {"id":408880,"From":" ., 2","To":"- ., 1","When":"25-12-2018 03:44","WhenDate":1545709440,"Price":"79","Rate":0,"preorder":0,"status":1,"orderid":"10966503","additionalServices":"[]","classAvto":2,"callsignid":4545,"Car":" ,Toyota Corolla,, 0415 ","city":null,"cityName":null,"distance":"0.00"}
Di sini tersedia: Alamat keberangkatan, alamat tujuan, Tanggal dan waktu perjalanan, Biaya, serta nama lengkap pengemudi taksi, jenis, warna dan nomor mobilnya.
Total: dengan sepasang permintaan, berdasarkan nomor telepon Anda dapat mengetahui segala sesuatu tentang klien dari layanan ini, termasuk perincian tertentu dari kehidupan pribadinya (misalnya, perjalanan ke Tahun Baru pukul 2 pagi dari satu alamat ke alamat lainnya).
Tentunya ada tempat lain dalam aplikasi di mana informasi lain dapat diperoleh. Tapi itu sudah cukup untuk menginformasikan pengembang tentang hal ini, yang saya lakukan segera untuk mengarahkan alamat kantor.
Kami berkorespondensi selama sebulan, dan kemudian mereka membayar saya.
Dan kemudian posting ini bisa berakhir, tetapi saya memutuskan untuk memeriksa lagi jika semua kesalahan sudah diperbaiki.
Ya, dua dari tiga permintaan tidak lagi memberi saya informasi orang lain,
tetapi satu masih valid.Kartu pembayaran ditambahkan ke aplikasi ini dengan cara yang sama seperti yang lain: pertama, pada halaman khusus, klien menunjukkan nomor lengkap, tanggal kedaluwarsa dan kartu CVV. Kemudian datang verifikasi dengan menghapus 1 UAH. dan konfirmasi pelanggan untuk operasi semacam itu menggunakan 3-D Secure / LookUp. Ini adalah praktik normal, nomor lengkap dan rincian pembayaran lainnya dari kartu pelanggan tidak ada dalam permintaan.
Tetapi karena saya melihat bahwa kartu tambahan saya dihapus oleh permintaan dari form
data={"Task":"DeleteClientCardsData", "rectoken":"bc65bbef2390329ccaffe873a0e88caf49" }
, saya memutuskan untuk memeriksa: apa yang akan terjadi jika saya menentukan klien yang di-rectoken dari klien lain.
4) Melepaskan kartu orang lain dengan tokenSaya menjalankan permintaan dengan token lain:
https://sometaxi/mobile3/ClientCard.php?PHPSESSID=5n4tim74asve7uefdf3hvd6c3 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G925F) Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 86 data={"Task":"DeleteClientCardsData","rectoken":"ccaffe873a0e88caf49bc65bbef2390329"}
Dan kartu alien telah hilang!
Saya juga memeriksa ini dengan permintaan yang sama # 2 - apakah itu hanya respons visual
{"status":"Success"."err":""}
, atau apakah kartu tersebut benar-benar dihapus dari klien.
Peta memang telah dihapus.
Segera saya menulis surat kedua, meminta maaf, tetapi memutuskan untuk bereksperimen lebih lanjut dengan membuat akun lain untuk saya sendiri: jika kartu dapat dihapus dengan token - mungkin dapat dihubungkan dengan token yang sama, dan dapat dikaitkan dengan dirinya sendiri?
5) Menambahkan kartu orang lain dengan token ke akun AndaYa, saya tidak akan merana - kartu orang lain dapat dikaitkan dengan dirinya sendiri. Hal utama adalah mengetahui dikoreksi (dan Anda bisa mendapatkannya berkat masalah terbuka # 2).
Dalam permintaan POST, dimungkinkan untuk menentukan data apa pun - 6 digit pertama dan 4 terakhir dari nomor kartu, setidaknya 500.000 **** 1111 - kartu secara visual dikaitkan dengan data ini, dan tokennya berasal dari klien lain dan valid.
POST https://sometaxi/mobile3/ClientCard.php?PHPSESSID=5n4tim74asve7uefdf3hvd6c3 HTTP/1.1 Content-Type: application/x-www-form-urlencoded charset: utf-8 User-Agent: Dalvik/2.1.0 (Linux; U; Android 5.1.1; SM-G925F) Host: sometaxi Connection: Keep-Alive Accept-Encoding: gzip Content-Length: 221 data={"Task":"ClientCardData","default":false,"phone":"+380991234567","masked_card":"500000XXXXXX1111","card_name":"Test","card_type":"MASTERCARD","rectoken":"4f6d228517f2d45690670aba78013a0408"}
Apa artinya ini: karena kemungkinan menautkan token ke akun saya, saya bisa melakukan perjalanan dengan biaya orang lain tanpa mengetahui detail lengkap kartu dan tanpa verifikasi tambahan - lagipula, kartu telah ditambahkan oleh klien dan berhasil diverifikasi oleh layanan pembayaran.
Penjelasan tentang kemampuan membayar dari kartu orang lain:Untuk menyederhanakan input perincian pembayaran untuk pembayaran, digunakan pembayaran satu kali klik berdasarkan token. Pada pembelian pertama, klien memasukkan data pembayaran, dengan pembayaran berikutnya kepada klien, cukup klik tombol "bayar".
Token adalah nomor unik yang ditugaskan untuk satu set parameter kartu dalam sistem. Token ini dapat digunakan untuk pembayaran langsung tanpa memasukkan CVV dan tanpa otentikasi 3-D Secure.
OpsionalMembuat token adalah proses pembayaran / pemblokiran dana yang berhasil pada kartu klien dengan memasukkan detail lengkap klien (nomor kartu, tanggal kedaluwarsa, CVV). Anda dapat membuat token sebagai berikut:
- Terima pembayaran (Pembelian) - pembayaran yang berhasil oleh klien dengan pengenalan detail kartu lengkap. Kartu ini ditugaskan recToken dan dikirim dalam respon.
- Verifikasi kartu / tanda terima token (Verifikasi) - verifikasi kartu berhasil, memblokir dana pada kartu klien. Kartu ini ditugaskan recToken dan dikirim dalam respon.
Penghapusan oleh token - operasi mendebet / memblokir dana pada kartu, tanpa partisipasi klien, dengan mentransfer token dari pedagang.
Contoh penjelasan diambil
dari sini .
Pengembang diminta untuk menunjukkan kemungkinan mentransfer token dari akun mereka ke tambang dan memesan taksi - mereka perlu memastikan bahwa pengurangan token akan benar-benar terjadi. Tentu saja, pesanan berlalu, uangnya didebit (
saya tidak masuk ke dalam mobil ). Kemudian mereka membayar saya lebih banyak uang.
Seperti yang Anda lihat dari artikel ini dan sebelumnya, terkadang PHPSESSID, Otorisasi, atau SecurityToken tidak cukup.
Jika Anda seorang pengembang, ikuti apa yang Anda berikan ketika Anda bertanya. Jika Anda seorang tester, cari dan temukan, tetapi pastikan untuk memberi tahu pengembang tentang hal itu. Kerentanan penuh di sana-sini, jadi silakan menjadi peretas putih.