mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-23 13:11:02 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,232 @@
|
||||
---
|
||||
name: performing-thick-client-application-penetration-test
|
||||
description: Conduct a thick client application penetration test to identify insecure local storage, hardcoded credentials, DLL hijacking, memory manipulation, and insecure API communication in desktop applications using dnSpy, Procmon, and Burp Suite.
|
||||
domain: cybersecurity
|
||||
subdomain: penetration-testing
|
||||
tags: [thick-client, desktop-application, dnSpy, Procmon, DLL-hijacking, binary-analysis, API-interception]
|
||||
version: "1.0"
|
||||
author: mahipal
|
||||
license: MIT
|
||||
---
|
||||
|
||||
# Performing Thick Client Application Penetration Test
|
||||
|
||||
## Overview
|
||||
|
||||
Thick client (fat client) penetration testing assesses the security of desktop applications that run locally on user machines and communicate with backend servers. Unlike web applications, thick clients present a broader attack surface including local file storage, binary analysis, memory manipulation, DLL injection, process interception, and client-server communication. Common targets include banking applications, ERP clients (SAP GUI), trading platforms, healthcare systems, and legacy enterprise software.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Application installer and valid credentials
|
||||
- Windows/Linux test machine (isolated)
|
||||
- Tools: dnSpy, Procmon, Process Hacker, Wireshark, Burp Suite, Echo Mirage, Fiddler, IDA Pro/Ghidra
|
||||
- Administrative access to test machine
|
||||
|
||||
## Phase 1 — Information Gathering
|
||||
|
||||
### Static Analysis
|
||||
|
||||
```powershell
|
||||
# Identify application technology
|
||||
# Check file properties, signatures, framework (.NET, Java, C++, Electron)
|
||||
file application.exe
|
||||
# .NET -> dnSpy, JetBrains dotPeek
|
||||
# Java -> JD-GUI, JADX
|
||||
# C/C++ -> Ghidra, IDA Pro
|
||||
# Electron -> extract asar archive
|
||||
|
||||
# Check for .NET framework
|
||||
Get-ChildItem -Path "C:\Program Files\TargetApp" -Recurse -Filter "*.dll" |
|
||||
ForEach-Object { [System.Reflection.AssemblyName]::GetAssemblyName($_.FullName).FullName }
|
||||
|
||||
# Strings analysis
|
||||
strings application.exe | findstr -i "password\|secret\|api\|key\|token\|jdbc\|connection"
|
||||
|
||||
# Check for hardcoded credentials
|
||||
strings application.exe | findstr -i "username\|user=\|pass=\|pwd=\|admin"
|
||||
|
||||
# Review configuration files
|
||||
type "C:\Program Files\TargetApp\app.config"
|
||||
type "C:\Program Files\TargetApp\settings.xml"
|
||||
type "%APPDATA%\TargetApp\config.json"
|
||||
|
||||
# Check for certificate pinning
|
||||
strings application.exe | findstr -i "cert\|pin\|ssl\|tls"
|
||||
```
|
||||
|
||||
### .NET Decompilation with dnSpy
|
||||
|
||||
```
|
||||
# Open application in dnSpy
|
||||
1. Launch dnSpy
|
||||
2. File > Open > Select application.exe and DLLs
|
||||
3. Search for:
|
||||
- "password", "secret", "connectionString"
|
||||
- Authentication methods
|
||||
- Encryption/decryption functions
|
||||
- API endpoints and keys
|
||||
- License validation logic
|
||||
|
||||
# Look for:
|
||||
- Hardcoded credentials in source
|
||||
- Insecure encryption (DES, MD5, base64 "encryption")
|
||||
- SQL queries (potential injection)
|
||||
- Disabled certificate validation
|
||||
- Debug/verbose logging with sensitive data
|
||||
```
|
||||
|
||||
## Phase 2 — Dynamic Analysis
|
||||
|
||||
### Process Monitoring
|
||||
|
||||
```powershell
|
||||
# Monitor file system activity with Procmon
|
||||
# Filters:
|
||||
# Process Name = application.exe
|
||||
# Operation = CreateFile, WriteFile, ReadFile, RegSetValue
|
||||
|
||||
# Key observations:
|
||||
# - Where does the app store data? (AppData, temp, registry)
|
||||
# - Does it write credentials to disk?
|
||||
# - Does it create temporary files with sensitive data?
|
||||
# - What registry keys does it access?
|
||||
|
||||
# Monitor with Process Hacker
|
||||
# Check: loaded DLLs, network connections, handles, tokens
|
||||
|
||||
# Monitor network traffic
|
||||
# Wireshark filter: ip.addr == <server_ip>
|
||||
# Check for: unencrypted credentials, API keys, tokens
|
||||
```
|
||||
|
||||
### Traffic Interception
|
||||
|
||||
```bash
|
||||
# Intercept HTTP/HTTPS traffic with Burp Suite
|
||||
# Configure system proxy: 127.0.0.1:8080
|
||||
# Install Burp CA certificate in Windows certificate store
|
||||
|
||||
# For non-HTTP protocols, use Echo Mirage
|
||||
# Inject into process and intercept TCP/UDP traffic
|
||||
|
||||
# For HTTPS with certificate pinning:
|
||||
# Method 1: Patch certificate validation in dnSpy
|
||||
# Method 2: Use Frida to hook SSL validation
|
||||
frida -l bypass_ssl_pinning.js -f application.exe
|
||||
|
||||
# Fiddler for .NET applications
|
||||
# Enable HTTPS decryption
|
||||
# Monitor API calls, request/response bodies
|
||||
```
|
||||
|
||||
## Phase 3 — Vulnerability Testing
|
||||
|
||||
### Authentication Bypass
|
||||
|
||||
```
|
||||
# Test local authentication bypass
|
||||
1. Open dnSpy, find authentication method
|
||||
2. Set breakpoint on credential validation
|
||||
3. Modify return value to bypass (Debug > Set Next Statement)
|
||||
4. Or: Patch binary to always return true
|
||||
|
||||
# Test for credential storage
|
||||
# Check: registry, config files, SQLite databases, Windows Credential Manager
|
||||
reg query "HKCU\Software\TargetApp" /s
|
||||
type "%APPDATA%\TargetApp\user.db"
|
||||
# SQLite: sqlite3 user.db ".dump"
|
||||
```
|
||||
|
||||
### DLL Hijacking
|
||||
|
||||
```powershell
|
||||
# Identify DLL search order vulnerability
|
||||
# Use Procmon to find DLLs loaded from writable paths
|
||||
# Filter: Result = NAME NOT FOUND, Path ends with .dll
|
||||
|
||||
# Create malicious DLL
|
||||
# msfvenom -p windows/exec CMD=calc.exe -f dll -o hijacked.dll
|
||||
# Place in application directory or writable PATH directory
|
||||
|
||||
# DLL sideloading
|
||||
# If app loads DLL without full path:
|
||||
# 1. Create DLL with same exports
|
||||
# 2. Place in app directory
|
||||
# 3. DLL loads before legitimate version
|
||||
```
|
||||
|
||||
### Memory Analysis
|
||||
|
||||
```powershell
|
||||
# Dump process memory
|
||||
# Use Process Hacker > Process > Properties > Memory
|
||||
# Search for plaintext credentials, tokens, session IDs
|
||||
|
||||
# Strings from memory dump
|
||||
strings process_dump.dmp | findstr -i "password\|token\|session\|bearer"
|
||||
|
||||
# Modify memory values (license bypass, privilege escalation)
|
||||
# Use Cheat Engine or x64dbg to:
|
||||
# 1. Find memory address of authorization variable
|
||||
# 2. Modify value (e.g., isAdmin = 0 -> isAdmin = 1)
|
||||
```
|
||||
|
||||
### Input Validation
|
||||
|
||||
```
|
||||
# SQL Injection in local database
|
||||
# Test input fields with: ' OR 1=1--
|
||||
# If app uses local SQLite/SQL Server Express
|
||||
|
||||
# Command injection
|
||||
# Test fields that interact with OS:
|
||||
# File paths: ..\..\..\..\windows\system32\cmd.exe
|
||||
# Print/export: | calc.exe
|
||||
|
||||
# Buffer overflow
|
||||
# Send oversized input to text fields
|
||||
# Monitor with x64dbg for crashes
|
||||
# Check for SEH-based or stack-based overflows
|
||||
```
|
||||
|
||||
## Phase 4 — API Security Testing
|
||||
|
||||
```bash
|
||||
# Capture API calls from thick client
|
||||
# In Burp Suite, analyze:
|
||||
|
||||
# IDOR (Insecure Direct Object Reference)
|
||||
# Change user IDs in requests to access other users' data
|
||||
# GET /api/users/1001 -> GET /api/users/1002
|
||||
|
||||
# Authorization bypass
|
||||
# Remove or modify JWT tokens
|
||||
# Test role escalation: change role claim from "user" to "admin"
|
||||
|
||||
# Mass assignment
|
||||
# Add additional parameters to API requests
|
||||
# POST /api/profile {"name": "test", "isAdmin": true}
|
||||
|
||||
# Rate limiting
|
||||
# Test for brute-force protection on login API
|
||||
# Test for account lockout bypass
|
||||
```
|
||||
|
||||
## Findings Template
|
||||
|
||||
| Finding | Severity | CVSS | Remediation |
|
||||
|---------|----------|------|-------------|
|
||||
| Hardcoded database credentials in binary | Critical | 9.1 | Use secure credential storage (DPAPI, vault) |
|
||||
| DLL hijacking via writable app directory | High | 7.8 | Use full DLL paths, validate DLL signatures |
|
||||
| Plaintext credentials in memory | High | 7.5 | Zero memory after use, use SecureString |
|
||||
| No certificate pinning | Medium | 6.5 | Implement certificate pinning |
|
||||
| Local SQLite DB with cleartext passwords | Critical | 9.0 | Use bcrypt/Argon2 hashing |
|
||||
| Disabled SSL validation in code | High | 8.1 | Enable proper certificate validation |
|
||||
|
||||
## References
|
||||
|
||||
- dnSpy: https://github.com/dnSpy/dnSpy
|
||||
- Procmon: https://learn.microsoft.com/en-us/sysinternals/downloads/procmon
|
||||
- OWASP Thick Client Testing Guide: https://owasp.org/www-project-thick-client-top-10/
|
||||
- Ghidra: https://ghidra-sre.org/
|
||||
- Echo Mirage: https://sourceforge.net/projects/echomirage/
|
||||
@@ -0,0 +1,24 @@
|
||||
# Thick Client Penetration Test — Report Template
|
||||
|
||||
## Document Control
|
||||
| Field | Value |
|
||||
|-------|-------|
|
||||
| Application | [Name and version] |
|
||||
| Technology | [.NET / Java / C++ / Electron] |
|
||||
| Platform | [Windows / macOS / Linux] |
|
||||
| Period | [Start] — [End] |
|
||||
|
||||
## Executive Summary
|
||||
[Overview of thick client security posture, key vulnerabilities found in binary, storage, and communication]
|
||||
|
||||
## Findings
|
||||
### Finding [N]: [Title]
|
||||
| Attribute | Detail |
|
||||
|-----------|--------|
|
||||
| Category | [Binary / Storage / Communication / Authentication] |
|
||||
| Severity | [Level] |
|
||||
| CVSS | [Score] |
|
||||
| Remediation | [Fix] |
|
||||
|
||||
## Recommendations
|
||||
1. [Priority recommendations for thick client hardening]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Standards — Thick Client Application Penetration Testing
|
||||
|
||||
## Frameworks
|
||||
- OWASP Thick Client Top 10: https://owasp.org/www-project-thick-client-top-10/
|
||||
- PTES Application Security: http://www.pentest-standard.org/
|
||||
- CWE Top 25: https://cwe.mitre.org/top25/
|
||||
|
||||
## OWASP Thick Client Top 10
|
||||
1. Improper Platform Usage
|
||||
2. Insecure Data Storage
|
||||
3. Insecure Communication
|
||||
4. Insecure Authentication
|
||||
5. Insufficient Cryptography
|
||||
6. Insecure Authorization
|
||||
7. Client Code Quality
|
||||
8. Code Tampering
|
||||
9. Reverse Engineering
|
||||
10. Extraneous Functionality
|
||||
@@ -0,0 +1,26 @@
|
||||
# Workflows — Thick Client Penetration Testing
|
||||
|
||||
## Attack Flow
|
||||
```
|
||||
Application Binary
|
||||
│
|
||||
├── Static Analysis (dnSpy/Ghidra/JD-GUI)
|
||||
│ ├── Hardcoded credentials
|
||||
│ ├── Encryption analysis
|
||||
│ └── API endpoint discovery
|
||||
│
|
||||
├── Dynamic Analysis (Procmon/Process Hacker)
|
||||
│ ├── File system monitoring
|
||||
│ ├── Registry access tracking
|
||||
│ └── Memory inspection
|
||||
│
|
||||
├── Traffic Interception (Burp/Fiddler/Echo Mirage)
|
||||
│ ├── API security testing
|
||||
│ ├── Certificate pinning bypass
|
||||
│ └── Authentication token analysis
|
||||
│
|
||||
└── Binary Exploitation
|
||||
├── DLL hijacking
|
||||
├── Memory manipulation
|
||||
└── Binary patching
|
||||
```
|
||||
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Thick Client Penetration Test — Static Analysis Helper
|
||||
|
||||
Performs basic static analysis on thick client applications: string extraction,
|
||||
config file scanning, and DLL dependency analysis.
|
||||
|
||||
Usage:
|
||||
python process.py --app-dir "C:/Program Files/TargetApp" --output ./results
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
import argparse
|
||||
import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
SENSITIVE_PATTERNS = {
|
||||
"password": re.compile(r'(?i)(password|passwd|pwd)\s*[=:]\s*["\']?([^\s"\']+)'),
|
||||
"api_key": re.compile(r'(?i)(api[_-]?key|apikey)\s*[=:]\s*["\']?([^\s"\']+)'),
|
||||
"connection_string": re.compile(r'(?i)(connection[_-]?string|jdbc:)\s*[=:]\s*["\']?([^\s"\']+)'),
|
||||
"secret": re.compile(r'(?i)(secret|token)\s*[=:]\s*["\']?([^\s"\']+)'),
|
||||
"url_with_creds": re.compile(r'https?://[^:]+:[^@]+@[\w.]+'),
|
||||
"hardcoded_ip": re.compile(r'\b(?:10|172\.(?:1[6-9]|2\d|3[01])|192\.168)\.\d{1,3}\.\d{1,3}\b'),
|
||||
}
|
||||
|
||||
|
||||
def extract_strings(filepath: str, min_length: int = 8) -> list[str]:
|
||||
"""Extract printable strings from a binary file."""
|
||||
strings = []
|
||||
try:
|
||||
with open(filepath, "rb") as f:
|
||||
data = f.read()
|
||||
|
||||
current = []
|
||||
for byte in data:
|
||||
if 32 <= byte <= 126:
|
||||
current.append(chr(byte))
|
||||
else:
|
||||
if len(current) >= min_length:
|
||||
strings.append("".join(current))
|
||||
current = []
|
||||
if len(current) >= min_length:
|
||||
strings.append("".join(current))
|
||||
except (PermissionError, OSError):
|
||||
pass
|
||||
return strings
|
||||
|
||||
|
||||
def scan_for_secrets(strings: list[str]) -> list[dict]:
|
||||
"""Scan extracted strings for sensitive patterns."""
|
||||
findings = []
|
||||
for s in strings:
|
||||
for name, pattern in SENSITIVE_PATTERNS.items():
|
||||
match = pattern.search(s)
|
||||
if match:
|
||||
findings.append({
|
||||
"type": name,
|
||||
"match": s[:200],
|
||||
"severity": "High" if name in ("password", "connection_string", "secret") else "Medium"
|
||||
})
|
||||
break
|
||||
return findings
|
||||
|
||||
|
||||
def scan_config_files(app_dir: str) -> list[dict]:
|
||||
"""Scan configuration files for sensitive data."""
|
||||
config_extensions = {".config", ".xml", ".json", ".ini", ".properties", ".yaml", ".yml", ".cfg"}
|
||||
findings = []
|
||||
|
||||
for root, dirs, files in os.walk(app_dir):
|
||||
for filename in files:
|
||||
ext = os.path.splitext(filename)[1].lower()
|
||||
if ext in config_extensions:
|
||||
filepath = os.path.join(root, filename)
|
||||
try:
|
||||
with open(filepath, encoding="utf-8", errors="ignore") as f:
|
||||
content = f.read()
|
||||
for name, pattern in SENSITIVE_PATTERNS.items():
|
||||
matches = pattern.findall(content)
|
||||
for match in matches:
|
||||
findings.append({
|
||||
"file": filepath,
|
||||
"type": name,
|
||||
"match": str(match)[:200],
|
||||
"severity": "High"
|
||||
})
|
||||
except (PermissionError, OSError):
|
||||
continue
|
||||
return findings
|
||||
|
||||
|
||||
def analyze_dlls(app_dir: str) -> list[dict]:
|
||||
"""Analyze DLL dependencies for potential hijacking."""
|
||||
dlls = []
|
||||
for root, dirs, files in os.walk(app_dir):
|
||||
for filename in files:
|
||||
if filename.lower().endswith(".dll"):
|
||||
filepath = os.path.join(root, filename)
|
||||
dlls.append({
|
||||
"name": filename,
|
||||
"path": filepath,
|
||||
"writable": os.access(filepath, os.W_OK),
|
||||
"size": os.path.getsize(filepath)
|
||||
})
|
||||
|
||||
writable = [d for d in dlls if d["writable"]]
|
||||
return dlls, writable
|
||||
|
||||
|
||||
def generate_report(app_dir: str, string_findings: list[dict],
|
||||
config_findings: list[dict], dll_info: tuple,
|
||||
output_dir: Path) -> str:
|
||||
"""Generate thick client analysis report."""
|
||||
report_file = output_dir / "thick_client_report.md"
|
||||
timestamp = datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
|
||||
all_dlls, writable_dlls = dll_info
|
||||
|
||||
with open(report_file, "w") as f:
|
||||
f.write("# Thick Client Static Analysis Report\n\n")
|
||||
f.write(f"**Application:** {app_dir}\n")
|
||||
f.write(f"**Generated:** {timestamp}\n\n---\n\n")
|
||||
|
||||
f.write("## Binary String Analysis\n\n")
|
||||
if string_findings:
|
||||
f.write(f"Found **{len(string_findings)}** potentially sensitive strings:\n\n")
|
||||
f.write("| Type | Match | Severity |\n|------|-------|----------|\n")
|
||||
for finding in string_findings[:50]:
|
||||
f.write(f"| {finding['type']} | `{finding['match'][:80]}` | {finding['severity']} |\n")
|
||||
else:
|
||||
f.write("No sensitive strings detected in binaries.\n")
|
||||
f.write("\n")
|
||||
|
||||
f.write("## Configuration File Analysis\n\n")
|
||||
if config_findings:
|
||||
f.write(f"Found **{len(config_findings)}** sensitive entries in configs:\n\n")
|
||||
for finding in config_findings[:20]:
|
||||
f.write(f"- **{finding['type']}** in `{finding['file']}`: `{finding['match'][:80]}`\n")
|
||||
else:
|
||||
f.write("No sensitive data found in configuration files.\n")
|
||||
f.write("\n")
|
||||
|
||||
f.write("## DLL Analysis\n\n")
|
||||
f.write(f"Total DLLs: **{len(all_dlls)}**\n")
|
||||
f.write(f"Writable DLLs (potential hijacking): **{len(writable_dlls)}**\n\n")
|
||||
if writable_dlls:
|
||||
f.write("| DLL | Path |\n|-----|------|\n")
|
||||
for dll in writable_dlls:
|
||||
f.write(f"| {dll['name']} | {dll['path']} |\n")
|
||||
f.write("\n")
|
||||
|
||||
print(f"[+] Report: {report_file}")
|
||||
return str(report_file)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Thick Client Static Analysis")
|
||||
parser.add_argument("--app-dir", required=True, help="Application installation directory")
|
||||
parser.add_argument("--output", default="./results")
|
||||
args = parser.parse_args()
|
||||
|
||||
output_dir = Path(args.output)
|
||||
output_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"[*] Scanning {args.app_dir}...")
|
||||
|
||||
# Scan binaries for strings
|
||||
all_findings = []
|
||||
for root, dirs, files in os.walk(args.app_dir):
|
||||
for filename in files:
|
||||
if filename.lower().endswith((".exe", ".dll")):
|
||||
filepath = os.path.join(root, filename)
|
||||
strings = extract_strings(filepath)
|
||||
findings = scan_for_secrets(strings)
|
||||
all_findings.extend(findings)
|
||||
|
||||
# Scan config files
|
||||
config_findings = scan_config_files(args.app_dir)
|
||||
|
||||
# Analyze DLLs
|
||||
dll_info = analyze_dlls(args.app_dir)
|
||||
|
||||
generate_report(args.app_dir, all_findings, config_findings, dll_info, output_dir)
|
||||
print("[+] Analysis complete")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user