Bagaimana Saya Meretas Steam. Dua kali

Halo, Habr! Hari ini saya akan memberi tahu Anda mengapa Valve membayar karunia terbesar dalam sejarah program hadiah mereka untuk kerentanan. Selamat datang di kucing!



1. SQL Injection


Layanan partner.steampowered.com dirancang untuk menerima informasi keuangan dari mitra Steam. Pada halaman laporan penjualan, grafik digambar dengan tombol yang mengubah periode statistik yang ditampilkan. Di sini mereka berada di kotak hijau:



Permintaan unduhan statistik terlihat seperti ini:


di mana "UA" adalah kode negara.

Kalau begitu, saatnya untuk mengutip!
Mari kita coba "UA '":



Statistik TIDAK kembali, yang diharapkan.

Sekarang "UA ''":



Statistik kembali lagi dan sepertinya injeksi!

Mengapa
Katakanlah instruksi database terlihat seperti ini:

SELECT * FROM countries WHERE country_code = `UA`; 

Jika Anda mengirim UA ', maka instruksi basis data adalah:

 SELECT * FROM countries WHERE country_code = `UA``; 

Melihat penawaran tambahan? Dan ini berarti instruksi tersebut tidak valid.
Menurut sintaks SQL, kueri di bawah ini benar-benar valid (tidak ada kutipan tambahan):

 SELECT * FROM countries WHERE country_code = `UA```; 

Harap perhatikan bahwa kami sedang berhadapan dengan array countryFilter [] . Saya berasumsi bahwa jika kita menduplikasi parameter countryFilter [] dalam permintaan beberapa kali, maka semua nilai yang kami kirim akan digabungkan dalam permintaan SQL dengan cara ini:

 'value1', 'value2', 'value3' 

Kami memeriksa dan memastikan:



Faktanya, kami meminta statistik dari tiga negara dari basis data:

 `UA`, `,` ,`RU` 

Sintaksnya benar - statistik kembali :)

Aplikasi Web Firewall Bypass

Server uap bersembunyi di balik Akamai WAF. Sisipan memalukan ini melekat pada roda peretas yang baik (dan tidak demikian). Namun, saya bisa mengatasinya dengan menggabungkan nilai-nilai array menjadi satu query (apa yang saya jelaskan di atas) dan berkomentar. Pertama, pastikan yang terakhir tersedia:

 ?countryFilter[]=UA`/*&countryFilter[]=*/,`RU 

Permintaan ini valid, jadi ada komentar di bermacam-macam kami.
Kami memiliki beberapa opsi sintaks, database lokal untuk menguji payload, karakter komentar, dan jumlah kutipan tak terbatas untuk semua penyandian, serta skrip yang ditulis sendiri pada python, dokumentasi untuk semua database, instruksi tentang cara mem-bypass firewall, wikipedia, dan antichest. Bukannya itu adalah cadangan yang diperlukan untuk promosi injeksi, tetapi karena mulai merusak basis data, sulit untuk berhenti ...
WAF memblokir permintaan ketika menemukan fungsi di dalamnya. Tahukah Anda bahwa DB_NAME / ** / () adalah panggilan fungsi yang valid? Firewall juga tahu dan memblokir. Namun, berkat fitur ini, kami dapat membagi panggilan fungsi menjadi dua parameter!

 ?countryFilter[]=UA',DB_NAME/*&countryFilter[]=*/(),'RU 

Kami mengirim permintaan dengan DB_NAME / * tetap * / () - WAF tidak mengerti apa-apa, tetapi database berhasil memproses instruksi semacam itu.

Mengambil nilai dari database

Jadi, contoh untuk mendapatkan panjang nilai DB_NAME ():

 https://partner.steampowered.com/report_xml.php?query=QuerySteamHistory&countryFilter[]=',(SELECT/*&countryFilter[]=*/CASE/**/WHEN/*&countryFilter[]=*/(len(DB_NAME/*&countryFilter[]=*/())/*&countryFilter[]=*/=1)/**/THEN/**/'UA'/**/ELSE/*&countryFilter[]=*/'qwerty'/**/END),' 

Dalam SQL:

 SELECT CASE WHEN (len(DB_NAME())= 1) THEN 'UA' ELSE 'qwerty' END 

Secara manusiawi:

   DB_NAME()  "1",   β€œUA”,   β€œqwerty”. 

Ini berarti bahwa jika perbandingannya benar, maka sebagai imbalannya kami mendapatkan statistik untuk negara "UA". Tidak sulit untuk menebak bahwa jika nilai mulai dari 1 hingga tak terbatas, cepat atau lambat kita akan menemukan yang benar.

Dengan cara yang sama, Anda dapat beralih di atas nilai teks:

    DB_NAME()  β€œa”,  "UA",  "qwerty". 

Biasanya, fungsi "substring" digunakan untuk mendapatkan karakter ke-N, tetapi WAF dengan keras membloknya. Di sini kombinasi datang untuk menyelamatkan:

 right(left(system_user,N),1) 

Bagaimana cara kerjanya? Kami mendapatkan N karakter dari nilai system_user dari mana kami mengambil yang terakhir.
Bayangkan system_user = "steam". Beginilah tampilan karakter ketiga:

 left(system_user,3) = ste right(β€œste”,1) = e 

Dengan skrip sederhana, proses ini otomatis dan saya mendapatkan hostname, system_user, versi dan nama-nama semua database. Informasi ini lebih dari cukup (yang terakhir bahkan berlebihan, tetapi menarik) untuk menunjukkan kekritisan.

Setelah 5 jam, kerentanan diperbaiki, tetapi status triaged ditetapkan untuk itu setelah 8 jam dan, sialnya, bagi saya itu sangat sulit 3 jam di mana otak saya berhasil melewati tahapan dari penolakan hingga penerimaan.

Penjelasan paranoia
Karena kerentanan tidak ditetapkan diterima, saya percaya bahwa saluran belum mencapai laporan saya. Tetapi mereka memperbaiki bug, yang berarti mereka bisa mendaftarkannya sebelum saya.

2. Memperoleh semua kunci untuk game apa pun


Di antarmuka mitra Steam, ada fungsi untuk membuat kunci game.
Anda dapat mengunduh kumpulan kunci yang dihasilkan menggunakan permintaan:

 https://partner.steamgames.com/partnercdkeys/assignkeys/ &sessionid=xxxxxxxxxxxxx&keyid=123456&sourceAccount=xxxxxxxxx&appid=xxxxxx&keycount=1&generateButton=Download 

Dalam permintaan ini, parameter keyid adalah id dari set kunci, dan keycount adalah jumlah kunci yang harus diperoleh dari set ini.

Tentu saja, tangan saya langsung mengulurkan tangan untuk mengemudi di keyid yang berbeda, tetapi kesalahan menunggu saya: " Tidak dapat menghasilkan kunci CD: Tidak ada tugas untuk pengguna. ". Ternyata tidak semuanya sederhana, dan Steam memeriksa apakah saya memiliki set kunci yang diminta. Bagaimana saya bisa melewati tes ini? Perhatian ...

 keycount=0 

File dihasilkan dengan 36.000 kunci ke game Portal 2. Wow.
Hanya dalam satu set adalah jumlah kunci ini. Dan semua set saat ini lebih dari 430.000. Jadi, memilah- milah nilai keyid, saya adalah penyerang potensial yang bisa mengunduh semua kunci yang pernah dihasilkan oleh pengembang game Steam.

Kesimpulan


  • Sistem WAF yang mahal dari perusahaan-perusahaan top jauh dari menjamin keamanan aplikasi web Anda.
  • Jika Anda seorang pemburu bug, maka cobalah menembus sedalam mungkin. Semakin sedikit pengguna memiliki akses ke antarmuka, semakin besar kemungkinan untuk menemukan kerentanan di antarmuka itu.
  • Pengembang dan pemilik bisnis, tidak ada aplikasi yang benar-benar aman! Tapi kamu tunggu. Semoga suasana hatinya menyenangkan!

Tapi serius
Lakukan pentest, bayar kerentanan, pikirkan strategis.

Source: https://habr.com/ru/post/id421215/


All Articles