Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SNMP TCP support #19064

Merged
merged 3 commits into from Apr 10, 2024
Merged

SNMP TCP support #19064

merged 3 commits into from Apr 10, 2024

Conversation

nrathaus
Copy link
Contributor

@nrathaus nrathaus commented Apr 8, 2024

Related to #9649

  1. Added support for TCP in the snmp.rb file
  2. Added support for TCP selection in the snmp_login.rb file

Comment on lines 205 to 224
def recv_wrapper(sock, max_size, timeout)
res = nil
if protocol == 'udp'
res = sock.recvfrom(max_size, timeout)
end

if protocol == 'tcp'
ready = ::IO.select([sock], nil, nil, timeout)
if ready
res = sock.recv_nonblock(max_size)
# Put into an array to mimic recvfrom
res = [res, host, port]
else
# print("timeout\n")
end
end

return res
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this could be cleaned up just a touch.

Suggested change
def recv_wrapper(sock, max_size, timeout)
res = nil
if protocol == 'udp'
res = sock.recvfrom(max_size, timeout)
end
if protocol == 'tcp'
ready = ::IO.select([sock], nil, nil, timeout)
if ready
res = sock.recv_nonblock(max_size)
# Put into an array to mimic recvfrom
res = [res, host, port]
else
# print("timeout\n")
end
end
return res
end
def recv_wrapper(sock, max_size, timeout)
res = nil
if protocol == 'udp'
res = sock.recvfrom(max_size, timeout)
elsif protocol == 'tcp'
ready = ::IO.select([sock], nil, nil, timeout)
if ready
res = sock.recv_nonblock(max_size)
# Put into an array to mimic recvfrom
res = [res, host, port]
end
end
res
end

It also looks like the only place this is used just wants the response. You could normalize on just returning data when it's received and nil otherwise.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok - I will adjust

Comment on lines 392 to 398
klass = ::Rex::Socket::Udp

if protocol == 'tcp'
klass = ::Rex::Socket::Tcp
end

self.sock = klass.create({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rex::Socket actually provides a Proto argument for exactly this purpose. You should be able to just call ::Rex::Socket.create and pass Proto in the hash as either tcp or udp.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, didn't know that - documentation for Rex::Socket is a bit scarce - thank you for pointing that out

2. Use ::Rex::Socket create's Proto
@smcintyre-r7
Copy link
Contributor

Any chance you know of like a docker container or something that'll start an SNMP service listening on a TCP socket that I can use for testing? I've tried a few so far with no luck.

@nrathaus
Copy link
Contributor Author

I put it in the original issue ticket, here it is as well:

Lets start with getting a testing environment (listen on TCP and UDP)
docker run -d --name snmpd -p 161:161/tcp -p 161:161/udp polinux/snmpd udp:161 tcp:161

Make sure it is (docker) working as expected
snmpwalk -Os -c public -v 1 tcp:127.0.0.1 .

Copy link
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I was able to confirm that everything appears to be working as intended. I was able to test both version 1 and 2c with the new TCP protocol support with the docker.io/polinux/snmpd image. I also tested that UDP is still working with a target printer I have.

metasploit-framework (S:0 J:0) auxiliary(scanner/snmp/snmp_login) > run PROTOCOL=tcp VERSION=2c

[+] 127.1.1.1:161 - Login Successful: public (Access level: read-only); Proof (sysDescr.0): Linux b33cb77ccba4 6.7.9-200.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Mar  6 19:35:04 UTC 2024 x86_64
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
metasploit-framework (S:0 J:0) auxiliary(scanner/snmp/snmp_login) > run PROTOCOL=tcp VERSION=1

[+] 127.1.1.1:161 - Login Successful: public (Access level: read-only); Proof (sysDescr.0): Linux b33cb77ccba4 6.7.9-200.fc39.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Mar  6 19:35:04 UTC 2024 x86_64
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
metasploit-framework (S:0 J:0) auxiliary(scanner/snmp/snmp_login) > run PROTOCOL=udp RHOSTS=192.168.250.7 VERSION=1

[+] 192.168.159.7:161 - Login Successful: internal (Access level: read-write); Proof (sysDescr.0): Brother NC-8800w, Firmware Ver.Z  ,MID 8C5-K8JFID 2
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
metasploit-framework (S:0 J:0) auxiliary(scanner/snmp/snmp_login) > 

@smcintyre-r7 smcintyre-r7 merged commit 76145c3 into rapid7:master Apr 10, 2024
34 checks passed
@smcintyre-r7
Copy link
Contributor

Release Notes

This adds support to the auxiliary/scanner/snmp/snmp_login module to work over the TCP protocol in addition to UDP.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

2 participants