为什么执行ping命令时不需要root权限? 怎样让进程具有root权限?
2018-03-02 23:09
495 查看
最近遇到一个问题, 需要让普通用户执行程序时具有root权限, 怎么办呢?
我们来看看ping, 它采用了raw socket, 需要root权限, 但是, 我们平常执行root命令的时候, 没有加sudo啊, 来探个究竟:ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll `which ping`
-rwsr-xr-x 1 root root 44168 May 8 2014 /bin/ping*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 可以看到, 可执行程序二进制文件ping的owner是root, 且是rws的, 注意这个s
APUE说:若文件的所有者是超级用户,而且设置了该文件的设置用户位(suid),然后该程序由一个进程执行时,则该进程具有超级用户特权。
所以, 我们来模仿ping的方式。 程序如下:#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main()
{
printf("main is running\n");
int iSock, nRead, iProtocol;
char buffer[4096] = {0};
char *ethhead, *iphead, *tcphead, *udphead, *icmphead, *p;
if((iSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0)
{
printf("create iSocket error, check root\n"); // 需要root权限
return 1;
}
while(1)
{
nRead = recvfrom(iSock, buffer, 2048, 0, NULL, NULL);
/*
以太网帧头 14
ip头 20
udp头 8
总共42字节(最少)
*/
if(nRead < 42)
{
printf("packet error\n");
continue;
}
int n = 0XFF;
char szVisBuf[1024] = {0};
for(unsigned int i = 0; i < nRead; ++i)
{
char szTmp[3] = {0};
sprintf(szTmp, "%02x", buffer[i]&n);
strcat(szVisBuf, szTmp);
}
ethhead = buffer;
p = ethhead;
iphead = ethhead + 14;
p = iphead + 12;
char szIps[128] = {0};
snprintf(szIps, sizeof(szIps), "IP: %d.%d.%d.%d => %d.%d.%d.%d",
p[0]&n, p[1]&n, p[2]&n, p[3]&n,
p[4]&n, p[5]&n, p[6]&n, p[7]&n);
iProtocol = (iphead + 9)[0];
p = iphead + 20;
unsigned int iDstPort = (p[2]<<8)&0xff00 | p[3]&n;
switch(iProtocol)
{
case IPPROTO_UDP :
if(iDstPort == 8888)
{
printf("source port: %u,",(p[0]<<8)&0xff00 | p[1]&n);
printf("dest port: %u\n", iDstPort);
printf("%s\n", szIps);
printf("%s\n", szVisBuf);
printf("nRead is %d\n", nRead);
}
break;
case IPPROTO_RAW :
printf("raw\n");
break;
default:
break;
}
}
}
再看:ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ g++ server.cpp
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out
main is running
create iSocket error, check root
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out
-rwxrwxr-x 1 ubuntu ubuntu 9016 Mar 2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chown root a.out
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chmod u+s a.out
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out
-rwsrwxr-x 1 root ubuntu 9016 Mar 2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out
main is running
结果OK, 可见a.out进程具有了root权限。
由于进程具有了root权限, 所以操作的时候, 一定要注意安全问题。
我们来看看ping, 它采用了raw socket, 需要root权限, 但是, 我们平常执行root命令的时候, 没有加sudo啊, 来探个究竟:ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll `which ping`
-rwsr-xr-x 1 root root 44168 May 8 2014 /bin/ping*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ 可以看到, 可执行程序二进制文件ping的owner是root, 且是rws的, 注意这个s
APUE说:若文件的所有者是超级用户,而且设置了该文件的设置用户位(suid),然后该程序由一个进程执行时,则该进程具有超级用户特权。
所以, 我们来模仿ping的方式。 程序如下:#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <arpa/inet.h>
int main()
{
printf("main is running\n");
int iSock, nRead, iProtocol;
char buffer[4096] = {0};
char *ethhead, *iphead, *tcphead, *udphead, *icmphead, *p;
if((iSock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 0)
{
printf("create iSocket error, check root\n"); // 需要root权限
return 1;
}
while(1)
{
nRead = recvfrom(iSock, buffer, 2048, 0, NULL, NULL);
/*
以太网帧头 14
ip头 20
udp头 8
总共42字节(最少)
*/
if(nRead < 42)
{
printf("packet error\n");
continue;
}
int n = 0XFF;
char szVisBuf[1024] = {0};
for(unsigned int i = 0; i < nRead; ++i)
{
char szTmp[3] = {0};
sprintf(szTmp, "%02x", buffer[i]&n);
strcat(szVisBuf, szTmp);
}
ethhead = buffer;
p = ethhead;
iphead = ethhead + 14;
p = iphead + 12;
char szIps[128] = {0};
snprintf(szIps, sizeof(szIps), "IP: %d.%d.%d.%d => %d.%d.%d.%d",
p[0]&n, p[1]&n, p[2]&n, p[3]&n,
p[4]&n, p[5]&n, p[6]&n, p[7]&n);
iProtocol = (iphead + 9)[0];
p = iphead + 20;
unsigned int iDstPort = (p[2]<<8)&0xff00 | p[3]&n;
switch(iProtocol)
{
case IPPROTO_UDP :
if(iDstPort == 8888)
{
printf("source port: %u,",(p[0]<<8)&0xff00 | p[1]&n);
printf("dest port: %u\n", iDstPort);
printf("%s\n", szIps);
printf("%s\n", szVisBuf);
printf("nRead is %d\n", nRead);
}
break;
case IPPROTO_RAW :
printf("raw\n");
break;
default:
break;
}
}
}
再看:ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ g++ server.cpp
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out
main is running
create iSocket error, check root
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out
-rwxrwxr-x 1 ubuntu ubuntu 9016 Mar 2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chown root a.out
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ sudo chmod u+s a.out
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ll a.out
-rwsrwxr-x 1 root ubuntu 9016 Mar 2 22:26 a.out*
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$
ubuntu@VM-0-15-ubuntu:~/taoge/raw_soc$ ./a.out
main is running
结果OK, 可见a.out进程具有了root权限。
由于进程具有了root权限, 所以操作的时候, 一定要注意安全问题。
相关文章推荐
- 怎样从Linux终端管理进程:10个你必须知道的命令
- 在CMD窗口中使用javac和java命令进行编译和执行带有包名的具有继承关系的类
- android应用执行需要root权限的shell命令
- linux机器上执行ping命令的java方法
- 为什么有的命令用sudo执行出错,不用sudo反而正常?
- 让apache可执行远程需root权限的命令
- android在apk中获取root权限,并执行命令
- c#关闭系统进程以及如何调用cmd并执行命令
- android在apk中获取root权限,并执行命令(改变文件权读写限)
- 为什么有时候执行ls命令非常缓慢
- PHP通过ROOT权限执行linux命令
- [Linux进程]使用vfork创建子进程并且执行命令
- 关于C#远程执行命令后,在远程主机上能看到进程但看不到交互窗口的问题(一)
- 关闭系统进程,以及如何调用cmd并执行命令
- shell: 普通用户如何以root权限执行远程服务器上的命令_20160706_七侠镇莫尛貝
- Unix网络编程:while中执行waitpid为什么能正确解决同时出现的多个子进程结束
- 普通用户执行需要root权限的命令的方法
- Linux--- MySQL中GRANT命令执行时发生root权限报错及解决方法
- 执行具有root权限的java代码
- 关闭系统进程,以及如何调用cmd并执行命令