来自 php 的 运行 iptables 时的意外行为
Unexpected behaviour when running iptables from php
我运行正在php
中编写以下代码
$ipAddress=$_SERVER['REMOTE_ADDR'];
$mac = `arp -an |grep $ipAddress | awk '{print }'`;
$c = "sudo iptables -t mangle -I internet 1 -m mac --mac-source $mac -j RETURN";
shell_exec($c);
之后,
的输出
#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
注意target中没有RETURN
如果我 运行 来自 bash shell 的相同命令作为 sudo,输出是
$ 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
观察目标
中有一个RETURN
我已经用 visudo 修改了 sudoers 以启用 php 到 运行 作为 root
的上述命令
我还在 php 中尝试了 system()、exec 和使用反引号运算符。但是,都是一样的。
我不明白为什么会发生这种情况以及补救措施。
分配给 $mac
的字符串以换行符结尾,从而破坏了 iptables
命令。删除换行符,例如使用 explode
而不是 awk
,应该可以解决这个问题:
$ipArp = `arp -an | grep $ipAddress`;
$mac = explode(' ', $ipArp)[3];
我想补充一点,这种剧本让我有点害怕。盲目地将值传递给 shell 命令可能会产生非常糟糕的后果。我不认为这个特定的脚本是可利用的,但是从安全的角度来看,给 PHP sudo 权限不是一个好主意。
解决方案:-
我制作了一个脚本 /usr/bin/addtheuser 并只为该脚本授予 sudo 访问 www 数据的权限。
/usr/bin/addtheuser:-
iptables -t mangle -i wlan0 -I internet 1 -m mac --mac-source -j RETURN
当我尝试 运行 来自 php
$c = "sudo /usr/bin/addtheuser ".$mac;
shell_exec($c);
现在它按预期工作了。
我运行正在php
中编写以下代码$ipAddress=$_SERVER['REMOTE_ADDR'];
$mac = `arp -an |grep $ipAddress | awk '{print }'`;
$c = "sudo iptables -t mangle -I internet 1 -m mac --mac-source $mac -j RETURN";
shell_exec($c);
之后,
的输出#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
注意target中没有RETURN
如果我 运行 来自 bash shell 的相同命令作为 sudo,输出是
$ 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
观察目标
中有一个RETURN我已经用 visudo 修改了 sudoers 以启用 php 到 运行 作为 root
的上述命令我还在 php 中尝试了 system()、exec 和使用反引号运算符。但是,都是一样的。
我不明白为什么会发生这种情况以及补救措施。
分配给 $mac
的字符串以换行符结尾,从而破坏了 iptables
命令。删除换行符,例如使用 explode
而不是 awk
,应该可以解决这个问题:
$ipArp = `arp -an | grep $ipAddress`;
$mac = explode(' ', $ipArp)[3];
我想补充一点,这种剧本让我有点害怕。盲目地将值传递给 shell 命令可能会产生非常糟糕的后果。我不认为这个特定的脚本是可利用的,但是从安全的角度来看,给 PHP sudo 权限不是一个好主意。
解决方案:-
我制作了一个脚本 /usr/bin/addtheuser 并只为该脚本授予 sudo 访问 www 数据的权限。
/usr/bin/addtheuser:-
iptables -t mangle -i wlan0 -I internet 1 -m mac --mac-source -j RETURN
当我尝试 运行 来自 php
$c = "sudo /usr/bin/addtheuser ".$mac;
shell_exec($c);
现在它按预期工作了。