mirror of
https://github.com/shmilylty/OneForAll.git
synced 2026-10-25 00:56:14 +08:00
addr字段改为ip2location 添加ip2region字段
This commit is contained in:
+7
-5
@@ -79,7 +79,8 @@ class Database(object):
|
|||||||
f'ttl text,'
|
f'ttl text,'
|
||||||
f'cidr text,'
|
f'cidr text,'
|
||||||
f'asn text,'
|
f'asn text,'
|
||||||
f'addr text,'
|
f'ip2region text,'
|
||||||
|
f'ip2location text,'
|
||||||
f'resolver text,'
|
f'resolver text,'
|
||||||
f'module text,'
|
f'module text,'
|
||||||
f'source text,'
|
f'source text,'
|
||||||
@@ -106,11 +107,11 @@ class Database(object):
|
|||||||
f'id, type, alive, resolve, request, new, url, subdomain,'
|
f'id, type, alive, resolve, request, new, url, subdomain,'
|
||||||
f'port, level, cname, content, public, status, reason,'
|
f'port, level, cname, content, public, status, reason,'
|
||||||
f'title, banner, header, response, times, ttl, cidr, asn,'
|
f'title, banner, header, response, times, ttl, cidr, asn,'
|
||||||
f'addr, resolver, module, source, elapse, find, brute, valid) '
|
f'ip2region, ip2location, resolver, module, source, elapse, find, brute, valid) '
|
||||||
f'values (:id, :type, :alive, :resolve, :request, :new,'
|
f'values (:id, :type, :alive, :resolve, :request, :new,'
|
||||||
f':url, :subdomain, :port, :level, :cname, :content,'
|
f':url, :subdomain, :port, :level, :cname, :content,'
|
||||||
f':public, :status, :reason, :title, :banner, :header,'
|
f':public, :status, :reason, :title, :banner, :header,'
|
||||||
f':response, :times, :ttl, :cidr, :asn, :addr, :resolver,'
|
f':response, :times, :ttl, :cidr, :asn, :ip2region, :ip2location, :resolver,'
|
||||||
f':module, :source, :elapse, :find, :brute, :valid)', results)
|
f':module, :source, :elapse, :find, :brute, :valid)', results)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.log('ERROR', e)
|
logger.log('ERROR', e)
|
||||||
@@ -234,8 +235,9 @@ class Database(object):
|
|||||||
table_name = table_name.replace('.', '_')
|
table_name = table_name.replace('.', '_')
|
||||||
query = f'select id, type, new, alive, request, resolve, url, ' \
|
query = f'select id, type, new, alive, request, resolve, url, ' \
|
||||||
f'subdomain, level, cname, content, public, port, status, ' \
|
f'subdomain, level, cname, content, public, port, status, ' \
|
||||||
f'reason, title, banner, times, ttl, cidr, asn, addr, resolver, ' \
|
f'reason, title, banner, times, ttl, cidr, asn, ip2region, ' \
|
||||||
f'module, source, elapse, find, brute, valid from "{table_name}"'
|
f'ip2location, resolver, module, source, elapse, find, brute, valid ' \
|
||||||
|
f'from "{table_name}"'
|
||||||
if alive and limit:
|
if alive and limit:
|
||||||
if limit in ['resolve', 'request']:
|
if limit in ['resolve', 'request']:
|
||||||
where = f' where {limit} = 1'
|
where = f' where {limit} = 1'
|
||||||
|
|||||||
+246
@@ -0,0 +1,246 @@
|
|||||||
|
# encoding = uft-8
|
||||||
|
"""
|
||||||
|
" ip2region python searcher client module
|
||||||
|
"
|
||||||
|
" Author: koma<komazhang@foxmail.com>
|
||||||
|
" Date : 2015-11-06
|
||||||
|
"""
|
||||||
|
import io
|
||||||
|
import socket
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
class IpRegInfo(object):
|
||||||
|
__INDEX_BLOCK_LENGTH = 12
|
||||||
|
__TOTAL_HEADER_LENGTH = 8192
|
||||||
|
|
||||||
|
__f = None
|
||||||
|
__headerSip = []
|
||||||
|
__headerPtr = []
|
||||||
|
__headerLen = 0
|
||||||
|
__indexSPtr = 0
|
||||||
|
__indexLPtr = 0
|
||||||
|
__indexCount = 0
|
||||||
|
__dbBinStr = ''
|
||||||
|
|
||||||
|
def __init__(self, db_file):
|
||||||
|
self.init_database(db_file)
|
||||||
|
|
||||||
|
def memory_search(self, ip):
|
||||||
|
"""
|
||||||
|
" memory search method
|
||||||
|
" param: ip
|
||||||
|
"""
|
||||||
|
if not ip.isdigit():
|
||||||
|
ip = self.ip2long(ip)
|
||||||
|
|
||||||
|
if self.__dbBinStr == '':
|
||||||
|
self.__dbBinStr = self.__f.read() # read all the contents in file
|
||||||
|
self.__indexSPtr = self.get_long(self.__dbBinStr, 0)
|
||||||
|
self.__indexLPtr = self.get_long(self.__dbBinStr, 4)
|
||||||
|
self.__indexCount = int((self.__indexLPtr - self.__indexSPtr) / self.__INDEX_BLOCK_LENGTH) + 1
|
||||||
|
|
||||||
|
l, h, data_ptr = (0, self.__indexCount, 0)
|
||||||
|
while l <= h:
|
||||||
|
m = int((l + h) >> 1)
|
||||||
|
p = self.__indexSPtr + m * self.__INDEX_BLOCK_LENGTH
|
||||||
|
sip = self.get_long(self.__dbBinStr, p)
|
||||||
|
|
||||||
|
if ip < sip:
|
||||||
|
h = m - 1
|
||||||
|
else:
|
||||||
|
eip = self.get_long(self.__dbBinStr, p + 4)
|
||||||
|
if ip > eip:
|
||||||
|
l = m + 1;
|
||||||
|
else:
|
||||||
|
data_ptr = self.get_long(self.__dbBinStr, p + 8)
|
||||||
|
break
|
||||||
|
|
||||||
|
if data_ptr == 0:
|
||||||
|
raise Exception("Data pointer not found")
|
||||||
|
|
||||||
|
return self.return_data(data_ptr)
|
||||||
|
|
||||||
|
def binary_search(self, ip):
|
||||||
|
"""
|
||||||
|
" binary search method
|
||||||
|
" param: ip
|
||||||
|
"""
|
||||||
|
if not ip.isdigit(): ip = self.ip2long(ip)
|
||||||
|
|
||||||
|
if self.__indexCount == 0:
|
||||||
|
self.__f.seek(0)
|
||||||
|
super_block = self.__f.read(8)
|
||||||
|
self.__indexSPtr = self.get_long(super_block, 0)
|
||||||
|
self.__indexLPtr = self.get_long(super_block, 4)
|
||||||
|
self.__indexCount = int((self.__indexLPtr - self.__indexSPtr) / self.__INDEX_BLOCK_LENGTH) + 1
|
||||||
|
|
||||||
|
l, h, data_ptr = (0, self.__indexCount, 0)
|
||||||
|
while l <= h:
|
||||||
|
m = int((l + h) >> 1)
|
||||||
|
p = m * self.__INDEX_BLOCK_LENGTH
|
||||||
|
|
||||||
|
self.__f.seek(self.__indexSPtr + p)
|
||||||
|
buffer = self.__f.read(self.__INDEX_BLOCK_LENGTH)
|
||||||
|
sip = self.get_long(buffer, 0)
|
||||||
|
if ip < sip:
|
||||||
|
h = m - 1
|
||||||
|
else:
|
||||||
|
eip = self.get_long(buffer, 4)
|
||||||
|
if ip > eip:
|
||||||
|
l = m + 1
|
||||||
|
else:
|
||||||
|
data_ptr = self.get_long(buffer, 8)
|
||||||
|
break
|
||||||
|
|
||||||
|
if data_ptr == 0:
|
||||||
|
raise Exception("Data pointer not found")
|
||||||
|
|
||||||
|
return self.return_data(data_ptr)
|
||||||
|
|
||||||
|
def btree_search(self, ip):
|
||||||
|
"""
|
||||||
|
" b-tree search method
|
||||||
|
" param: ip
|
||||||
|
"""
|
||||||
|
if not ip.isdigit():
|
||||||
|
ip = self.ip2long(ip)
|
||||||
|
|
||||||
|
if len(self.__headerSip) < 1:
|
||||||
|
header_len = 0
|
||||||
|
# pass the super block
|
||||||
|
self.__f.seek(8)
|
||||||
|
# read the header block
|
||||||
|
b = self.__f.read(self.__TOTAL_HEADER_LENGTH)
|
||||||
|
# parse the header block
|
||||||
|
for i in range(0, len(b), 8):
|
||||||
|
sip = self.get_long(b, i)
|
||||||
|
ptr = self.get_long(b, i + 4)
|
||||||
|
if ptr == 0:
|
||||||
|
break
|
||||||
|
self.__headerSip.append(sip)
|
||||||
|
self.__headerPtr.append(ptr)
|
||||||
|
header_len += 1
|
||||||
|
self.__headerLen = header_len
|
||||||
|
|
||||||
|
l, h, sptr, eptr = (0, self.__headerLen, 0, 0)
|
||||||
|
while l <= h:
|
||||||
|
m = int((l + h) >> 1)
|
||||||
|
|
||||||
|
if ip == self.__headerSip[m]:
|
||||||
|
if m > 0:
|
||||||
|
sptr = self.__headerPtr[m - 1]
|
||||||
|
eptr = self.__headerPtr[m]
|
||||||
|
else:
|
||||||
|
sptr = self.__headerPtr[m]
|
||||||
|
eptr = self.__headerPtr[m + 1]
|
||||||
|
break
|
||||||
|
|
||||||
|
if ip < self.__headerSip[m]:
|
||||||
|
if m == 0:
|
||||||
|
sptr = self.__headerPtr[m]
|
||||||
|
eptr = self.__headerPtr[m + 1]
|
||||||
|
break
|
||||||
|
elif ip > self.__headerSip[m - 1]:
|
||||||
|
sptr = self.__headerPtr[m - 1]
|
||||||
|
eptr = self.__headerPtr[m]
|
||||||
|
break
|
||||||
|
h = m - 1
|
||||||
|
else:
|
||||||
|
if m == self.__headerLen - 1:
|
||||||
|
sptr = self.__headerPtr[m - 1]
|
||||||
|
eptr = self.__headerPtr[m]
|
||||||
|
break
|
||||||
|
elif ip <= self.__headerSip[m + 1]:
|
||||||
|
sptr = self.__headerPtr[m]
|
||||||
|
eptr = self.__headerPtr[m + 1]
|
||||||
|
break
|
||||||
|
l = m + 1
|
||||||
|
|
||||||
|
if sptr == 0:
|
||||||
|
raise Exception("Index pointer not found")
|
||||||
|
|
||||||
|
index_len = eptr - sptr
|
||||||
|
self.__f.seek(sptr)
|
||||||
|
index = self.__f.read(index_len + self.__INDEX_BLOCK_LENGTH)
|
||||||
|
|
||||||
|
l, h, data_prt = (0, int(index_len / self.__INDEX_BLOCK_LENGTH), 0)
|
||||||
|
while l <= h:
|
||||||
|
m = int((l + h) >> 1)
|
||||||
|
offset = int(m * self.__INDEX_BLOCK_LENGTH)
|
||||||
|
sip = self.get_long(index, offset)
|
||||||
|
|
||||||
|
if ip < sip:
|
||||||
|
h = m - 1
|
||||||
|
else:
|
||||||
|
eip = self.get_long(index, offset + 4)
|
||||||
|
if ip > eip:
|
||||||
|
l = m + 1;
|
||||||
|
else:
|
||||||
|
data_prt = self.get_long(index, offset + 8)
|
||||||
|
break
|
||||||
|
|
||||||
|
if data_prt == 0:
|
||||||
|
raise Exception("Data pointer not found")
|
||||||
|
|
||||||
|
return self.return_data(data_prt)
|
||||||
|
|
||||||
|
def init_database(self, db_file):
|
||||||
|
"""
|
||||||
|
" initialize the database for search
|
||||||
|
" param: dbFile
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
self.__f = io.open(db_file, "rb")
|
||||||
|
except IOError as e:
|
||||||
|
print("[Error]: %s" % e)
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
def return_data(self, data_ptr):
|
||||||
|
"""
|
||||||
|
" get ip data from db file by data start ptr
|
||||||
|
" param: dsptr
|
||||||
|
"""
|
||||||
|
data_len = (data_ptr >> 24) & 0xFF
|
||||||
|
data_ptr = data_ptr & 0x00FFFFFF
|
||||||
|
|
||||||
|
self.__f.seek(data_ptr)
|
||||||
|
data = self.__f.read(data_len)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"city_id": self.get_long(data, 0),
|
||||||
|
"region": data[4:]
|
||||||
|
}
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def ip2long(ip):
|
||||||
|
_ip = socket.inet_aton(ip)
|
||||||
|
return struct.unpack("!L", _ip)[0]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_ip(ip):
|
||||||
|
p = ip.split(".")
|
||||||
|
if len(p) != 4:
|
||||||
|
return False
|
||||||
|
for pp in p:
|
||||||
|
if not pp.isdigit():
|
||||||
|
return False
|
||||||
|
if len(pp) > 3:
|
||||||
|
return False
|
||||||
|
if int(pp) > 255:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_long(b, offset):
|
||||||
|
if len(b[offset:offset + 4]) == 4:
|
||||||
|
return struct.unpack('I', b[offset:offset + 4])[0]
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
if self.__f is not None:
|
||||||
|
self.__f.close()
|
||||||
|
self.__dbBinStr = None
|
||||||
|
self.__headerPtr = None
|
||||||
|
self.__headerSip = None
|
||||||
+6
-3
@@ -304,7 +304,8 @@ class Module(object):
|
|||||||
'ttl': None,
|
'ttl': None,
|
||||||
'cidr': None,
|
'cidr': None,
|
||||||
'asn': None,
|
'asn': None,
|
||||||
'addr': None,
|
'ip2region': None,
|
||||||
|
'ip2location': None,
|
||||||
'resolver': None,
|
'resolver': None,
|
||||||
'module': self.module,
|
'module': self.module,
|
||||||
'source': self.source,
|
'source': self.source,
|
||||||
@@ -336,7 +337,8 @@ class Module(object):
|
|||||||
public = record.get('public')
|
public = record.get('public')
|
||||||
cidr = record.get('cidr')
|
cidr = record.get('cidr')
|
||||||
asn = record.get('asn')
|
asn = record.get('asn')
|
||||||
addr = record.get('addr')
|
ip2region = record.get('ip2region')
|
||||||
|
ip2location = record.get('ip2location')
|
||||||
if isinstance(cname, list):
|
if isinstance(cname, list):
|
||||||
cname = ','.join(cname)
|
cname = ','.join(cname)
|
||||||
content = ','.join(content)
|
content = ','.join(content)
|
||||||
@@ -366,7 +368,8 @@ class Module(object):
|
|||||||
'ttl': ttl,
|
'ttl': ttl,
|
||||||
'cidr': cidr,
|
'cidr': cidr,
|
||||||
'asn': asn,
|
'asn': asn,
|
||||||
'addr': addr,
|
'ip2region': ip2region,
|
||||||
|
'ip2location': ip2location,
|
||||||
'resolver': resolver,
|
'resolver': resolver,
|
||||||
'module': self.module,
|
'module': self.module,
|
||||||
'source': self.source,
|
'source': self.source,
|
||||||
|
|||||||
+13
-6
@@ -7,6 +7,7 @@ from common import utils
|
|||||||
from common.database import Database
|
from common.database import Database
|
||||||
from common.ipasn import IPAsnInfo
|
from common.ipasn import IPAsnInfo
|
||||||
from common.ipgeo import IpGeoInfo
|
from common.ipgeo import IpGeoInfo
|
||||||
|
from common.ipreg import IpRegInfo
|
||||||
|
|
||||||
|
|
||||||
def filter_subdomain(data):
|
def filter_subdomain(data):
|
||||||
@@ -75,6 +76,8 @@ def deal_output(output_path):
|
|||||||
records = dict() # 用来记录所有域名解析数据
|
records = dict() # 用来记录所有域名解析数据
|
||||||
ip_asn = IPAsnInfo()
|
ip_asn = IPAsnInfo()
|
||||||
ip_geo = IpGeoInfo
|
ip_geo = IpGeoInfo
|
||||||
|
db_path = setting.data_storage_dir.joinpath('ip2region.db')
|
||||||
|
ip_reg = IpRegInfo(db_path)
|
||||||
with open(output_path) as fd:
|
with open(output_path) as fd:
|
||||||
for line in fd:
|
for line in fd:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
@@ -108,7 +111,8 @@ def deal_output(output_path):
|
|||||||
ttls = list()
|
ttls = list()
|
||||||
cidrs = list()
|
cidrs = list()
|
||||||
asns = list()
|
asns = list()
|
||||||
addrs = list()
|
locs = list()
|
||||||
|
regs = list()
|
||||||
answers = data.get('answers')
|
answers = data.get('answers')
|
||||||
for answer in answers:
|
for answer in answers:
|
||||||
if answer.get('type') == 'A':
|
if answer.get('type') == 'A':
|
||||||
@@ -123,10 +127,12 @@ def deal_output(output_path):
|
|||||||
asn_info = ip_asn.find(ip)
|
asn_info = ip_asn.find(ip)
|
||||||
cidrs.append(asn_info.get('cidr'))
|
cidrs.append(asn_info.get('cidr'))
|
||||||
asns.append(asn_info.get('asn'))
|
asns.append(asn_info.get('asn'))
|
||||||
addr = f'{ip_geo.get_country_long(ip)} ' \
|
loc = f'{ip_geo.get_country_long(ip)} ' \
|
||||||
f'{ip_geo.get_region(ip)} ' \
|
f'{ip_geo.get_region(ip)} ' \
|
||||||
f'{ip_geo.get_city(ip)}'
|
f'{ip_geo.get_city(ip)}'
|
||||||
addrs.append(addr)
|
locs.append(loc)
|
||||||
|
reg = ip_reg.memory_search(ip).get('region').decode('utf-8')
|
||||||
|
regs.append(reg)
|
||||||
record['resolve'] = 1
|
record['resolve'] = 1
|
||||||
record['reason'] = status
|
record['reason'] = status
|
||||||
record['cname'] = ','.join(cname)
|
record['cname'] = ','.join(cname)
|
||||||
@@ -135,7 +141,8 @@ def deal_output(output_path):
|
|||||||
record['ttl'] = ','.join(ttls)
|
record['ttl'] = ','.join(ttls)
|
||||||
record['cidr'] = ','.join(cidrs)
|
record['cidr'] = ','.join(cidrs)
|
||||||
record['asn'] = ','.join(asns)
|
record['asn'] = ','.join(asns)
|
||||||
record['addr'] = ','.join(addrs)
|
record['ip2location'] = ','.join(locs)
|
||||||
|
record['ip2region'] = ','.join(regs)
|
||||||
records[qname] = record
|
records[qname] = record
|
||||||
if not flag:
|
if not flag:
|
||||||
record['alive'] = 0
|
record['alive'] = 0
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user