Закинул общий репозиторий

This commit is contained in:
Vladislav Karmishkin 2022-04-13 20:45:14 +03:00
parent 40566525c1
commit 96be2f59a7
14 changed files with 418 additions and 1 deletions

View File

@ -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`
![img.png](assets/gomem.gif)

BIN
assets/gomem.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

20
cmd/main.go Normal file
View 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
View 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
View 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
View 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
View File

@ -0,0 +1,12 @@
package delivery
type Delivery interface {
GetTcpNetwork() string
}
type Http struct {
}
func (http Http) GetTcpNetwork() string {
return "tcp"
}

View 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())
}

View 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
}
}

View 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)
})
}

View 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
}

View 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())
}

View 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
}

View 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)
}