⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 snmp.c

📁 FERRET - a broadcast analysis tool This tool is designed to demonstrate the problem of "data seap
💻 C
字号:
/* Copyright (c) 2007 by Errata Security */
#include "protos.h"
#include "netframe.h"
#include "ferret.h"
#include "formats.h"

#include <string.h>

struct SNMP
{
	unsigned version;
	unsigned pdu_tag;
	const unsigned char *community;
	unsigned community_length;
	unsigned request_id;
	unsigned error_index;
	unsigned error_status;
};

const unsigned snmp_length(struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned *r_offset)
{
	unsigned result;

	if ( (*r_offset >= length) 
		|| (px[*r_offset] & 0x80) 
		&& ((*r_offset) + (px[*r_offset]&0x7F) >= length)) {
		FRAMERR(frame, "snmp: truncated\n");
		*r_offset = length;
		return 0xFFFFffff;
	}
	result = px[(*r_offset)++];
	if (result & 0x80) {
		unsigned length_of_length = result & 0x7F;
		if (length_of_length == 0) {
			FRAMERR(frame, "snmp: unexpected value\n");
			*r_offset = length;
			return 0xFFFFffff;
		}
		result = 0;
		while (length_of_length) {
			result = result * 256 + px[(*r_offset)++];
			if (result > 0x10000) {
				FRAMERR(frame, "snmp: unexpected value\n");
				*r_offset = length;
				return 0xFFFFffff;
			}
		}
	}
	return result;
}
const unsigned snmp_integer(struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned *r_offset)
{
	unsigned int_length;
	unsigned result;

	if (px[(*r_offset)++] != 0x02) {
		FRAMERR(frame, "snmp: unexpected tag\n");
		*r_offset = length;
		return 0xFFFFffff;
	}

	int_length = snmp_length(frame, px, length, r_offset);
	if (int_length == 0xFFFFffff) {
		*r_offset = length;
		return 0xFFFFffff;
	}
	if (*r_offset + int_length > length) {
		FRAMERR(frame, "snmp: truncated\n");
		*r_offset = length;
		return 0xFFFFffff;
	}

	result = 0;
	while (int_length--)
		result = result * 256 + px[(*r_offset)++];

	return result;
}

static unsigned snmp_tag(const unsigned char *px, unsigned length, unsigned *r_offset)
{
	if (*r_offset >= length)
		return 0;
	return px[(*r_offset)++];
}

void process_snmp(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length)
{
	unsigned offset=0;
	unsigned outer_length;
	struct SNMP snmp[1];

	memset(&snmp, 0, sizeof(*snmp));

	/* tag */
	if (snmp_tag(px, length, &offset) != 0x30)
		return;

	/* length */
	outer_length = snmp_length(frame, px, length, &offset);
	if (length > outer_length + offset)
		length = outer_length + offset;

	/* Version */
	snmp->version = snmp_integer(frame, px, length, &offset);
	if (snmp->version != 0)
		return;

	/* Community */
	if (snmp_tag(px, length, &offset) != 0x04)
		return;
	snmp->community_length = snmp_length(frame, px, length, &offset);
	snmp->community = px+offset;
	offset += snmp->community_length;

	/* PDU */
	snmp->pdu_tag = snmp_tag(px, length, &offset);
	if (snmp->pdu_tag < 0xA0 || 0xA5 < snmp->pdu_tag)
		return;
	outer_length = snmp_length(frame, px, length, &offset);
	if (length > outer_length + offset)
		length = outer_length + offset;

	/* Request ID */
	snmp->request_id = snmp_integer(frame, px, length, &offset);
	snmp->error_status = snmp_integer(frame, px, length, &offset);
	snmp->error_index = snmp_integer(frame, px, length, &offset);

	/* Varbind List */
	if (snmp_tag(px, length, &offset) != 0x30)
		return;
	outer_length = snmp_length(frame, px, length, &offset);
	if (length > outer_length + offset)
		length = outer_length + offset;

	/* Var-bind list */
	while (offset < length) {
		unsigned varbind_length;
		unsigned varbind_end;
		if (px[offset++] != 0x30) {
			FRAMERR(frame, "snmp: unexpected value\n");
			break;
		}
		varbind_length = snmp_length(frame, px, length, &offset);
		if (varbind_length == 0xFFFFffff)
			break;
		varbind_end = offset + varbind_length;
		if (varbind_end > length) {
			FRAMERR(frame, "snmp: unexpected value\n");
			return;
		}
		
		/* OID */
		if (snmp_tag(px,length,&offset) != 6)
			return;
		else {
			unsigned oid_length = snmp_length(frame, px, length, &offset);
			const unsigned char *oid = px+offset;
			unsigned value_tag;
			unsigned value_length;

			offset += oid_length;
			if (offset > length)
				return;

			value_tag = snmp_tag(px,length,&offset);
			value_length = snmp_length(frame, px, length, &offset);
		
			switch (snmp->pdu_tag) {
			case 0xA0:
				process_record(seap, 
					"proto",REC_SZ,"SNMP",-1,
					"GET", REC_FRAMESRC,	frame, -1,
					"community",REC_PRINTABLE, snmp->community, snmp->community_length,
					0);
				process_record(seap, 
					"proto",REC_SZ,"SNMP",-1,
					"GET", REC_FRAMESRC,	frame, -1,
					"oid",REC_OID, oid, oid_length,
					0);
				break;
			default:
				FRAMERR(frame, "snmp: unknown msg type\n");
			}

		}

	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -