http://www.perlmonks.org?node_id=1020463


in reply to Re: How to encode snmpv2 trap varbind
in thread How to encode snmpv2 trap varbind

Hi,

For my testing, I needed to send source IP spoofed traps to SNMP
manager (NMS). I am able to send traps now with some dirty way.
I have used Net::SNMP module to send traps. Modified the IPTABLES rule to change the source ip of trap packets.

#!/usr/bin/perl
use lib '/opt/perl_64/lib/site_perl/5.8.8/';
use strict;
use warnings;
use Net::SNMP qw(:ALL);
my $curr_time = (scalar time);
print "IPTABLES Rule inserted\n";
`iptables -t nat -A POSTROUTING -d 10.10.70.14 -p udp --dport 5286 -j SNAT --to 10.10.16.230`;
my ($session, $error) = Net::SNMP->session(
-hostname => '10.10.70.14',
-port => '5286',
-localaddr => '192.168.10.121',
-localport => '1028',
-version => 'snmpv2c',
-community => 'PUBLIC',
);
if (!defined($session)) {
printf("ERROR: %s.\n", $error);
exit 1;
}

my $result = $session->snmpv2_trap(
-varbindlist => [
'1.3.6.1.2.1.1.3.0', , TIMETICKS, 600,
'1.3.6.1.6.3.1.1.4.1.0',OBJECT_IDENTIFIER,'1.3.6.1.4.1.42767.64.1.1.5.1.40.1',
'1.3.6.1.4.1.42767.64.1.1.3.1.9', INTEGER32, 11,
'1.3.6.1.4.1.42767.64.1.1.3.1.10', OBJECT_IDENTIFIER, 1.3.6.1.2.1.26.2.1.1.3.1.9,
'1.3.6.1.4.1.42767.64.1.1.3.1.11', COUNTER32, 10,
'1.3.6.1.4.1.42767.64.1.1.3.1.12', TIMETICKS, $curr_time,
'1.3.6.1.4.1.42767.64.1.1.3.1.13', INTEGER32, 2,
'1.3.6.1.4.1.42767.64.1.1.3.1.14', OCTET_STRING, '' ]
);

if (!defined($result)) {
printf("ERROR: %s.\n", $session->error());
}
else {
printf("SNMPv2-Trap-PDU sent.\n");
}

$session->close();
`iptables -t nat -D POSTROUTING -d 10.10.70.14 -p udp --dport 5286 -j SNAT --to 10.10.16.230`;
print "IPTABLES rules removed\n";

Replies are listed 'Best First'.
Re^3: How to encode snmpv2 trap varbind
by topher (Scribe) on Feb 26, 2013 at 00:50 UTC

    Are you sure they have to be spoofed?

    The reason I ask is because there may be a simpler way to accomplish this. Most network monitoring systems (unless they're brain-damaged) support SNMP-COMMUNITY-MIB::snmpTrapAddress (1.3.6.1.6.3.18.1.3 with a .0 as your instance identifier). This is an SNMPv2 varbind that you can pass that contains an IP address to signify that the NMS should treat that as the originating SNMP source (commonly used by SNMP trap relays and aggregators). The docs on it noted that it should be the second varbind sent after the sysUptime (http://tools.ietf.org/html/rfc2576).

    This variable serves roughly the same purpose as the agent-addr value in SNMPv1 traps. In fact, if your NMS supports SNMPv1, using that and setting agent-addr should be another viable option.

    I've used both of the above methods successfully to "spoof" traps to multiple NMS's in the past. It works correctly on nearly all of them. In fact, if any of them fail to treat the trap as if it had come from the snmpTrapAddress/agent-addr, I'd recommend filing a bug with the developer and get them to fix their application.

    I'd definitely recommend giving this a try. It may simplify things a great deal for you, and save you from the hassle and complexity of packet-level spoofing.

    If needed, I might be able to dig up some (working) code I've used to accomplish the above; however, I was using the Net-SNMP project's SNMP perl module (not Net::SNMP), so the syntax is quite different.

      Thanks topher ...I will include snmpTrapAddress also in the varbind and test. I will post my test results ..

        Hi topher,

        Thanks a ton for this info !!! Its like a life saver for me ...
        I have included snmpTrapAddress.0 in the trap varbind. Now trap is correctly received and processed by NMS

        #!/usr/bin/perl
        use lib '/opt/perl_64/lib/site_perl/5.8.8/';
        use strict;
        use warnings;
        use Net::SNMP qw(:ALL);
        my $curr_time = (scalar time);
        my ($session, $error) = Net::SNMP->session(
        -hostname => '10.10.70.14',
        -port => '5286',
        -localaddr => '192.168.10.121',
        -localport => '1028',
        -version => 'snmpv2c',
        -community => 'PUBLIC',
        );
        if (!defined($session)) {
        printf("ERROR: %s.\n", $error);
        exit 1;
        }

        my $result = $session->snmpv2_trap(
        -varbindlist => [
        '1.3.6.1.2.1.1.3.0', TIMETICKS, 600,
        '1.3.6.1.6.3.1.1.4.1.0',OBJECT_IDENTIFIER,'1.3.6.1.4.1.42767.64.1.1.5.1.40.1',
        '1.3.6.1.6.3.18.1.3.0', IPADDRESS, '10.10.16.230', '1.3.6.1.4.1.42767.64.1.1.3.1.9', INTEGER32, 11,
        '1.3.6.1.4.1.42767.64.1.1.3.1.10', OBJECT_IDENTIFIER, 1.3.6.1.2.1.26.2.1.1.3.1.9,
        '1.3.6.1.4.1.42767.64.1.1.3.1.11', COUNTER32, 10,
        '1.3.6.1.4.1.42767.64.1.1.3.1.12', TIMETICKS, $curr_time,
        '1.3.6.1.4.1.42767.64.1.1.3.1.13', INTEGER32, 2,
        '1.3.6.1.4.1.42767.64.1.1.3.1.14', OCTET_STRING, '' ]
        );

        if (!defined($result)) {
        printf("ERROR: %s.\n", $session->error());
        }
        else {
        printf("SNMPv2-Trap-PDU sent.\n");
        }

        $session->close();

Re^3: How to encode snmpv2 trap varbind
by VinsWorldcom (Prior) on Feb 25, 2013 at 13:43 UTC