根据IP地址登记信息进行目标信息收集

admin 2024年11月24日12:13:10评论21 views字数 8537阅读28分27秒阅读模式

免责声明

本文仅用于技术讨论与学习,利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

只供对已授权的目标使用测试,对未授权目标的测试作者不承担责任,均由使用本人自行承担。

根据IP地址登记信息进行目标信息收集

文章正文

0x00 前言

在目标资产梳理的过程中,总能遇到一些IP的Whois信息中存在与目标的关联。

根据IP地址登记信息进行目标信息收集
image-20230320100045530

例如上图中218.108.40.56属于218.108.40.56 - 218.108.40.63,整个段的网络名称为xihu-***,描述为Hangzhou xihu ***,根据这个描述和名称推测与之相关联的极有可能是杭州市西湖区****。

这种关联给了我们另一种寻找目标资产的思路,即通过一定的手段处理目标资产名称为关键词,在数据库中查找与之相关联的IP段。但我在网络中没有寻找到适合红队进行此类资产梳理的工具(应该是我菜),因此决定自己动手。

不想看过程的师傅们可直接在下边下载工具用。

工具(开源)与数据库下载:后台回复“0321" 获取

总共两个功能,根据IP查询所属IP段信息、根据关键词查询IP段信息。

0x01 数据来源

要进行IP Whois信息的查询,首先得知道从哪里获取这些信息,通过搜索引擎一把梭得知:

IP地址的划分,有RIR机构来进行统筹管理。负责亚洲地区IP地址分配的,就是APNIC,总部位于澳大利亚墨尔本。各大RIR机构都提供了关于IP地址划分的登记信息,即whois记录。

APNIC提供了每日更新的亚太地区IPv4,IPv6,AS号分配的信息表,访问url是

http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest

向上级目录访问,并浏览一番后得知

http://ftp.apnic.net/apnic/whois/apnic.db.inetnum.gz

http://ftp.apnic.net/apnic/whois/apnic.db.inet6num.gz

这里存放着亚洲地区所有IP地址段信息。

根据IP地址登记信息进行目标信息收集
截屏2022-12-27 16.41.50

那这就很方便了,免除了编写爬虫的过程,只需要读取下载的文件进行解析即可。

0x02 数据解析

解压后的apnic.db.inetnum文件有足足500m,直接对文本文件进行检索性能绝对有问题,那就需要对数据进行解析后存进数据库,在对数据库进行检索。为了方便到处跑,这里选自包含的、无服务的、零配置的sqlite3数据库

既然要存数据库,那必然得建表,这里写了个小脚本统计到底有多少像这样的列。

根据IP地址登记信息进行目标信息收集
截屏2022-12-27 16.56.28
inetnums =[]
withopen("apnic.db.inetnum","rb")as f:
    inetnums = f.read().split(b"n")
result =[]
for line in inetnums:
ifb": "in line:
        key = line.split(b":")[0]
if key notin result:
            result.append(key)
for each in result:
print(each.decode("UTF-8"))
inetnum
netname
country
descr
admin-c
tech-c
status
mnt-by
mnt-routes
last-modified
source
remarks
org
abuse-c
mnt-lower
mnt-irt
geoloc
language

主键就以inetnum中的ip段的起始ip的十进制数字形式存储为start字段,ip段结束ip存储为end字段,而不是以字符串形式存储ip段,这样会方便搜索ip属于哪个ip段。

为了方便搜索ip属于哪个ip段,这里添加ip段的起始ip的十进制数字形式存储为start字段,ip段结束ip为end字段。

一个IP段中可能存在多个descr,那么可以将多个重复项通过空格合并写入数据库的统一列,不影响数据搜索。

根据IP地址登记信息进行目标信息收集
截屏2022-12-27 17.15.19

这就可以建表了,建表语句如下

CREATETABLE"ipseg"(
"start"INTEGERNOTNULLCOLLATEBINARY,
"end"INTEGERNOTNULL,
"inetnum" TEXT NOTNULLUNIQUE,
"netname" TEXT,
"country" TEXT,
"descr" TEXT,
"admin-c" TEXT,
"tech-c" TEXT,
"status" TEXT,
"mnt-by" TEXT,
"mnt-routes" TEXT,
"last-modified" TEXT,
"source" TEXT,
"remarks" TEXT,
"org" TEXT,
"abuse-c" TEXT,
"mnt-lower" TEXT,
"mnt-irt" TEXT,
"geoloc" TEXT,
"language" TEXT,
PRIMARY KEY("inetnum")
);

再写一个小脚本负责解析并导入sqlite

import sqlite3
importIPy

whoisinfo =[]

def analysis_whois(whois_str):
start=0
end=0
    inetnum =""
    netname =""
    country =""
    descr =""
    admin_c =""
    tech_c =""
    status =""
    mnt_by =""
    mnt_routes =""
    last_modified =""
    source =""
    remarks =""
    org =""
    abuse_c =""
    mnt_lower =""
    mnt_irt =""
    geoloc =""
language=""

for _line in whois_str.split(b"n"):
if _line == b"":
continue
        line = _line.decode(encoding='UTF-8',errors='ignore')
        line = line.replace(""","")
if"inetnum:"in line:
            inetnum = line.split(":")[1].strip()
#print(inetnum)
if- "notin inetnum:
continue
            ip = inetnum.split(- ")
            start =int(IPy.IP(ip[0]).strDec())
end=int(IPy.IP(ip[1]).strDec())
elif"netname:"in line:
            netname = line.replace("netname:","").strip()
elif"country:"in line:
            country = line.replace("country:","").strip()
elif"descr:"in line:
            descr += line.replace("descr:","").strip()+" "
elif"admin-c:"in line:
            admin_c += line.replace("admin-c:","").strip()+" "
elif"tech-c:"in line:
            tech_c += line.replace("tech-c:","").strip()+" "
elif"status:"in line:
            status += line.replace("status:","").strip()+" "
elif"mnt-by:"in line:
            mnt_by += line.replace("mnt-by:","").strip()+" "
elif"mnt-routes:"in line:
            mnt_routes += line.replace("mnt-routes:","").strip()+" "
elif"last-modified:"in line:
            last_modified += line.replace("last-modified:","").strip()+" "
elif"source:"in line:
            source += line.replace("source:","").strip()+" "
elif"remarks:"in line:
            remarks += line.replace("remarks:","").strip()+" "
elif"org:"in line:
            org += line.replace("org:","").strip()+" "
elif"abuse-c:"in line:
            abuse_c += line.replace("abuse-c:","").strip()+" "
elif"mnt-lower:"in line:
            mnt_lower += line.replace("mnt-lower:","").strip()+" "
elif"mnt-irt:"in line:
            mnt_irt += line.replace("mnt-irt:","").strip()+" "
elif"geoloc:"in line:
            geoloc += line.replace("geoloc:","").strip()+" "
elif"language:"in line:
            language += line.replace("language:","").strip()+" "
if- "notin inetnum or"."notin inetnum:
return
    sql ="""INSERTINTO ipseg(start,end,inetnum,netname,country,descr,"admin-c","tech-c",status,"mnt-by","mnt-routes","last-modified",source,remarks,org,"abuse-c","mnt-lower","mnt-irt",geoloc,languageVALUES ( """+""{}","*19+""{}" )"
    sql = sql.format(start,end,inetnum,netname,country,descr[:-1],admin_c[:-1],tech_c[:-1],status[:-1],mnt_by[:-1],mnt_routes[:-1],last_modified[:-1],source[:-1],remarks[:-1],org[:-1],abuse_c[:-1],mnt_lower[:-1],mnt_irt[:-1],geoloc[:-1],language[:-1])
try:
        conn.execute(sql)
exceptBaseExceptionas e:
print(inetnum,"error",e,descr)



conn = sqlite3.connect("IP.db")
with open("apnic.db.inetnum","rb")as f:
    whoisinfo = f.read().split(b"nn")
count =0
for info in whoisinfo:
    analysis_whois(info)
if count %1000==0:
        conn.commit()
    count +=1
conn.close()

运行后看起来效果还不戳。

根据IP地址登记信息进行目标信息收集
截屏2022-12-28 09.13.03

不想麻烦的师傅们可以直接进github的Release找到IP.zip下载。

数据库有了,接下来就是查询工具的实现。

语言方面我选择能一次编码到处运行的Golang。

0x03 IP查询IP段

在线版IPwhois

http://ip.webmasterhome.cn/ipwhois.asp?ip=1.1.1.1

这个功能是为了实现IPWhois的离线版,解决在线查询目标资产大量IP会比较慢,也会给服务器造成负担的问题。

前边建表的时候为了方便此功能,增加了start与end字段,这时候该派上用场了。

根据IP地址登记信息进行目标信息收集
截屏2022-12-28 09.35.52

比如我要搜索222.222.222.222的IP段信息,转换得到十进制IP为3739147998,那就搜索start比这个小于等于,end比这个大于等于的ip段。

根据IP地址登记信息进行目标信息收集
截屏2022-12-28 09.41.09

出现了三个包含目标的IP段,选范围最小最精细的。那就用end-start排序一下,最后只输出最小的那个。

根据IP地址登记信息进行目标信息收集
截屏2022-12-28 09.46.48

最终sql语句与代码如下

select inetnum,netname,country,descr,status,"last-modified"from ipseg wherestart<=3739147998andend>=3739147998orderbyend-startASC limit 0,1;
funcqueryInfoByIP(ip int, db *sql.DB){
var inetnum string
var netname string
var country string
var descr string
var status string
var last_modified string
    query :="select inetnum,netname,country,descr,status,"last-modified" from ipseg where start <= %d and end >= %d order by end-start ASC limit 0,1;"
    query = fmt.Sprintf(query, ip, ip)
    rows, err := db.Query(query)
if err !=nil{
        log.Fatal(err)
}
defer rows.Close()
for rows.Next(){
        err = rows.Scan(&inetnum,&netname,&country,&descr,&status,&last_modified)
if err !=nil{
            log.Fatal(err)
}
}
    fmt.Println("IP段:", inetnum)
    fmt.Println("名称:", netname)
    fmt.Println("描述:", descr)
    fmt.Println("国家:", country)
    fmt.Println("状态:", status)
    fmt.Println("最后修改:", last_modified)
}

0x04 关键词查询IP段

一般与目标名称关联的信息在descr与netname中,只要信息中出现关键词即可输出。

sql语句很简单。

select inetnum,netname,descr from ipseg where descr like"%key%"or netname like"%key%";

多个key查询只需要稍稍构造下sql语句。

funcqueryInfoByKey(keys []string, db *sql.DB){
    query :="select inetnum,netname,descr from ipseg where "
    descrQuery :="("
for _, key :=range keys {
        descrQuery += fmt.Sprintf("descr like "%%%s%%" and ", key)
}
    descrQuery = descrQuery[:len(descrQuery)-5]+") "
    query += descrQuery
    query +="or "
    netnameQuery :="("
for _, key :=range keys {
        netnameQuery += fmt.Sprintf("netname like "%%%s%%" and ", key)
}
    netnameQuery = netnameQuery[:len(netnameQuery)-5]+")"
    query += netnameQuery +";"

    rows, err := db.Query(query)
if err !=nil{
        log.Fatal(err)
}
defer rows.Close()
    count :=0
for rows.Next(){
var inetnum string
var netname string
var descr string
        err = rows.Scan(&inetnum,&netname,&descr)
if err !=nil{
            log.Fatal(err)
}
        count +=1
        fmt.Println("序号:", count)
        fmt.Println("IP段:", inetnum)
        fmt.Println("名称:", netname)
        fmt.Println("描述:", descr,"n")
// 限制数量
if count >2000{
break
}
}
}

搜开头对应的西湖****IP段就直接这么调用

queryInfoByKey([]string{"xihu","***"}, db)
根据IP地址登记信息进行目标信息收集
image-20230320105341778

可见还是可以获取到目标IP段的,但会有奇怪的东西混进来,需要人工筛选。

0x05 使用场景

场景一

护网中拿到目标名称为杭州市西湖区***,根据西湖可查询xihu.

使用IPSearch直接搜索相关IP段。

coco@Mac IPSearch%./IPSearch-k xihu,***,***
序号:1
IP段:218.108.40.56-218.108.40.63
名称: xihu-***
描述:Hangzhou xihu ***.

序号:2
IP段:222.133.244.192-222.133.244.207
名称: LCZFXXH
描述: liaocheng***ermentxinxihua 

序号:3
IP段:61.164.41.224-61.164.41.255
名称: XIHU-***-INFORMATION-CENTER
描述: XIHU District***ernment InformationCenter

序号:4
IP段:58.241.40.64-58.241.40.127
名称: XINXIHUABANGONGSHI
描述: XINXIHUABANGONGSHI,WUXI,JIANGSU PROVINCE 

序号:5
IP段:115.238.92.224-115.238.92.239
名称: HZ-XIHU
描述:The people's ***ernment of Hangzhou City,Xihu District

可以得到五个结果,通过对描述的详细观察,序号为1,5的IP段内的IP极大概率为杭州市西湖区的资产。

场景二

演练中收集到一个与目标关联的IP,也许会查看当前IP下的所有资产是否与目标有关,但这个C段范围也许太大了,很可能耗费大量时间却打偏了。但将收集到的ip塞入IPSearch工具查询,通过ip信息查找相同段的资产,再看描述先过滤一次能降低日偏的风险,节约宝贝的攻击时间。

根据IP地址登记信息进行目标信息收集

技术交流

原文始发于微信公众号(Z2O安全攻防):根据IP地址登记信息进行目标信息收集

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月24日12:13:10
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   根据IP地址登记信息进行目标信息收集https://cn-sec.com/archives/1620183.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息