Pemindaian API dengan Burp Suite

Pemindaian API dengan Burp Suite

Baik Burp Suite Professional dan Burp Suite Enterprise Edition berisi Burp Scanner - memungkinkan pengguna memindai kerentanan aplikasi web dengan mudah. 

Entri blog lainnya membahas bagaimana perayap Burp Scanner mengikuti tautan di laman web untuk menemukan permukaan serangan yang mungkin mengekspos kerentanan keamanan. Dalam posting ini kita membahas bagaimana perayap diadaptasi untuk bekerja dengan titik akhir API daripada halaman web.

Sebagian besar dari kita sering menggunakan aplikasi web untuk hal-hal sehari-hari seperti berita, hiburan, belanja, dan sebagainya. Halaman web ini ditujukan untuk pengguna akhir biasa. 

Namun web juga digunakan untuk menyediakan API (Antarmuka Pemrograman Aplikasi), yang memungkinkan aplikasi yang berbeda untuk berbicara satu sama lain. Ada banyak API yang ditawarkan oleh berbagai organisasi. Beberapa di antaranya adalah API publik yang ditawarkan sebagai layanan untuk pelanggan yang membayar, tetapi API juga digunakan untuk menyediakan layanan mikro secara internal dalam organisasi, memungkinkan tim yang berbeda di dalam perusahaan untuk mengintegrasikan modul terpisah mereka bersama-sama. 

API ini menyediakan berbagai permukaan serangan tambahan untuk pengguna jahat, dan seringkali ini diabaikan oleh tim keamanan karena mereka hanya digunakan oleh pengembang dan mesin lain .

Contoh API


Sebagai contoh, pertimbangkan sebuah perusahaan seperti ZapMap yang mengembangkan situs web yang memungkinkan pengguna menemukan titik pengisian daya terdekat untuk mobil listrik. Perusahaan ingin menunjukkan titik pengisian di peta. 

Untuk melakukan ini, mereka dapat menggunakan API pemetaan (misalnya Google Maps API) untuk menghasilkan peta dengan titik muatan yang ditandai di atasnya. Dalam kasus ini, akan ada beberapa langkah penyiapan awal yang diperlukan, karena mereka memerlukan kunci API untuk menggunakan layanan. Tetapi kemudian untuk mendapatkan data peta, mereka kemudian hanya akan mengirim permintaan web (HTTP) dengan cara yang sama seperti yang dilakukan browser web kita saat meminta halaman web. Permintaan tersebut akan berisi informasi seperti area peta mana yang diperlukan, bersama dengan lokasi stasiun pengisian. Kemudian sebagai tanggapan.


Standar OpenAPI

API biasanya didokumentasikan sehingga pengguna mengetahui kapabilitas apa yang tersedia dan sintaks apa yang diperlukan untuk endpoint API yang berbeda (metode antarmuka yang dapat diakses oleh pengguna API). Perkembangan yang relatif baru adalah standar OpenAPI untuk mendefinisikan titik akhir API. 

Standar ini mendefinisikan struktur YAML atau JSON yang digunakan untuk menentukan titik akhir dengan cara standar, termasuk server yang menghosting API, dan untuk setiap titik akhir spesifikasi parameter yang diperlukan dan opsional, jenis kembalian dan seterusnya. 

Dokumen-dokumen ini dirancang agar dapat dibaca oleh manusia dan mesin. Fakta bahwa ini dapat dibaca mesin berarti bahwa pengembang dapat dengan mudah mengurai dokumen OpenAPI dalam bahasa pemrograman yang mereka pilih (misalnya Java / Python) dan langsung memiliki antarmuka yang siap digunakan.

Berikut adalah contoh spesifikasi OpenAPI untuk titik akhir:

paths:
    /users/{userId}:
       get:
         summary: Returns a user by ID.
         parameters:
             name: userId
             in: path
             required: true
             description: The user id
             schema:
                 type: integer
                 format: int64
                 minimum: 1
         responses:
             '200':
                 description: OK

Endpoint terletak di / users, dan memiliki satu parameter userId, yang merupakan parameter jalur berjenis "integer", dengan nilai minimum "1". Jadi dari spesifikasi ini, permintaan berikut valid untuk titik akhir ini:

GET /users/1 HTTP/1.1
GET /users/2 HTTP/1.1
GET /users/1932899 HTTP/1.1

Menulis ulang Burp Scanner untuk bekerja dengan OpenAPI

Kembali ke Burp Suite dan keamanan aplikasi web , titik akhir API memberikan permukaan serangan potensial tambahan untuk peretas jahat. Jadi jika kami menemukan dokumen OpenAPI, kami dapat secara otomatis menemukan titik akhir yang terekspos dan perayap dapat menambahkan titik akhir ini ke daftar item yang dikirimkan ke pemindai.

Pada prinsipnya, ini terdengar mudah, tetapi menghadirkan sejumlah tantangan teknis selama implementasi.

Penjelasan singkat tentang crawler

Pertama saya akan memberikan penjelasan singkat tentang bagaimana crawler bekerja dengan halaman web HTML biasa. Secara sederhana, kami menganggap setiap halaman sebagai sekumpulan link ke halaman lain. Perayap mengunjungi setiap tautan ini secara luas-pertama, menambahkan setiap halaman baru yang ditemukan sebagai kemungkinan permukaan serangan untuk pemindai. 

Secara internal, kami mengabstraksi detail berbagai jenis tautan dengan menggunakan metafora orang yang menelusuri melalui labirin. Alih-alih memikirkan halaman dan tautan, kami berbicara tentang Kamar dan Pintu . Kita dapat menganggap sebuah Ruangan kira-kira sesuai dengan sebuah halaman web dengan satu set Pintu masuk, yaitu tautan ke Ruangan lain (halaman).

Satu keuntungan menggunakan abstraksi ini adalah kita tidak terjebak dalam detail halus dari semua elemen dan teknologi HTML yang mungkin berbeda. Misalnya, alih-alih tautan pada halaman, kami mungkin memiliki formulir (misalnya formulir masuk atau pendaftaran). Ini memiliki beberapa masukan yang harus diisi pengguna sebelum mengirimkan untuk pindah ke halaman lain. 

Sekarang kita dapat menganggap formulir sebagai jenis Pintu Masuk lainnya. Jadi kita mungkin memiliki Pintu Jangkar yang mewakili tautan normal (jangkar menjadi istilah yang digunakan untuk menunjukkan tautan dalam HTML). Kemudian kita bisa memiliki Bentuk Pintu yang merepresentasikan Pintu keluar masuk jenis lain yang membutuhkan banyak input pengguna sebelum pindah ke ruangan lain. Ini memiliki keuntungan bahwa kami kemudian dapat menggunakan kembali semua algoritme yang ada untuk menavigasi melalui Kamar dan Pintu tanpa menulis ulang semuanya untuk bekerja dengan formulir serta tautan.

Namun formulir menimbulkan kerumitan bagi perayap: apa yang kita masukkan ke dalam formulir? Dalam terminologi perayap kami, kami menganggap bidang formulir sebagai Kunci yang perlu kami sediakan untuk melewati Pintu. Kami menggunakan sejumlah strategi berbeda untuk membuat Kunci untuk bentuk Doorway, yang sebagian bergantung pada apa yang telah dikonfigurasi pengguna. 

Kami memiliki konsep Tebak Kunci, yang memberikan nilai wajar untuk setiap bidang berdasarkan nama bidang formulir. Jadi untuk bidang email kami akan membuat alamat email palsu, dan demikian pula untuk negara, Nomor telepon, dan sebagainya. Jenis Kunci lainnya adalah Kunci Canary - ini adalah string acak yang kami gunakan dan simpan untuk tujuan tertentu - kami ingin melihat apakah Kunci Canary yang kami masukkan muncul di Ruangan (halaman) lain. Ini mungkin menunjukkan kemungkinan kerentanan karena ini menunjukkan bahwa input mentah yang dimasukkan oleh pengguna tercermin di halaman lain, memungkinkan pengguna jahat untuk menyuntikkan kode berbahaya ke dalam formulir dan membuatnya mengambil tindakan di tempat lain, seperti dalam serangan XSS (lihat kami halaman tentang serangan XSS untuk info lebih lanjut tentang ini). Dan akhirnya kami memiliki Kunci Kredensial. Ini adalah detail yang diberikan oleh pengguna untuk memungkinkan crawler melanjutkan ke area terlarang situs web, misalnya detail login.

Merayapi dokumen OpenAPI

Saat dihadapkan pada masalah perayapan titik akhir yang ditentukan dalam dokumen OpenAPI, pendekatan pertama kami adalah mempertimbangkan setiap titik akhir dengan cara yang mirip dengan formulir HTML. Lagi pula, setiap titik akhir menentukan daftar parameter yang diperlukan (dan opsional), dengan cara yang hampir sama seperti formulir HTML. Spesifikasi OpenAPI memungkinkan pencacahan sebagai parameter (yaitu daftar opsi terbatas), yang sesuai dengan menu drop-down atau tombol radio yang ditemukan dalam bentuk HTML.

Meskipun kami membuat beberapa kemajuan awal dengan model ini, kami segera menemui masalah. Terlepas dari kesamaan antara spesifikasi OpenAPI untuk titik akhir dan formulir HTML, ada perbedaan penting dalam hal detail spesifik.

Misalnya formulir HTML dapat memiliki kotak centang masukan yang dicentang atau tidak dicentang. Jika pengguna tidak mencentang kotak centang maka parameter itu tidak dikirim dalam permintaan saat formulir dikirimkan. Namun bidang Boolean di OpenAPI memiliki perilaku yang berbeda. Dalam kasus ini jika parameter tidak diberikan maka nilai default yang diberikan adalah salah. Ini dapat mengakibatkan perilaku yang berbeda dari API. Ada perbedaan serupa di tipe data lain seperti bidang angka.

Jadi kami mulai bekerja dalam membuat jalan pintas baru terlepas dari penanganan formulir HTML kami, memungkinkan kami untuk mengikuti spesifikasi OpenAPI tanpa mencoba menyesuaikan dengan pendekatan formulir HTML lama.

Di sini salah satu tantangan terbesar yang kami hadapi adalah mengirimkan badan permintaan JSON, yang diperlukan oleh beberapa titik akhir API. Ini adalah fungsi yang sepenuhnya baru untuk crawler - kode kami yang ada memiliki fasilitas untuk mengirimkan parameter dalam badan permintaan POST untuk formulir HTML (dengan jenis application/x-www-form-urlencoded dan multipart/form-data), tetapi kemampuan untuk mengirimkan badan permintaan JSON adalah fitur baru. Ini adalah fitur baru yang kuat karena membuka banyak permukaan serangan untuk titik akhir REST API yang memerlukan masukan JSON.

Memutuskan parameter apa yang akan dikirim dalam perayapan

Dengan adanya titik akhir tertentu, sangat mungkin untuk memiliki sejumlah besar kemungkinan parameter yang dapat dikirimkan. Misalnya, parameter String terbuka tanpa batasan dapat memiliki jumlah input valid yang mungkin tidak terbatas. Jadi, perayap tidak mungkin mencoba mencoba semua kombinasi parameter. Namun, pada saat yang sama kami ingin crawler mendapatkan cakupan yang baik dengan mencoba sejumlah kombinasi parameter yang mungkin untuk mengekspos kemungkinan permukaan serangan.

Kami telah memutuskan kombinasi berikut:

  • Setiap kombinasi server (selama masih dalam cakupan) dan metode jalur (GET, POST, dll.). Jadi jika kita memiliki tiga server dan titik akhir dengan metode GET dan POST, ini akan menjadi 3 x 2 = 6 total lokasi titik akhir.
  • Jika parameter opsional ditentukan, crawler akan mengirim setidaknya dua permintaan ke titik akhir tersebut: satu permintaan yang hanya berisi parameter wajib dan permintaan lainnya yang menyertakan semua parameter opsional juga.
  • Dalam kasus jenis enumerasi , crawler akan mengirimkan permintaan terpisah untuk setiap nilai parameter yang diizinkan.
  • Dalam kasus nilai numerik kami menggunakan nilai maksimum dan minimum seperti yang ditentukan.
  • Jika kumpulan contoh parameter disediakan, kami menggunakan contoh terakhir yang disediakan.

Jika parameter tidak ditentukan dengan salah satu cara yang tercantum di atas, kami kembali menggunakan Guess dan Canary Keys seperti yang kami lakukan untuk formulir HTML.

Contoh permintaan crawler untuk spesifikasi OpenAPI

Cuplikan ini menunjukkan spesifikasi untuk titik akhir GET dengan dua rangkaian contoh untuk parameter:

"paths":{

  "/api": {

    "get": {

      "summary": "Summary of this API endpoint",

      "requestBody": {

        "required": true,

        "content": {

          "application/json": {

            "schema": {

              "type": "object",

              "properties": {

                "stringField": {

                  "type": "string"

                },

                "numberField": {

                  "type": "number"

                }

              }

            },

            "examples": {

              "example1": {

                "value": {

                  "stringField": "example1",

                  "numberField": 1.5

                }

              },

              "example2": {

                "value":

                {

                  "stringField": "example2",

                  "numberField": 2.5

                }

              }

Dalam kasus ini, crawler akan menggunakan contoh terakhir, yaitu "example2", untuk mengirim permintaan berikut (menghilangkan beberapa header HTTP):

GET /scans HTTP/1.1

{"stringField":"example2","numberField":2.5}

Contoh lain dengan enum:

"paths": {

  "/stringParameter/{stringParameter}":{

    "get": {

      "summary": "Summary of this API endpoint",

      "tags": [

        "scans"

      ],

      "parameters": [

        {

          "name": "stringParameter", 

          "in": "path",

          "required": true,

          "schema": {

            "type": "string",

            "enum": [

              "enum1",

              "enum2"

            ]

          }

        }

      ]

   }

}

Dalam hal ini Perayap akan mengirim permintaan berikut, menggunakan pencacahan parameter string dan nilai minimum dan maksimum untuk parameter angka:

GET /stringParameter/enum1 HTTP/1.1

GET /stringParameter/enum2 HTTP/1.1

Titik akhir ini kemudian akan dikirim ke pemindai sebagai tujuan pemindaian.

Kesimpulan

Kami telah memperkenalkan fitur pemindaian API sebagai dasar untuk mencakup area permintaan yang terus berkembang ini. 

Py

Subscribe to our YouTube Channel