SNMP vulnerability
Martin Bjorklund
mbj@REDACTED
Wed Feb 13 13:12:30 CET 2002
Hi,
You might have seen that CERT has found vulnerabilities in many
implementations of SNMP (http://www.cert.org/advisories/CA-2002-03.html)
I've had an oppurtunity to run the tool they're using to find these
falws towards OTP's SNMP agent (some 30.000 cases with mostly
malformed ASN.1 PDUs). No security issues were found, and the agent
did not waste resources during the test.
However, I did found a couple of bugs; in some of the corner cases the
packets were silently dropped but the snmpInASNParseErrs counter was
not incremented. A patch for this bug is attached. (Also, looking at
the code in snmp_pdus.erl, I realize that there is lots of room for
improvments!)
/martin
-------------- next part --------------
*** /usr/local/lib/erlang/lib/snmp-3.3.3/src/snmp_pdus.erl Wed Dec 12 11:23:05 2001
--- snmp_pdus.erl Wed Feb 6 14:49:59 2002
***************
*** 256,274 ****
{{'IpAddress', Value}, Rest};
dec_value([65 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! {{'Counter32', Value}, Rest};
dec_value([66 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! {{'Unsigned32', Value}, Rest};
dec_value([67 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! {{'TimeTicks', Value}, Rest};
dec_value([68 | Bytes]) ->
{Value, Rest} = dec_oct_str_notag(Bytes),
{{'Opaque', Value}, Rest};
dec_value([70 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! {{'Counter64', Value}, Rest};
dec_value([128,0|T]) ->
{{'NULL', noSuchObject}, T};
dec_value([129,0|T]) ->
--- 253,287 ----
{{'IpAddress', Value}, Rest};
dec_value([65 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! if Value >= 0, Value =< 4294967295 ->
! {{'Counter32', Value}, Rest};
! true ->
! exit({error, {bad_counter32, Value}})
! end;
dec_value([66 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! if Value >= 0, Value =< 4294967295 ->
! {{'Unsigned32', Value}, Rest};
! true ->
! exit({error, {bad_unsigned32, Value}})
! end;
dec_value([67 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! if Value >= 0, Value =< 4294967295 ->
! {{'TimeTicks', Value}, Rest};
! true ->
! exit({error, {bad_timeticks, Value}})
! end;
dec_value([68 | Bytes]) ->
{Value, Rest} = dec_oct_str_notag(Bytes),
{{'Opaque', Value}, Rest};
dec_value([70 | Bytes]) ->
{Value, Rest} = dec_integer_notag(Bytes),
! if Value >= 0, Value =< 18446744073709551615 ->
! {{'Counter64', Value}, Rest};
! true ->
! exit({error, {bad_counter64, Value}})
! end;
dec_value([128,0|T]) ->
{{'NULL', noSuchObject}, T};
dec_value([129,0|T]) ->
***************
*** 288,294 ****
length(Tail) == Size ->
Tail;
true ->
! exit({error, {'wrong length', Bytes}})
end.
split_at(L, 0, Acc) -> {lists:reverse(Acc), L};
--- 301,307 ----
length(Tail) == Size ->
Tail;
true ->
! exit({error, {wrong_length, Bytes}})
end.
split_at(L, 0, Acc) -> {lists:reverse(Acc), L};
***************
*** 676,686 ****
enc_integer_tag(Val) when Val >= 0 -> %% stdcase positive ints
Bytes = eint(Val,[]),
! [2, length(Bytes) | Bytes];
enc_integer_tag(Val) -> %% It's a negative number
Bytes = enint(Val,[]),
! [2, length(Bytes) | Bytes].
enc_integer_notag(Val) when Val >= 0 -> %% stdcase positive ints
eint(Val,[]);
--- 689,699 ----
enc_integer_tag(Val) when Val >= 0 -> %% stdcase positive ints
Bytes = eint(Val,[]),
! [2 | elength(length(Bytes))] ++ Bytes;
enc_integer_tag(Val) -> %% It's a negative number
Bytes = enint(Val,[]),
! [2 | elength(length(Bytes))] ++ Bytes.
enc_integer_notag(Val) when Val >= 0 -> %% stdcase positive ints
eint(Val,[]);
More information about the erlang-questions
mailing list