Закинул общий репозиторий
This commit is contained in:
parent
40566525c1
commit
96be2f59a7
12
README.md
12
README.md
@ -1 +1,11 @@
|
|||||||
# SynAck
|
# SynAck (Port Scanner)
|
||||||
|
|
||||||
|
## Core team:
|
||||||
|
*danabolik and FalloutBaby*
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
`go run ./cmd/main.go {domain/ip_address} {count gorutines}`
|
||||||
|
>You may request certain address and amount of concurrent requests.
|
||||||
|
By default, they are `scanme.nmap.org` and `8`
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
BIN
assets/gomem.gif
Normal file
BIN
assets/gomem.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 214 KiB |
20
cmd/main.go
Normal file
20
cmd/main.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"SynAck/internal/app"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
addr, grt := "scanme.nmap.org", "8"
|
||||||
|
switch true {
|
||||||
|
case len(os.Args) == 2:
|
||||||
|
addr = os.Args[1]
|
||||||
|
break
|
||||||
|
case len(os.Args) >= 3:
|
||||||
|
addr, grt = os.Args[1], os.Args[2]
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
app.Run(addr, grt)
|
||||||
|
}
|
||||||
12
go.mod
Normal file
12
go.mod
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module SynAck
|
||||||
|
|
||||||
|
go 1.18
|
||||||
|
|
||||||
|
require github.com/stretchr/testify v1.7.1
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/stretchr/objx v0.1.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||||
|
)
|
||||||
12
go.sum
Normal file
12
go.sum
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
29
internal/app/app.go
Normal file
29
internal/app/app.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package app
|
||||||
|
|
||||||
|
import (
|
||||||
|
"SynAck/internal/delivery"
|
||||||
|
"SynAck/internal/services/decorators"
|
||||||
|
"SynAck/internal/services/producers"
|
||||||
|
"SynAck/internal/services/workers"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type App struct {
|
||||||
|
dialer decorators.NetDialer
|
||||||
|
decorator decorators.NetDecorator
|
||||||
|
producer producers.Generator
|
||||||
|
delivery delivery.Http
|
||||||
|
}
|
||||||
|
|
||||||
|
func Run(addr string, grt string) {
|
||||||
|
app := new(App)
|
||||||
|
decorator := decorators.NetDecorator{Dialer: app.dialer}
|
||||||
|
|
||||||
|
count, _ := strconv.Atoi(grt)
|
||||||
|
worker := workers.Worker{Decorator: decorator, Delivery: app.delivery, Producer: app.producer}
|
||||||
|
openPs := worker.ScanPorts(addr, count)
|
||||||
|
|
||||||
|
fmt.Println(openPs)
|
||||||
|
fmt.Println("Збазиба!")
|
||||||
|
}
|
||||||
12
internal/delivery/Http.go
Normal file
12
internal/delivery/Http.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package delivery
|
||||||
|
|
||||||
|
type Delivery interface {
|
||||||
|
GetTcpNetwork() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Http struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (http Http) GetTcpNetwork() string {
|
||||||
|
return "tcp"
|
||||||
|
}
|
||||||
10
internal/delivery/Http_test.go
Normal file
10
internal/delivery/Http_test.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package delivery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHttp_GetNetwork(t *testing.T) {
|
||||||
|
assert.Equal(t, "tcp", Http{}.GetTcpNetwork())
|
||||||
|
}
|
||||||
40
internal/services/decorators/NetDial.go
Normal file
40
internal/services/decorators/NetDial.go
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package decorators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Dialer interface {
|
||||||
|
DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetDialer struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d NetDialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
return net.DialTimeout(network, address, timeout)
|
||||||
|
}
|
||||||
|
|
||||||
|
type DialerDecorator interface {
|
||||||
|
DialPort(network, addr string, p int) int
|
||||||
|
}
|
||||||
|
|
||||||
|
type NetDecorator struct {
|
||||||
|
Dialer Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d NetDecorator) DialPort(network, addr string, p int) int {
|
||||||
|
timeout := time.Second
|
||||||
|
c, err := d.Dialer.DialTimeout(network, addr+":"+strconv.Itoa(p), timeout)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
} else {
|
||||||
|
err = c.Close()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
103
internal/services/decorators/NetDial_test.go
Normal file
103
internal/services/decorators/NetDial_test.go
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package decorators
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"net"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ConnStub struct {
|
||||||
|
isClosed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c ConnStub) Read(b []byte) (n int, err error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) Write(b []byte) (n int, err error) {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) Close() error {
|
||||||
|
if c.isClosed {
|
||||||
|
return errors.New("failed close connection")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) LocalAddr() net.Addr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) RemoteAddr() net.Addr {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) SetDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) SetReadDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func (c ConnStub) SetWriteDeadline(t time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type TestDialer struct {
|
||||||
|
isOpen bool
|
||||||
|
conn ConnStub
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d TestDialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
if !d.isOpen {
|
||||||
|
return d.conn, errors.New("failed connection")
|
||||||
|
}
|
||||||
|
return d.conn, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type dialAllDataProvider struct {
|
||||||
|
dialer TestDialer
|
||||||
|
network string
|
||||||
|
address string
|
||||||
|
port int
|
||||||
|
openPort int
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNetDial_DialPort(t *testing.T) {
|
||||||
|
provider := []dialAllDataProvider{
|
||||||
|
{
|
||||||
|
TestDialer{isOpen: true, conn: ConnStub{isClosed: false}},
|
||||||
|
"tcp",
|
||||||
|
"scanme.nmap.org",
|
||||||
|
80,
|
||||||
|
80,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TestDialer{isOpen: false, conn: ConnStub{isClosed: false}},
|
||||||
|
"tcp",
|
||||||
|
"scanme.nmap.org",
|
||||||
|
443,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, p := range provider {
|
||||||
|
ps := NetDecorator{p.dialer}.DialPort(p.network, p.address, p.port)
|
||||||
|
assert.Equal(t, p.openPort, ps)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type PanicDataProvider struct {
|
||||||
|
dialer TestDialer
|
||||||
|
network string
|
||||||
|
address string
|
||||||
|
port int
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNetDial_DialPortWhenPanic(t *testing.T) {
|
||||||
|
p := PanicDataProvider{
|
||||||
|
TestDialer{isOpen: true, conn: ConnStub{isClosed: true}},
|
||||||
|
"tcp",
|
||||||
|
"scanme.nmap.org",
|
||||||
|
664,
|
||||||
|
}
|
||||||
|
assert.Panics(t, func() {
|
||||||
|
NetDecorator{p.dialer}.DialPort(p.network, p.address, p.port)
|
||||||
|
})
|
||||||
|
}
|
||||||
20
internal/services/producers/Producer.go
Normal file
20
internal/services/producers/Producer.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package producers
|
||||||
|
|
||||||
|
type Producer interface {
|
||||||
|
WritePsToChan(psChan chan int)
|
||||||
|
GetCountPorts() int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Generator struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Generator) WritePsToChan(psChan chan int) {
|
||||||
|
for i := 1; i <= cap(psChan); i++ {
|
||||||
|
psChan <- i
|
||||||
|
}
|
||||||
|
close(psChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Generator) GetCountPorts() int {
|
||||||
|
return 65536
|
||||||
|
}
|
||||||
21
internal/services/producers/Producer_test.go
Normal file
21
internal/services/producers/Producer_test.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package producers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerator_WritePsToChan(t *testing.T) {
|
||||||
|
cntPs := 10
|
||||||
|
psChan := make(chan int, cntPs)
|
||||||
|
|
||||||
|
g := Generator{}
|
||||||
|
g.WritePsToChan(psChan)
|
||||||
|
for i := 1; i <= cntPs; i++ {
|
||||||
|
assert.Equal(t, i, <-psChan)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerator_GetCountPorts(t *testing.T) {
|
||||||
|
assert.Equal(t, 65536, Generator{}.GetCountPorts())
|
||||||
|
}
|
||||||
42
internal/services/workers/Worker.go
Normal file
42
internal/services/workers/Worker.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"SynAck/internal/delivery"
|
||||||
|
"SynAck/internal/services/decorators"
|
||||||
|
"SynAck/internal/services/producers"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Worker struct {
|
||||||
|
Decorator decorators.DialerDecorator
|
||||||
|
Delivery delivery.Delivery
|
||||||
|
Producer producers.Producer
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w Worker) ScanPorts(addr string, grt int) []int {
|
||||||
|
tcp := w.Delivery.GetTcpNetwork()
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
|
||||||
|
psChan := make(chan int, w.Producer.GetCountPorts())
|
||||||
|
go w.Producer.WritePsToChan(psChan)
|
||||||
|
var m sync.Mutex
|
||||||
|
|
||||||
|
var result []int
|
||||||
|
for i := 0; i < grt; i++ {
|
||||||
|
wg.Add(1)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
for p := range psChan {
|
||||||
|
dial := w.Decorator.DialPort(tcp, addr, p)
|
||||||
|
if dial != 0 {
|
||||||
|
m.Lock()
|
||||||
|
result = append(result, dial)
|
||||||
|
m.Unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
86
internal/services/workers/Worker_test.go
Normal file
86
internal/services/workers/Worker_test.go
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package workers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DialerStub struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeliveryStub struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProducerStub struct {
|
||||||
|
psChan chan int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps ProducerStub) WritePsToChan(psChan chan int) {
|
||||||
|
for i := 1; i <= cap(psChan); i++ {
|
||||||
|
psChan <- i
|
||||||
|
}
|
||||||
|
close(psChan)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ps ProducerStub) GetCountPorts() int {
|
||||||
|
return 5
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ds DeliveryStub) GetTcpNetwork() string {
|
||||||
|
return "tcp"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DialerStub) DialPort(network, addr string, p int) int {
|
||||||
|
args := d.Called(network, addr, p)
|
||||||
|
return args.Int(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScanPorts(t *testing.T) {
|
||||||
|
addr := "scanme.nmap.org"
|
||||||
|
grt := 5
|
||||||
|
|
||||||
|
delivery := DeliveryStub{}
|
||||||
|
|
||||||
|
dialer := &DialerStub{}
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Once().Return(1)
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Once().Return(2)
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Once().Return(3)
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Once().Return(4)
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Once().Return(5)
|
||||||
|
|
||||||
|
producer := ProducerStub{}
|
||||||
|
psChan := make(chan int, producer.GetCountPorts())
|
||||||
|
|
||||||
|
w := Worker{Decorator: dialer, Delivery: delivery, Producer: &producer}
|
||||||
|
|
||||||
|
producer.WritePsToChan(psChan)
|
||||||
|
result := w.ScanPorts(addr, grt)
|
||||||
|
|
||||||
|
exp := []int{1, 2, 3, 4, 5}
|
||||||
|
for _, act := range result {
|
||||||
|
assert.Contains(t, exp, act)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScanPortsWhenEmpty(t *testing.T) {
|
||||||
|
addr := "scanme.nmap.org"
|
||||||
|
grt := 5
|
||||||
|
|
||||||
|
producer := ProducerStub{}
|
||||||
|
cntPs := producer.GetCountPorts()
|
||||||
|
|
||||||
|
delivery := DeliveryStub{}
|
||||||
|
|
||||||
|
dialer := &DialerStub{}
|
||||||
|
dialer.On("DialPort", delivery.GetTcpNetwork(), addr, mock.Anything).Times(cntPs).Return(0)
|
||||||
|
psChan := make(chan int, cntPs)
|
||||||
|
|
||||||
|
w := Worker{Decorator: dialer, Delivery: delivery, Producer: &producer}
|
||||||
|
|
||||||
|
producer.WritePsToChan(psChan)
|
||||||
|
result := w.ScanPorts(addr, grt)
|
||||||
|
|
||||||
|
assert.Empty(t, result)
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user