使用 PySNMP 进行完整的 nextCmd 扫描
Doing a complete nextCmd scan with PySNMP
我正在尝试使用 PySNMP 扫描我网络中的设备,并希望广泛遍历 MIB 树并查看我能找到什么。
为此我写了一个脚本,效果很好,但是没有完成任务。
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Function definition
def snmp_get_next(OID, target_IP, target_port, target):
if exists(target):
sys.exit("The file '%s' already exists!" % target)
else:
target_file = open(target, 'w+')
# Getting values
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port)),
OID,
cmdgen.MibVariable('IF-MIB', '').loadMibs(),
lexicographicMode=True, maxRows=100,
ignoreNonIncreasingOid=True
)
# Printing errors and OID_name to file
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
target_file.write('- %s:\t OID: %s and value = %s\n'
% (OID, name.prettyPrint(), val.prettyPrint())
)
target_file.close()
print('Writing successful!')
sys.exit(0)
# Execution of function
snmp_get_next(
tuple(map(int,raw_input('OID Tuple:\t').split(','))),
raw_input('Target IP:\t'),
raw_input('Target Port:\t'),
raw_input('Target File:\t')
)
所以,当我以起始元组 1,3,6,1,2,1,2,2,1,3 执行脚本时,我得到一个包含大约 100 个条目的文件,最后一个条目有元组 1, 3,6,1,2,1,2,2,1,2,21。现在,当我使用最后一个元组作为起始元组时,它仍然会找到更多。
要么我误解了什么,要么它不符合预期。
更新:
我稍微更改了我的代码,现在它几乎可以正常工作了。唯一的问题是,我不能省略 "maxRows" 参数,否则我会收到超时错误消息。
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
# Turn on debugging
#debug.setLogger(debug.Debug('msgproc', 'secmod'))
# Enter parameters
target_IP = raw_input('Target IP (192.168.13.100): ') or '192.168.13.100'
target_port = raw_input('Target port (161): ') or 161
target_file_name = raw_input('Target filename (.txt is added): ') + '.txt'
# Check for already existing file
if exists(target_file_name):
sys.exit("The file '%s' already exists!" % target_file_name)
else:
target_file = open(target_file_name, 'w+')
# Initialize counter to zero
counter = 0
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Get data
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port)),
'1.3', # <---- Does not seem perfect to me, but it works
lexicographicMode=True,
maxRows=5000, # <---- Can't be left out, but I want to
ignoreNonIncreasingOid=True,
lookupNames=True,
lookupValues=True
)
# Print errors and values to file
if errorIndication:
print(errorIndication)
else:
# Print error messages
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
# Print values
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
counter += 1
target_file.write("(%s)\t start_OID: %s\tvalue =\t%s\n" % (counter, name.prettyPrint(), val.prettyPrint()))
# Finish the operation
target_file.close()
print('Writing to %s successful. %d lines have been written' % (target_file_name, counter))
sys.exit(0)
阅读 documentation of the example you are following,变量 maxRows
突出显示为相关。
该示例将其设置为 100,您说的大致是返回的行数。 (我希望它正好是那个数字。)
所以,尝试增加 maxRows
!
通常情况下,SNMP Walk 不会将自己限制在特定的行数。相反,正确的终止标准应该是 "have I received a response OID which is not a child of the OID I started at"。我不清楚该实用程序是否会在此时终止。最坏的情况下,如果你愿意,它会遍历整个 MIB 树。
我正在尝试使用 PySNMP 扫描我网络中的设备,并希望广泛遍历 MIB 树并查看我能找到什么。 为此我写了一个脚本,效果很好,但是没有完成任务。
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Function definition
def snmp_get_next(OID, target_IP, target_port, target):
if exists(target):
sys.exit("The file '%s' already exists!" % target)
else:
target_file = open(target, 'w+')
# Getting values
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port)),
OID,
cmdgen.MibVariable('IF-MIB', '').loadMibs(),
lexicographicMode=True, maxRows=100,
ignoreNonIncreasingOid=True
)
# Printing errors and OID_name to file
if errorIndication:
print(errorIndication)
else:
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
target_file.write('- %s:\t OID: %s and value = %s\n'
% (OID, name.prettyPrint(), val.prettyPrint())
)
target_file.close()
print('Writing successful!')
sys.exit(0)
# Execution of function
snmp_get_next(
tuple(map(int,raw_input('OID Tuple:\t').split(','))),
raw_input('Target IP:\t'),
raw_input('Target Port:\t'),
raw_input('Target File:\t')
)
所以,当我以起始元组 1,3,6,1,2,1,2,2,1,3 执行脚本时,我得到一个包含大约 100 个条目的文件,最后一个条目有元组 1, 3,6,1,2,1,2,2,1,2,21。现在,当我使用最后一个元组作为起始元组时,它仍然会找到更多。 要么我误解了什么,要么它不符合预期。
更新:
我稍微更改了我的代码,现在它几乎可以正常工作了。唯一的问题是,我不能省略 "maxRows" 参数,否则我会收到超时错误消息。
from pysnmp.entity.rfc3413.oneliner import cmdgen
from os.path import exists
import sys
# Turn on debugging
#debug.setLogger(debug.Debug('msgproc', 'secmod'))
# Enter parameters
target_IP = raw_input('Target IP (192.168.13.100): ') or '192.168.13.100'
target_port = raw_input('Target port (161): ') or 161
target_file_name = raw_input('Target filename (.txt is added): ') + '.txt'
# Check for already existing file
if exists(target_file_name):
sys.exit("The file '%s' already exists!" % target_file_name)
else:
target_file = open(target_file_name, 'w+')
# Initialize counter to zero
counter = 0
# Create command generator
cmdGen = cmdgen.CommandGenerator()
# Get data
errorIndication, errorStatus, errorIndex, varBindTable = cmdGen.nextCmd(
cmdgen.CommunityData('public'),
cmdgen.UdpTransportTarget((target_IP, target_port)),
'1.3', # <---- Does not seem perfect to me, but it works
lexicographicMode=True,
maxRows=5000, # <---- Can't be left out, but I want to
ignoreNonIncreasingOid=True,
lookupNames=True,
lookupValues=True
)
# Print errors and values to file
if errorIndication:
print(errorIndication)
else:
# Print error messages
if errorStatus:
print('%s at %s' % (
errorStatus.prettyPrint(),
errorIndex and varBindTable[-1][int(errorIndex)-1] or '?'
)
)
else:
# Print values
for varBindTableRow in varBindTable:
for name, val in varBindTableRow:
counter += 1
target_file.write("(%s)\t start_OID: %s\tvalue =\t%s\n" % (counter, name.prettyPrint(), val.prettyPrint()))
# Finish the operation
target_file.close()
print('Writing to %s successful. %d lines have been written' % (target_file_name, counter))
sys.exit(0)
阅读 documentation of the example you are following,变量 maxRows
突出显示为相关。
该示例将其设置为 100,您说的大致是返回的行数。 (我希望它正好是那个数字。)
所以,尝试增加 maxRows
!
通常情况下,SNMP Walk 不会将自己限制在特定的行数。相反,正确的终止标准应该是 "have I received a response OID which is not a child of the OID I started at"。我不清楚该实用程序是否会在此时终止。最坏的情况下,如果你愿意,它会遍历整个 MIB 树。