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

📄 ldap.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>
#include <stdio.h>
#include <stdlib.h>

const unsigned 
asn1_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;
			}
			length_of_length--;
		}
	}
	return result;
}


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

	tag = px[(*r_offset)++];
	if (tag != 0x0a && tag != 0x02 && tag != 0x01)
		FRAMERR_BADVAL(frame, "asn1", tag);

	int_length = asn1_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;
}

#define asn1_enumerated asn1_integer
#define asn1_boolean asn1_integer

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

static void
asn1_string(struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned *r_offset, const unsigned char **r_str, unsigned *r_str_length)
{
	unsigned len;
	unsigned tag;

	if (*r_offset >= length)
		return;
	
	tag = asn1_tag(px, length, r_offset);

	len = asn1_length(frame, px, length, r_offset);

	*r_str = px + *r_offset;
	*r_str_length = len;

	*r_offset += len;
}

struct AttributeValueAssertion {
	const unsigned char *attributeDescription;
	unsigned attributeDescription_length;

	const unsigned char *assertionValue;
	unsigned assertionValue_length;
};
struct FILTER
{
	unsigned tag;
	unsigned count;
	union {
		struct FILTER *filters[128];
		struct AttributeValueAssertion *attributes[64];
		struct AttributeType {
			const unsigned char *attributeType;
			unsigned attributeType_length;
		} at;

		struct {
			const unsigned char *attributeType;
			unsigned attributeType_length;
		} substringfilter;

		struct AttributeValueAssertion val;
	} data;
};

struct LDAP
{
	unsigned message_id;
	unsigned message_type;
	const unsigned char *basedn;
	unsigned basedn_length;
	unsigned scope;
	unsigned dereference;
	unsigned size_limit;
	unsigned time_limit;
	unsigned attribute_only;

	struct FILTER *filter;
};


static void process_ldap_filter(struct NetFrame *frame, const unsigned char *px, unsigned length, unsigned *r_offset, struct FILTER **r_filter)
{
	unsigned len;
	struct FILTER *filter;

	*r_filter = (struct FILTER*)malloc(sizeof(struct FILTER));
	memset(*r_filter, 0, sizeof(struct FILTER));
	filter = *r_filter;

	filter->tag = asn1_tag(px,length,r_offset);
	len = asn1_length(frame,px,length,r_offset);

	if (length > *r_offset+len)
		length = *r_offset+len;

	if (0)
	switch (filter->tag) {
	case 0xa0: /* 'and' - SET OF Filter */
	case 0xa1: /* 'or' - SET OF Filter */
		while (*r_offset < length) {
			if (filter->count < 128) {
				process_ldap_filter(frame, px, length, r_offset, &filter->data.filters[filter->count++]);
			} else {
				asn1_tag(px,length,r_offset);
				len = asn1_length(frame,px,length,r_offset);
				*r_offset += len;
			}
		}
		break;
	case 0xa3: /*equalityMatch   - AttributeValueAssertion */
	case 0xa5: /*greaterOrEqual  - AttributeValueAssertion */
	case 0xa6: /*lessOrEqual     - AttributeValueAssertion */
		asn1_string(frame, px, length, r_offset, &filter->data.val.attributeDescription, &filter->data.val.attributeDescription_length);
		asn1_string(frame, px, length, r_offset, &filter->data.val.assertionValue, &filter->data.val.assertionValue_length);
		break;			
	case 0xa4: /*substrings      - SubstringFilter */
	case 0xa7: /*present         - AttributeDescription */
	case 0xa8: /*approxMatch     - AttributeValueAssertion,	default */
	default:
		FRAMERR_BADVAL(frame, "ldap", filter->tag);
		break;
	}

	*r_offset = length;
}

static void process_ldap_search_request(struct Seaper *seap, struct NetFrame *frame, const unsigned char *px, unsigned length, struct LDAP *ldap)
{
	unsigned offset = 0;

	seap;

	asn1_string(frame, px, length, &offset, &ldap->basedn, &ldap->basedn_length);
	ldap->scope = asn1_enumerated(frame, px, length, &offset);
	ldap->dereference = asn1_enumerated(frame, px, length, &offset);
	ldap->size_limit = asn1_integer(frame, px, length, &offset);
	ldap->time_limit = asn1_integer(frame, px, length, &offset);
	ldap->attribute_only = asn1_boolean(frame, px, length, &offset);

	process_ldap_filter(frame, px, length, &offset, &ldap->filter);
}

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

	memset(ldap, 0, sizeof(ldap[0]));

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

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

	/* Version */
	ldap->message_id = asn1_integer(frame, px, length, &offset);

	/* PDU */
	ldap->message_type = asn1_tag(px, length, &offset);
	outer_length = asn1_length(frame, px, length, &offset);
	if (length > outer_length + offset)
		length = outer_length + offset;

	switch (ldap->message_type) {
	case 0x63:
		process_ldap_search_request(seap, frame, px+offset, length-offset, ldap);
		break;
	default:
		FRAMERR_BADVAL(frame, "ldap", ldap->message_type);
		break;
	}
}

⌨️ 快捷键说明

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