对从外部获取的“IP地址或者域名”进行校验,避免命令注入

本文介绍了如何通过配置文件获取IP地址或域名,并进行校验以防止命令注入攻击。通过inet_aton()函数验证IP地址的有效性,以及使用gethostbyname()解析域名并获取IP,然后再次校验。同时,提供了示例代码展示校验过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题:】

因IP地址或 域名的参数是通过配置文件获取的,且当client连接broker异常时,需要通过system()系统调用来执行ping IP操作,将结果记录在日志中;

但是system()函数如果执行的命令被异常修改,可能会导致系统异常。所以为了解决外部来的数据被system()执行时恶意修改,即避免命令注入,需要对从外部获取的参数进行校验。

【解法方法:】

IP地址或 域名的参数是通过配置文件获取,获取后对其进行校验:1)如果是IP地址,则使用 inet_aton() 进行校验; 2)如果是域名,则需从域名中解析出IP地址,然后再对IP地址进行校验;

int inet_pton(int af,const char*src,void*dst);  // 经常用这个函数点分十进制字符串ip转换为网络字节序。

1.把ip地址转化为用于网络传输的二进制数值
int inet_aton(const char *cp, struct in_addr *inp);

inet_aton() 转换网络主机地址ip(如192.168.1.10)为二进制数值,并存储在struct in_addr结构中,即第二个参数*inp,函数返回非0表示cp主机有地有效,返回0表示主机地址无效。(这个转换完后不能用于网络传输,还需要调用htons或htonl函数才能将主机字节顺序转化为网络字节顺序)

in_addr_t inet_addr(const char *cp);

inet_addr函数转换网络主机地址(如192.168.1.10)为网络字节序二进制值,如果参数char *cp无效,函数返回-1(INADDR_NONE),这个函数在处理地址为255.255.255.255时也返回-1,255.255.255.255是一个有效的地址,不过inet_addr无法处理;


2.将网络传输的二进制数值转化为成点分十进制的ip地址

char *inet_ntoa(struct in_addr in);

inet_ntoa 函数转换网络字节排序的地址为标准的ASCII以点分开的地址,该函数返回指向点分开的字符串地址(如192.168.1.10)的指针,该字符串的空间为静态分配的,这意味着在第二次调用该函数时,上一次调用将会被重写(复盖),所以如果需要保存该串最后复制出来自己管理!
 

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

int errnoStr;
 
int main(int argc, char **argv)
{
    if (argc != 2) {
        printf("Use example: %s www.baidu.com\n", *argv);
        return -1;
    }
 
    char *name = argv[1];
    struct hostent *hptr = gethostbyname(name);
    if (hptr == NULL) {
        printf("gethostbyname error, host: %s: %s\n", name, hstrerror(errnoStr));
        return -1;
    }
    // 输出主机的规范名
    printf("\tofficial: %s\n", hptr->h_name);
 
    // 输出主机的别名
    char **pptr;
    char str[INET_ADDRSTRLEN] = {0};
    for (pptr=hptr->h_aliases; *pptr!=NULL; pptr++) {
        printf("\ttalias: %s\n", *pptr);
    }
	char buffer[31]={"192.168.1.1"};
	struct in_addr *ipData = NULL;
	if (inet_aton(buffer, ipData) == 0) {
		printf("inet_aton failed\n");
	} else {
		printf("inet_aton success\n");
	}

	// int inet_aton(const char *cp, struct in_addr *inp);
    // 输出ip地址
    switch (hptr->h_addrtype) {
        case AF_INET:
            pptr = hptr->h_addr_list;
            for (; *pptr != NULL; pptr++) {
                printf("\taddress: %s\n",
				       inet_ntop(hptr->h_addrtype, hptr->h_addr, str, sizeof(str)));
					   
				/* IP 地址转换为 */
				if (inet_aton(hptr->h_addr, ipData) == 0) {
					printf("inet_aton failed\n");
				} else {
					printf("inet_aton success\n");
				}
            }
            break;
        default:
            printf("unknown address type\n");
            break;
    }
    return 0;
}

/*
[zll@zll 5_linux_net]$ ./gethostbyname localhost
	official: localhost
	talias: localhost.localdomain
	talias: localhost4
	talias: localhost4.localdomain4
	talias: localhost.localdomain
	talias: localhost6
	talias: localhost6.localdomain6
inet_ntop success
	address: 127.0.0.1
inet_ntop failed
	address: 127.0.0.1
inet_ntop failed



*/

https://blog.youkuaiyun.com/daaikuaichuan/article/details/83061117 —— hao

https://blog.youkuaiyun.com/daiyudong2020/article/details/51946080
gethostbyname()函数详解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值