phpiptablescaptivenetwork

Unexpected behaviour when running iptables from php


I'm running the following code from within php

$ipAddress=$_SERVER['REMOTE_ADDR'];
$mac = `arp -an |grep $ipAddress | awk '{print $4}'`;
$c = "sudo iptables -t mangle -I internet 1 -m mac --mac-source $mac -j RETURN";
shell_exec($c);

after it, output of

#iptables -L -v -t mangle  

 pkts bytes target     prot opt in     out     source               destination         
  215 18676            all  --  *      *       0.0.0.0/0            0.0.0.0/0            MAC D0:17:C2:48:1E:4F
   26  1717 RETURN     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 RETURN     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
  340 26189 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK set 0x63

note that there is no RETURN in the target

If I run the same command from bash shell as sudo, the output is

$ sudo iptables -t mangle -I internet -m mac --mac-source D0:17:C2:48:1E:4F -j RETURN

pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0            MAC D0:17:C2:48:1E:4F
    0     0 RETURN     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
    0     0 RETURN     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
    0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK set 0x63

Observe that there is a RETURN in the target

I have modified sudoers with visudo to enable php to run the said command as root

I also tried system(), exec and using backtick operator in php. But, all is the same.

I could not understand why this happens and a remedy to it.


Solution

  • The string assigned to $mac ends with a newline characters, thus breaking the iptables command. Removing the newline, for example by using explode instead of awk, should fix this:

    $ipArp = `arp -an | grep $ipAddress`;
    $mac = explode(' ', $ipArp)[3];
    

    I'd like to add that this kind of script scares me a little. Blindly passing values to a shell command can have very bad consequences. I don't think this particular script is exploitable, but giving sudo permissions to PHP is not a good idea from a security point of view.