Skip to content

Commit

Permalink
v0.2.2
Browse files Browse the repository at this point in the history
- The -i option supports IP range scanning, such as 1.2.3.4/24
- The -p option supports custom scan ports, such as 80,8000-8009
- The -V option outputs all scan information, disabled by default, only outputting results
- The -F option help you to filter the result with http status code
- Fixed a bug where the progress bar would still be displayed when no parameters were given
- Added some informative output
  • Loading branch information
cckuailong committed Aug 14, 2023
1 parent 50469b8 commit b889677
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
version: latest
version: 1.18.0
args: release --rm-dist
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,26 @@ hostscan --help
Usage of hostscan:
-D string
Hosts in file to test
-F string
Filter result with List of Response Status Code.
Example: 200,201,302
-I string
Nginx Ip in file to test
-O string
Output File (default "result.txt")
-T int
Thread for Http connection. (default 3)
-U Open to send random UserAgent to avoid bot detection.
-V Output All scan Info.
Default is false, only output the result with title.
-d string
Host to test
-i string
Nginx IP
Nginx IP.
Example: 1.1.1.1 or 1.2.3.4/24
-p string
Port List of Nginx IP. If the flag is set, hostscan will ignore the port in origin IP input.
Example: 80,8080,8000-8009
-t int
Timeout for Http connection. (default 5)
-v Show hostscan version
Expand Down Expand Up @@ -136,6 +145,16 @@ server {

Simple Nginx Web Page.

## ChangeLog

v0.2.2
- The -i option supports IP range scanning, such as 1.2.3.4/24
- The -p option supports custom scan ports, such as 80,8000-8009
- The -V option outputs all scan information, disabled by default, only outputting results
- The -F option help you to filter the result with http status code
- Fixed a bug where the progress bar would still be displayed when no parameters were given
- Added some informative output

## References

[Fofapro's Hosts_scan](https://github.com/fofapro/Hosts_scan)
21 changes: 20 additions & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,26 @@ hostscan --help
Usage of hostscan:
-D string
Hosts in file to test
-F string
Filter result with List of Response Status Code.
Example: 200,201,302
-I string
Nginx Ip in file to test
-O string
Output File (default "result.txt")
-T int
Thread for Http connection. (default 3)
-U Open to send random UserAgent to avoid bot detection.
-V Output All scan Info.
Default is false, only output the result with title.
-d string
Host to test
-i string
Nginx IP
Nginx IP.
Example: 1.1.1.1 or 1.2.3.4/24
-p string
Port List of Nginx IP. If the flag is set, hostscan will ignore the port in origin IP input.
Example: 80,8080,8000-8009
-t int
Timeout for Http connection. (default 5)
-v Show hostscan version
Expand Down Expand Up @@ -140,6 +149,16 @@ server {

简单的nginx初始页面

## ChangeLog

v0.2.2
- -i选项支持IP段扫描,1.2.3.4/24
- -p选项支持自定义扫描端口,如 80,8000-8009
- -V选项输出所有扫描信息,默认关闭,只输出结果
- -F选项用于根据http响应状态码筛选结果
- 修复无参数时,进度条也会显示的bug
- 增加一些提示性输出

## 参考链接

[Fofapro 的 Hosts_scan](https://github.com/fofapro/Hosts_scan)
84 changes: 56 additions & 28 deletions core/hostscan.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import (
)


func calcTaskTotal(taskType string) int{
func calcTaskTotal(taskType string, SingleIpCnt int) int{
var err error
var ipCnt, hostCnt, schemeCnt int
schemeCnt = len(vars.Schemes)
if taskType == "ip_host" {
ipCnt = 1
ipCnt = SingleIpCnt
hostCnt = 1
}else if taskType == "ipfile_host" {
ipCnt, err = utils.LineCounter(*vars.IpFile)
Expand All @@ -29,7 +29,7 @@ func calcTaskTotal(taskType string) int{
}
hostCnt = 1
}else if taskType == "ip_hostfile" {
ipCnt = 1
ipCnt = SingleIpCnt
hostCnt, err = utils.LineCounter(*vars.HostFile)
if err != nil{
elog.Error(fmt.Sprintf("Get Lines Count[%s]: %v", *vars.HostFile, err))
Expand All @@ -50,12 +50,23 @@ func calcTaskTotal(taskType string) int{
return 0
}

return ipCnt * hostCnt * schemeCnt
totalTask := ipCnt * hostCnt * schemeCnt

elog.Info(fmt.Sprintf("Total Task: %d || Ip: %d, Host: %d, Scheme:%d", totalTask, ipCnt, hostCnt, schemeCnt))

return totalTask
}

func Scan(taskType string) error{
wg := sync.WaitGroup{}
totalTask := calcTaskTotal(taskType)
ip_list := []string{}
if strings.Contains(*vars.Ip, "/"){
ip_list = HandleIpRange(*vars.Ip)
}else{
ip_list = append(ip_list, *vars.Ip)
}

totalTask := calcTaskTotal(taskType, len(ip_list))

if totalTask == 0{
elog.Error(fmt.Sprintf("Get Lines Count: 0"))
Expand Down Expand Up @@ -86,14 +97,20 @@ func Scan(taskType string) error{
}

if taskType == "ip_host" {
for _, scheme := range vars.Schemes {
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, *vars.Ip),
Host: *vars.Host,
for _,ip := range ip_list{
for _, scheme := range vars.Schemes {
handled_set := HandleCustomPorts(*vars.Host, ip)
for _,item := range handled_set{
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, item.IP),
Host: item.Host,
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}

}else if taskType == "ipfile_host" {
ip_f, err := os.Open(*vars.IpFile)
defer ip_f.Close()
Expand All @@ -113,12 +130,15 @@ func Scan(taskType string) error{
}

for _, scheme := range vars.Schemes {
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, ip),
Host: *vars.Host,
handled_set := HandleCustomPorts(*vars.Host, ip)
for _,item := range handled_set{
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, item.IP),
Host: item.Host,
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
}
}else if taskType == "ip_hostfile" {
Expand All @@ -137,15 +157,20 @@ func Scan(taskType string) error{
}
return err
}

for _, scheme := range vars.Schemes {
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, *vars.Ip),
Host: host,
for _,ip := range ip_list{
for _, scheme := range vars.Schemes {
handled_set := HandleCustomPorts(host, ip)
for _,item := range handled_set{
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, item.IP),
Host: item.Host,
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}

}
}else if taskType == "ipfile_hostfile" {
ip_f, err := os.Open(*vars.IpFile)
Expand Down Expand Up @@ -183,12 +208,15 @@ func Scan(taskType string) error{
}

for _, scheme := range vars.Schemes {
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, ip),
Host: host,
handled_set := HandleCustomPorts(host, ip)
for _,item := range handled_set{
task := Task{
Uri: fmt.Sprintf("%s://%s", scheme, item.IP),
Host: item.Host,
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
// 生产者,不断地往taskChan channel发送数据,直到channel阻塞
taskChan <- task
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions core/task.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,25 @@ func goScan(taskChan chan Task, wg *sync.WaitGroup){
} else {
vars.ProcessBar.Add(1)
body := utils.GetHttpBody(task.Uri, task.Host)
if len(body) == 0{
if *vars.Verbose {
elog.Info(fmt.Sprintf("Uri: %s, Host: %s --> No Response Body", task.Uri, task.Host))
}
continue
}
title := getTitle(body)
var result models.Result
result.Uri = task.Uri
result.Host = task.Host
result.Title = title
resultStr, _ := json.Marshal(result)
if len(title) > 0{
elog.Notice(fmt.Sprintf("Uri: %s, Host: %s --> %s", task.Uri, task.Host, title))
elog.Notice(fmt.Sprintf("Uri: %s, Host: %s <==> %s", task.Uri, task.Host, title))
utils.WriteLine(string(resultStr), *vars.OutFile)
}else{
elog.Warn(fmt.Sprintf("Uri: %s, Host: %s No title found", task.Uri, task.Host))
if *vars.Verbose{
elog.Warn(fmt.Sprintf("Uri: %s, Host: %s --> No title found", task.Uri, task.Host))
}
}
}
}
Expand Down
107 changes: 106 additions & 1 deletion core/type.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
package core

import (
"fmt"
"hostscan/vars"
"net"
"sort"
"strconv"
"strings"
)


const PORTMAX = 65535
const PORTMIN = 1

func GetTaskType() string{
if len(*vars.Ip) == 0 && len(*vars.IpFile) == 0{
Expand All @@ -31,3 +37,102 @@ func GetTaskType() string{

return "N/A"
}

func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}

func HandleIpRange(ipRange string) []string{
ip, ipNet, err := net.ParseCIDR(ipRange)
if err != nil {
return []string{}
}

var ips []string
for ip := ip.Mask(ipNet.Mask); ipNet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
// Remove network address and broadcast address
return ips[1 : len(ips)-1]
}

func parsePort(ports string) []int {
var scanPorts []int
slices := strings.Split(ports, ",")
var start_str, end_str string
for _, port := range slices {
port = strings.Trim(port, " ")
if len(port) == 0{
continue
}
if strings.Contains(port, "-") {
ranges := strings.Split(port, "-")
if len(ranges) < 2 {
continue
}
sort.Strings(ranges)
start_str = ranges[0]
end_str = ranges[1]
start, err := strconv.Atoi(start_str)
if err != nil{
continue
}
end, err := strconv.Atoi(end_str)
if err != nil{
continue
}
if start < PORTMIN{
start = PORTMIN
}
if end > PORTMAX{
end = PORTMAX
}
for i := start; i <= end; i++ {
scanPorts = append(scanPorts, i)
}
}else{
target_port, err := strconv.Atoi(port)
if err == nil{
scanPorts = append(scanPorts, target_port)
}
}

}
return scanPorts
}

type TaskInput struct {
Host string
IP string
}

func HandleCustomPorts(host, ip string) []TaskInput{
handled_set := []TaskInput{}
clear_ip := strings.Split(ip, ":")[0]

iports := parsePort(*vars.Iports)

if len(iports) > 0 {
for _,iport := range iports{
handled_set = append(handled_set, TaskInput{
Host: host,
IP: fmt.Sprintf("%s:%d", clear_ip, iport),
})
}
}else{
handled_set = append(handled_set, TaskInput{
Host: host,
IP: ip,
})
}

//fmt.Println(handled_set)

return handled_set
}

Loading

0 comments on commit b889677

Please sign in to comment.