欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

为什么执行ping命令时不需要root权限? 怎样让进程具有root权限?

程序员文章站 2022-05-10 09:40:03
...

     最近遇到一个问题, 需要让普通用户执行程序时具有root权限, 怎么办呢?

     我们来看看ping, 它采用了raw socket, 需要root权限, 但是, 我们平常执行root命令的时候, 没有加sudo啊, 来探个究竟:

[email protected]:~/taoge/raw_soc$ ll `which ping`
-rwsr-xr-x 1 root root 44168 May  8  2014 /bin/ping*
[email protected]:~/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;
		}
	}
}

       再看:

[email protected]:~/taoge/raw_soc$ g++ server.cpp 
[email protected]:~/taoge/raw_soc$ ./a.out 
main is running
create iSocket error, check root
[email protected]:~/taoge/raw_soc$ ll a.out 
-rwxrwxr-x 1 ubuntu ubuntu 9016 Mar  2 22:26 a.out*
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ sudo chown root a.out 
[email protected]:~/taoge/raw_soc$ sudo chmod u+s a.out 
[email protected]:~/taoge/raw_soc$ ll a.out 
-rwsrwxr-x 1 root ubuntu 9016 Mar  2 22:26 a.out*
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ 
[email protected]:~/taoge/raw_soc$ ./a.out 
main is running

       结果OK, 可见a.out进程具有了root权限。

       由于进程具有了root权限, 所以操作的时候, 一定要注意安全问题。