Kscan是一款轻量级的资产发现工具,可针对IP/IP段或资产列表进行端口扫描以及TCP指纹识别和Banner抓取

Kscan-简单好用的资产测绘工具

一、简介


██╗  ██╗███████╗ ██████╗ █████╗ ███╗   ██╗
██║ ██╔╝██╔════╝██╔════╝██╔══██╗████╗  ██║
█████╔╝ ███████╗██║     ███████║██╔██╗ ██║
██╔═██╗ ╚════██║██║     ██╔══██║██║╚██╗██║
██║  ██╗███████║╚██████╗██║  ██║██║ ╚████║
╚═╝  ╚═╝╚══════╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═══╝

Kscan从初次发布至今经历了很多个版本,首次发布于吐司,姑且就叫她1.0吧:

https://www.t00ls.net/thread-57634-1-1.html

而后呢,发布了1.5版本首发于棱角,对之前的代码进行了重构:

https://forum.ywhack.com/viewthread.php?tid=114928

原本造这个轮子的初衷是为了解决平时自己护网大面积的寻找薄弱资产问题,最开始的雏形也只具备HTTP关键字(标题、Header)探测功能,现在的版本新增TCP端口的banner识别,以及HTTP、HTTPS的指纹识别功能。在这里也感谢EHole(棱洞)提供的指纹信息。

现在这个版本的kscan使用go编写,实际上前人已经提供了很多具备相似功能的工具了,但是最终我还是坚定心思,写一款自己的工具。

二、碎碎念

在开始正式介绍kscan之前,我决定聊一聊有关渗透过程过程中最重要的信息收集阶段:资产发现。

image-20210220154321503

如上图所示,从提供攻击目标,到最终实施攻击,经历了四个关键阶段。

  • 转换阶段

    这部分阶段主要目标是完成:从攻击目标到信息资产的一个转换,例如从一个关键字、主域名到具体的IP地址或者其他引申的子域名,主要手段是通过FOFA、钟馗之眼、子域名挖掘/爆破工具来生成一个模糊的清单用于后续阶段去做深层次的筛选。

    其实EHole、Glass等工具有做这一个阶段的整合,但是在这方面,我没有把这个功能做到kscan中,目前我其实是刻意把转换阶段独立出来的。因为在这个阶段,不论是搜索的关键字也好,还是通过域名找到真实IP也好,还是其实更多的需要”人“来做识别。识别完成之后,再生成一个清单给kscan,这样会使后面的流程更高效。

    当然这只是我的个人的一个执念,如果后续反响强烈的话,加进去其实也未尝不可。

  • 扫描阶段

    这一阶段主要是针对IP进行端口扫描以便于后续的应用层识别,扫描速率达标的工具诸如:s.exe、masscan等大都只能实现对开放情况进行探测。而目前的大部分工具,把这部分工作交给了FOFA等搜索引擎,不会自己进行资产探测,这样的优点是不会有大量的端口探测包打草惊蛇,缺点是存在时效性。可能漏掉资产。权衡之后,最终还是把这块功能整合到了kscan中,毕竟IP被封了可以换,资产漏掉了可就是真的漏掉了。

  • 识别阶段

    这一阶段就是对已开放的端口进行深度的端口识别,传统工具大都是只能对端口开放情况进行探测,各别具备识别功能的工具如:nmap效率则是硬伤,而且不能对内容进行解析,无法获取标题等。又或者只能进行HTTP等特定协议进行识别。为了解决这些问题,kscan在确保效率、不发送更多数据包的前提下,能够识别大多数开放端口的协议。

  • 检测阶段

    最后一个阶段,就是应用层检测了,类似CMS指纹识别、敏感目录/文件探测等等,kscan的开发初衷是在不发送更多数据的情况下更多的获取目标的信息,所以不会进行更深层次的目录扫描、指纹比对。但是会进行ico文件hash比对以及首页关键字比对,和返回包头部比对。这其实基本可以满足大部分的指纹识别需求了。

三、使用方法

鄙人是一个懒人,所以在写工具的时候也往易用性上进行了更多的考量

usage: kscan [-h,--help] (-t,--target) [-p,--port|--top] [-o,--output] [--proxy] [--threads] [--http-code] [--path] [--host] [--timeout]

optional arguments:
  -h , --help     show this help message and exit
  -t , --target   直接扫描指定对象,支持IP、URL、IP/[16-32]、file:/tmp/target.txt
  -p , --port     扫描指定端口,默认会扫描TOP400,支持:80,8080,8088-8090
  -o , --output   将扫描结果保存到文件
  --top           扫描WooYun统计开放端口前x个,最高支持1000个
  --proxy         设置代理{socks5/socks4/https/http}://IP:port
  --threads       线程参数,默认线程4000
  --http-code     指定会记录的HTTP状态码,逗号分割,默认会记录200,301,302,403,404
  --path          指定请求访问的目录,逗号分割,慎用!
  --host          指定所有请求的头部HOSTS值,慎用!
  --timeout       设置超时时间,默认3秒钟,单位为秒!

命令很简单相信举几个例子你们都会用

example:	kscan -t www.baidu.com
#你可以直接输入域名
example:	kscan -t http://www.baidu.com/1.asp
#你也可以直接输入URL地址
example:	kscan -t 114.114.114.114
#你还可以直接输入IP地址
example:	kscan -t 114.114.114.114/24
#你当然也可以直接输入IP+掩码
example:	kscan -t file:/tmp/target.txt
#你亦可以从文件导入,你甚至文件里面还可以嵌套文件
#其他命令都是一些修饰命令,相信聪明的你们都会用啦~~~

四、演示

image-20210220162851992

五、特别感谢

六、文末

Github项目地址(BUG、需求、规则欢迎提交): https://github.com/lcvvvv/kscan

image-20210220164117920

image-20210220164117923

Comments
  • 1.53.1-1.60版本登录爆破模块存在BUG

    1.53.1-1.60版本登录爆破模块存在BUG

    1.53.1版本识别服务成功后没有调用爆破 image

    1.60.0版本识别服务调用爆破模块后没有爆破成功,手工测试登录成功(已知redis密码进行测试)

    更早版本未测试,fscan扫描redis口令成功

    使用命令 ./kscan_linux_amd64 -t XXXX -p 6379 -o result.txt --hydra --hydra-pass pass.txt
    ./kscan_linux_amd64 -t XXXX -p 6379 -o result.txt --hydra --hydra-pass pass.txt --hydra-mod redis

  • 是越界了吗?

    是越界了吗?

    panic: runtime error: index out of range [10] with length 10

    goroutine 1 [running]: kscan/lib/chinese.isUtf8(0xc0052b7b40, 0xa, 0x10, 0xc0052b7b4a) /Users/kv2/Project/Gkscan/lib/chinese/chinese.go:83 +0xed kscan/lib/chinese.ByteToUTF8(0xc0052b7b40, 0xa, 0x10, 0xc0052b7b40, 0xa, 0x10) /Users/kv2/Project/Gkscan/lib/chinese/chinese.go:32 +0x61 kscan/lib/chinese.ToUTF8(...) /Users/kv2/Project/Gkscan/lib/chinese/chinese.go:63 kscan/lib/gonmap.(*AppBanner).Output(0xc003c492c0, 0xc0004cbd40, 0x1) /Users/kv2/Project/Gkscan/lib/gonmap/type-appbanner.go:176 +0xa8 kscan/run.(*kscan).Output(0xc008248b40) /Users/kv2/Project/Gkscan/run/type-kscan.go:215 +0x9a kscan/run.Start(0xc000192000, 0xff, 0x100, 0xce8998, 0x0, 0x0, 0xc4e800, 0x190, 0x462, 0x0, ...) /Users/kv2/Project/Gkscan/run/run.go:37 +0x1f0 main.main() /Users/kv2/Project/Gkscan/kscan.go:59 +0x8b

  • redis服务识别失败

    redis服务识别失败

    使用程序获取banner信息时发现redis服务无法识别成功。调试发现是正则的问题

    [gonmap] 2022/08/16 14:40:40 type-probe.go:82: 开始匹配正则: service:redis 
    pattern: ^-ERR wrong number of arguments for 'get' command\r\n$ 
    response:-ERR wrong number of arguments for 'get' command
    -ERR unknown command 'User-Agent:'
    -ERR unknown command 'Accept:'
    

    把正则改为^-ERR wrong number of arguments for 'get' command\r\n就可以正常识别,不知道其他服务有没有类似的情况。 扫描的redis服务版本: 3.2.12

  • The filename, directory name, or volume label syntax is incorrect

    The filename, directory name, or volume label syntax is incorrect

    .\kscan_windows_amd64.exe -t https://www.test.com 无法运行,报错: Error:https://www.test.comopen https://www.test.com: The filename, directory name, or volume label syntax is incorrect.

  • linux 遇到错误

    linux 遇到错误

    错误太多了,以这种为主

    goroutine 1594 [chan receive, 50 minutes]: kscan/lib/pool.(*Pool).work(0xc004e5def0) /Users/kv2/Project/Gkscan/lib/pool/pool.go:81 +0x94 created by kscan/lib/pool.(*Pool).Run /Users/kv2/Project/Gkscan/lib/pool/pool.go:110 +0x79

    goroutine 1595 [chan send]: kscan/lib/pool.(*Pool).work(0xc004e5df90) /Users/kv2/Project/Gkscan/lib/pool/pool.go:96 +0x265 created by kscan/lib/pool.(*Pool).Run /Users/kv2/Project/Gkscan/lib/pool/pool.go:110 +0x79

    中间伴随着少量这种错误

    goroutine 2938 [runnable]: internal/poll.runtime_pollWait(0x7fbf2b8c8ac0, 0x77, 0xc004ce8000) /Users/kv2/Project/go/go1.16.10/src/runtime/netpoll.go:227 +0x55 internal/poll.(*pollDesc).wait(0xc004923e98, 0x77, 0x103f600, 0xc0052285a0, 0xc004923e80) /Users/kv2/Project/go/go1.16.10/src/internal/poll/fd_poll_runtime.go:87 +0x45 internal/poll.(*pollDesc).waitWrite(...) /Users/kv2/Project/go/go1.16.10/src/internal/poll/fd_poll_runtime.go:96 internal/poll.(*FD).WaitWrite(...) /Users/kv2/Project/go/go1.16.10/src/internal/poll/fd_unix.go:528 net.(*netFD).connect(0xc004923e80, 0x103f6c8, 0xc0052285a0, 0x0, 0x0, 0x1033bc0, 0xc003616680, 0x0, 0x0, 0x0, ...) /Users/kv2/Project/go/go1.16.10/src/net/fd_unix.go:141 +0x27b net.(*netFD).dial(0xc004923e80, 0x103f6c8, 0xc0052285a0, 0x1042c50, 0x0, 0x1042c50, 0xc00a6f06c0, 0x0, 0x7fbf2aa48ed8, 0x10) /Users/kv2/Project/go/go1.16.10/src/net/sock_posix.go:149 +0x10b net.socket(0x103f6c8, 0xc0052285a0, 0xc39a52, 0x3, 0x2, 0x1, 0x0, 0x0, 0x1042c50, 0x0, ...) /Users/kv2/Project/go/go1.16.10/src/net/sock_posix.go:70 +0x1c5 net.internetSocket(0x103f6c8, 0xc0052285a0, 0xc39a52, 0x3, 0x1042c50, 0x0, 0x1042c50, 0xc00a6f06c0, 0x1, 0x0, ...) /Users/kv2/Project/go/go1.16.10/src/net/ipsock_posix.go:141 +0x145 net.(*sysDialer).doDialTCP(0xc004923b80, 0x103f6c8, 0xc0052285a0, 0x0, 0xc00a6f06c0, 0xb7b7e0, 0x18aaf98, 0x0) /Users/kv2/Project/go/go1.16.10/src/net/tcpsock_posix.go:65 +0xc5 net.(*sysDialer).dialTCP(0xc004923b80, 0x103f6c8, 0xc0052285a0, 0x0, 0xc00a6f06c0, 0x46bcc7, 0x4055fd, 0x60) /Users/kv2/Project/go/go1.16.10/src/net/tcpsock_posix.go:61 +0xd7 net.(*sysDialer).dialSingle(0xc004923b80, 0x103f6c8, 0xc0052285a0, 0x1038b40, 0xc00a6f06c0, 0x0, 0x0, 0x0, 0x0) /Users/kv2/Project/go/go1.16.10/src/net/dial.go:580 +0x5e8 net.(*sysDialer).dialSerial(0xc004923b80, 0x103f6c8, 0xc0052285a0, 0xc013ccd2a0, 0x1, 0x1, 0x0, 0x0, 0x0, 0x0) /Users/kv2/Project/go/go1.16.10/src/net/dial.go:548 +0x15e net.(*Dialer).DialContext(0xc009bffc90, 0x103f6c8, 0xc0052285a0, 0xc39a52, 0x3, 0xc00ae4ce70, 0x13, 0x0, 0x0, 0x0, ...) /Users/kv2/Project/go/go1.16.10/src/net/dial.go:425 +0x6e5 net.(*Dialer).Dial(...) /Users/kv2/Project/go/go1.16.10/src/net/dial.go:348 net.DialTimeout(0xc39a52, 0x3, 0xc00ae4ce70, 0x13, 0xb2d05e00, 0x40dbd2, 0x7fbf2af59f40, 0xc00ae4ce70, 0x18) /Users/kv2/Project/go/go1.16.10/src/net/dial.go:334 +0xba kscan/lib/gonmap/simplenet.Send(0xc39a52, 0x3, 0xc00ae4ce70, 0x13, 0x0, 0x0, 0xb2d05e00, 0x0, 0x0, 0x0, ...) /Users/kv2/Project/Gkscan/lib/gonmap/simplenet/simplenet.go:14 +0xaf kscan/lib/gonmap.PortScan(0xc39a52, 0x3, 0xc00ae4ce70, 0x13, 0xb2d05e00, 0xc00ae4ce70) /Users/kv2/Project/Gkscan/lib/gonmap/portscan.go:12 +0x71 kscan/run.(*kscan).PortDiscovery.func3(0xbde220, 0xc007c7d240, 0x124, 0x1) /Users/kv2/Project/Gkscan/run/type-kscan.go:225 +0x14f kscan/lib/pool.NewWorker.func1(0xbde220, 0xc007c7d240, 0x0, 0x0, 0x0, 0x0) /Users/kv2/Project/Gkscan/lib/pool/pool.go:28 +0x82 kscan/lib/pool.(*Worker).Run(...) /Users/kv2/Project/Gkscan/lib/pool/pool.go:36 kscan/lib/pool.(*Pool).work(0xc004e5df90) /Users/kv2/Project/Gkscan/lib/pool/pool.go:92 +0x185 created by kscan/lib/pool.(*Pool).Run /Users/kv2/Project/Gkscan/lib/pool/pool.go:110 +0x79

  • new finger

    new finger

    Server: Symantec Endpoint Protection Manager

    Server: XDaemon v1.0

    Server:

    Server: SEPM

    Server: [email protected]

    Server: NSFOCUS

    Server: gSOAP/2.8

Related tags