├── images
├── pegasus.png
└── recent.png
├── src
├── helper
│ ├── version.go
│ ├── ascii.go
│ └── helper.go
├── network
│ ├── sniffing
│ │ └── packet_sniffer.go
│ ├── network_tools.go
│ └── scanning
│ │ └── port_scanner.go
├── cmd
│ └── cmd.go
├── osint
│ └── osint_tools.go
└── shell.go
├── Dockerfile
├── go.mod
├── main.go
├── COPYING
├── install
└── install-pcap
├── go.sum
└── README.md
/images/pegasus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nebrix/Pegasus/HEAD/images/pegasus.png
--------------------------------------------------------------------------------
/images/recent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Nebrix/Pegasus/HEAD/images/recent.png
--------------------------------------------------------------------------------
/src/helper/version.go:
--------------------------------------------------------------------------------
1 | package helper
2 |
3 | func GetVersion() string {
4 | version := "4.4.2"
5 | return version
6 | }
7 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.21
2 |
3 | WORKDIR /app
4 |
5 | COPY . .
6 |
7 | RUN apt-get update && \
8 | apt-get install -y libpcap-dev
9 |
10 | RUN go build -o pegasus
11 |
12 | CMD [ "./pegasus" ]
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module shell
2 |
3 | go 1.21
4 |
5 | require (
6 | github.com/go-ping/ping v1.1.0
7 | github.com/google/gopacket v1.1.19
8 | github.com/likexian/whois v1.15.1
9 | golang.org/x/net v0.23.0
10 | )
11 |
12 | require (
13 | github.com/google/uuid v1.4.0 // indirect
14 | golang.org/x/sync v0.5.0 // indirect
15 | golang.org/x/sys v0.18.0 // indirect
16 | )
17 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | shell "shell/src"
7 | )
8 |
9 | func main() {
10 | styleFlag := flag.String("style", "default", "Specify the shell style")
11 | flag.Parse()
12 |
13 | config := shell.ShellConfig{PromptStyle: *styleFlag}
14 | initializeShell, err := shell.NewShell(config)
15 | if err != nil {
16 | fmt.Printf("Error initializing shell: %v\n", err)
17 | return
18 | }
19 |
20 | initializeShell.Start()
21 | }
22 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Nebrix
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/install/install-pcap:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | os_name=$(cat /etc/os-release | grep PRETTY_NAME | cut -d'"' -f2 | awk '{print $1}')
4 |
5 | case "$os_name" in
6 | "Arch")
7 | # Arch Linux Installer
8 | if command -v pacman &> /dev/null; then
9 | sudo pacman -S --needed --noconfirm libpcap
10 | elif command -v yay &> /dev/null; then
11 | yay -S --needed --noconfirm libpcap
12 | fi
13 | ;;
14 | "Ubuntu" | "Debian" | "LinuxMint" | "elementary" | "Pop")
15 | # Debian-based Linux Installer
16 | if command -v apt-get &> /dev/null; then
17 | sudo apt-get install -y libpcap-dev
18 | fi
19 | ;;
20 | "Fedora" | "RedHat" | "CentOS")
21 | # Redhat-based Linux Installer
22 | if command -v dnf &> /dev/null; then
23 | sudo dnf install -y libpcap-devel
24 | elif command -v yum &> /dev/null; then
25 | sudo yum install -y libpcap-devel
26 | fi
27 | ;;
28 | *)
29 | echo -e "\033[0;31m[-] Unsupported Linux distribuation. Please install libpcap manually.\033[0m"
30 | ;;
31 | esac
32 |
33 | if [ $? -eq 0 ]; then
34 | echo -e "\033[0;32m[+] Install successful!\033[0m"
35 | else
36 | echo -e "\033[0;31m[-] Install failed.\033[0m"
37 | fi
--------------------------------------------------------------------------------
/src/helper/ascii.go:
--------------------------------------------------------------------------------
1 | package helper
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "runtime"
7 | )
8 |
9 | func getUsername() string {
10 | username := os.Getenv("USER")
11 | if username == "" {
12 | username = os.Getenv("LOGNAME")
13 | }
14 | if username == "" {
15 | username = os.Getenv("USERNAME")
16 | }
17 | if username == "" {
18 | username = "Unknown"
19 | }
20 | return username
21 | }
22 |
23 | func retrieveDistributionName() string {
24 | if runtime.GOOS == "windows" {
25 | return "Windows"
26 | } else if runtime.GOOS == "linux" {
27 | return "Linux"
28 | } else {
29 | return "MacOS"
30 | }
31 | }
32 |
33 | func Ascii() {
34 | username := getUsername()
35 | distro := retrieveDistributionName()
36 |
37 | fmt.Println("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⡀⠀⠀⠀⠀⠀")
38 | fmt.Println("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢻⣧⠃⡃⠀⠀⠀⠀⠀")
39 | fmt.Println("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⢿⠇⠏⡇⠀⠀⠀⠀")
40 | fmt.Println("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣟⠏⡜⠰⢣⠀⠀⠀⠀")
41 | fmt.Println("⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡴⠟⣡⠊⡠⢁⣎⠀⠀⠀⠀")
42 | fmt.Println("⠀⠀⢀⣶⣰⡂⠀⠀⠀⠀⣠⠖⠋⡔⠊⡠⢏⡠⢃⡜⠀⠀⠀⠀")
43 | fmt.Println("⠀⠀⡧⣩⠾⢹⣓⣤⠀⠘⣯⡀⠀⣗⣋⣤⢃⠔⢩⠆⠀⠀⠀⠀")
44 | fmt.Println("⠀⣸⣅⠁⢁⡞⠨⡍⢷⢂⡾⠁⣰⠡⠤⣊⠥⠒⠁⠀⠀⠀⠀⠀")
45 | fmt.Println("⠘⠿⠽⠞⢫⠀⠀⠀⢻⠟⣡⡾⠱⡑⠦⠥⣀⣀⣀⠀⠀⠀⠀⠀")
46 | fmt.Println("⠀⠀⠀⠀⡎⢀⠐⠀⠁⠈⠺⠷⠣⠃⠁⡀⠈⢿⡇⠨⢢⠀⠀⠀")
47 | fmt.Println("⠀⠀⠀⢀⡃⠀⠐⠀⠂⠐⠂⢀⠂⠂⠐⢀⠀⡾⢔⢄⠡⣃⠀⠀")
48 | fmt.Printf("⠀ ⢸⡏⠃⠀⠙⣞⡆⠀⠀⠀⠀⠀⠀⣵⡚⠱⣎⣇⠀⠀ username: %v\n", username)
49 | fmt.Printf(" ⠀ ⣿⣷⠄⠀⠀⢹⣽⠀⠀⠀⠀⠀⣼⣳⠃⠀⠹⣾⣤⠀ OS : %v\n", distro)
50 | fmt.Printf("⠀ ⠉⠁⠀⠀⠰⠿⠟⠀⠀⠀⠀⠘⠛⠛⠀⠀⠀⠹⠋ version : %v\n", GetVersion())
51 | }
52 |
--------------------------------------------------------------------------------
/src/network/sniffing/packet_sniffer.go:
--------------------------------------------------------------------------------
1 | package sniffing
2 |
3 | import (
4 | "fmt"
5 | "log"
6 |
7 | "github.com/google/gopacket"
8 | "github.com/google/gopacket/pcap"
9 | )
10 |
11 | func printPacketInfo(packet gopacket.Packet) {
12 | networkLayer := packet.NetworkLayer()
13 | transportLayer := packet.TransportLayer()
14 | applicationLayer := packet.ApplicationLayer()
15 |
16 | fmt.Println("Packet Captured:")
17 | fmt.Printf(" Timestamp: %v\n", packet.Metadata().Timestamp)
18 | fmt.Printf(" Length: %v bytes\n\n", packet.Metadata().CaptureLength)
19 |
20 | if networkLayer != nil {
21 | fmt.Printf(" Network Layer: %v\n", networkLayer.LayerType())
22 | fmt.Printf(" Source IP: %v\n", networkLayer.NetworkFlow().Src())
23 | fmt.Printf(" Dest IP: %v\n\n", networkLayer.NetworkFlow().Dst())
24 | }
25 |
26 | if transportLayer != nil {
27 | fmt.Printf(" Transport Layer: %v\n", transportLayer.LayerType())
28 | fmt.Printf(" Source Port: %v\n", transportLayer.TransportFlow().Src())
29 | fmt.Printf(" Dest Port: %v\n\n", transportLayer.TransportFlow().Dst())
30 | }
31 |
32 | if applicationLayer != nil {
33 | fmt.Printf(" Application Layer: %v\n", applicationLayer.LayerType())
34 | fmt.Printf(" Payload: %v\n\n", applicationLayer.Payload())
35 | }
36 | }
37 |
38 | func PacketSniffer(networkInterface string) {
39 | handle, err := pcap.OpenLive(networkInterface, 1600, true, pcap.BlockForever)
40 | if err != nil {
41 | log.Fatal(err)
42 | }
43 | defer handle.Close()
44 |
45 | packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
46 |
47 | for packet := range packetSource.Packets() {
48 | printPacketInfo(packet)
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/cmd/cmd.go:
--------------------------------------------------------------------------------
1 | package cmd
2 |
3 | import (
4 | "fmt"
5 | "shell/src/helper"
6 | "shell/src/network"
7 | "shell/src/network/scanning"
8 | "shell/src/network/sniffing"
9 | "shell/src/osint"
10 | "strconv"
11 | "time"
12 | )
13 |
14 | func Traceroute(arguments []string) {
15 | network.Traceroute(arguments[0])
16 | }
17 |
18 | func Webheader(arguments []string) {
19 | osint.HeaderRetrieve(arguments[0])
20 | }
21 |
22 | func PortScanner(arguments []string) {
23 | scanning.PortScanner(arguments[0])
24 | }
25 |
26 | func Ping(arguments []string) {
27 | host, count := arguments[0], 0
28 | if len(arguments) > 1 {
29 | count, _ = strconv.Atoi(arguments[1])
30 | }
31 |
32 | network.Ping(host, count, 2*time.Second)
33 | }
34 |
35 | func Whois(arguments []string) {
36 | osint.Getwhois(arguments[0])
37 | }
38 |
39 | func Hash(arguments []string) {
40 | method, data := arguments[0], arguments[1]
41 |
42 | switch method {
43 | case "md5", "sha1", "sha256", "sha512":
44 | network.Hash(method, data)
45 | case "decode":
46 | fmt.Printf("Hash Algorithm: %s\n", network.DecodeHash(data))
47 | default:
48 | helper.HandleWarn("Unsupported hash method", method)
49 | }
50 | }
51 |
52 | func ShowIP() {
53 | osint.ShowIP()
54 | }
55 |
56 | func ShowSubnet(arguments []string) {
57 | if cidr, err := strconv.Atoi(arguments[1]); !helper.HandleErr("Invalid CIDR", err) {
58 | network.ShowCalculation(arguments[0], cidr)
59 | }
60 | }
61 |
62 | func GetDNSRecords(arguments []string) {
63 | osint.GetDNSRecords(arguments[0])
64 | }
65 |
66 | func GetIPInfo(arguments []string) {
67 | osint.GetIpInfo(arguments[0])
68 | }
69 |
70 | func ShowSnifferPackets(arguments []string) {
71 | sniffing.PacketSniffer(arguments[0])
72 | }
73 |
--------------------------------------------------------------------------------
/src/helper/helper.go:
--------------------------------------------------------------------------------
1 | package helper
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "os/exec"
7 | "runtime"
8 | "sort"
9 | "strings"
10 | )
11 |
12 | var (
13 | RESET = "\033[0m"
14 | ERROR = "\033[31m"
15 | WARNING = "\033[33m"
16 | )
17 |
18 | func init() {
19 | if runtime.GOOS == "windows" {
20 | if os.Stdout == nil || os.Stdout == os.Stderr {
21 | RESET = ""
22 | ERROR = ""
23 | WARNING = ""
24 | }
25 | }
26 | }
27 |
28 | func ExtractUsername(p string) string {
29 | usernameParts := strings.Split(p, "\\")
30 | if len(usernameParts) > 1 {
31 | return usernameParts[1]
32 | }
33 | return p
34 | }
35 |
36 | func GetGitBranch(directory string) string {
37 | cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
38 | cmd.Dir = directory
39 |
40 | output, err := cmd.Output()
41 | if err != nil {
42 | return ""
43 | }
44 |
45 | return strings.TrimSpace(string(output))
46 | }
47 |
48 | func MainHelp() {
49 | fmt.Println("Available Commands:")
50 | printCommandHelp("ping", "ICMP Ping", "Send ICMP echo requests to check the reachability of a host and measure round-trip times.")
51 | printCommandHelp("hash", "Hash", "Generate a cryptographic hash value for a given input.")
52 | printCommandHelp("subnet", "Subnet Calculator", "Calculate subnet details, including network and broadcast addresses, and IP ranges.")
53 | printCommandHelp("sniff", "Packet Sniffer", "Capture and analyze network packets on a specified interface.")
54 | printCommandHelp("traceroute", "Traceroute", "Reveal the network path and measure transit times of packets to a destination IP address.")
55 | printCommandHelp("scan", "Port Scanner", "Scan for open ports on a specified IP address or domain.")
56 | }
57 |
58 | func OsintHelp() {
59 | fmt.Println("Available Commands:")
60 | printCommandHelp("dig", "DNS Enumeration", "Perform DNS enumeration on a domain to gather information about its DNS records.")
61 | printCommandHelp("whois", "WHOIS Lookup", "Retrieve detailed registration information for a domain, including contact details.")
62 | printCommandHelp("lookup", "IP Lookup", "Retrieve basic information about an IP address, such as its geolocation and ISP.")
63 | printCommandHelp("webheader", "Website Header", "Retrieve basic header information via a HTTP web request")
64 | printCommandHelp("ip", "IP Addresses", "Display local and public IP addresses for the currently connected network.")
65 | }
66 |
67 | func printCommandHelp(command, title, description string) {
68 | fmt.Printf(" - %v (%v):\n\t%v\n", command, title, description)
69 | }
70 |
71 | func HandleErr(msg string, err error) bool {
72 | if err != nil {
73 | fmt.Printf(ERROR+"%v: %v\n"+RESET, msg, err)
74 | return true
75 | }
76 | return false
77 | }
78 |
79 | func HandleWarn(msg string, p string) bool {
80 | fmt.Printf(WARNING+"%v: %v\n"+RESET, msg, p)
81 | return true
82 | }
83 |
84 | func OSReadDir(root string) ([]string, error) {
85 | var files []string
86 | dirEntries, err := os.ReadDir(root)
87 | if HandleErr("", err) {
88 | return nil, err
89 | }
90 |
91 | for _, dirEntry := range dirEntries {
92 | if dirEntry.IsDir() {
93 | files = append(files, dirEntry.Name()+"/")
94 | } else {
95 | files = append(files, dirEntry.Name())
96 | }
97 | }
98 |
99 | sort.Strings(files)
100 |
101 | return files, nil
102 | }
103 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/go-ping/ping v1.1.0 h1:3MCGhVX4fyEUuhsfwPrsEdQw6xspHkv5zHsiSoDFZYw=
2 | github.com/go-ping/ping v1.1.0/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk=
3 | github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
4 | github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
5 | github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
6 | github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
7 | github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
8 | github.com/likexian/gokit v0.25.13 h1:p2Uw3+6fGG53CwdU2Dz0T6bOycdb2+bAFAa3ymwWVkM=
9 | github.com/likexian/gokit v0.25.13/go.mod h1:qQhEWFBEfqLCO3/vOEo2EDKd+EycekVtUK4tex+l2H4=
10 | github.com/likexian/whois v1.15.1 h1:6vTMI8n9s1eJdmcO4R9h1x99aQWIZZX1CD3am68gApU=
11 | github.com/likexian/whois v1.15.1/go.mod h1:/nxmQ6YXvLz+qTxC/QFtEJNAt0zLuRxJrKiWpBJX8X0=
12 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
13 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
14 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
15 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
16 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
17 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
18 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
19 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
20 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
21 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
22 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
23 | golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
24 | golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
25 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
26 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
27 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
28 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
29 | golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
30 | golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
31 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
32 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
33 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
34 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
35 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
36 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
37 |
--------------------------------------------------------------------------------
/src/osint/osint_tools.go:
--------------------------------------------------------------------------------
1 | package osint
2 |
3 | import (
4 | "fmt"
5 | "io"
6 | "net"
7 | "net/http"
8 | "os"
9 | "strings"
10 |
11 | "github.com/likexian/whois"
12 | )
13 |
14 | func GetDNSRecords(host string) {
15 | addrs, err := net.LookupHost(host)
16 | if err != nil {
17 | fmt.Println("Error resolving A records:", err)
18 | } else {
19 | fmt.Printf("A (IPv4) addresses for %v:\n", host)
20 | for _, addr := range addrs {
21 | fmt.Println(addr)
22 | }
23 | }
24 |
25 | nsRecords, err := net.LookupNS(host)
26 | if err != nil {
27 | fmt.Println("Error resolving NS records:", err)
28 | } else {
29 | fmt.Printf("NS (Name Server) records for %v:\n", host)
30 | for _, ns := range nsRecords {
31 | fmt.Println(ns.Host)
32 | }
33 | }
34 |
35 | cname, err := net.LookupCNAME(host)
36 | if err != nil {
37 | fmt.Println("Error resolving CNAME records:", err)
38 | } else {
39 | fmt.Printf("CNAME (Canonical Name) for %v: %v\n", host, cname)
40 | }
41 |
42 | txtRecords, err := net.LookupTXT(host)
43 | if err != nil {
44 | fmt.Println("Error resolving TXT records:", err)
45 | } else {
46 | fmt.Printf("TXT (Text) records for %v:\n", host)
47 | for _, txt := range txtRecords {
48 | fmt.Println(txt)
49 | }
50 | }
51 | }
52 |
53 | func getInternalIP() (string, error) {
54 | addrs, err := net.InterfaceAddrs()
55 | if err != nil {
56 | return "", err
57 | }
58 |
59 | for _, addr := range addrs {
60 | if ipnet, ok := addr.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
61 | if ipnet.IP.To4() != nil {
62 | return ipnet.IP.String(), nil
63 | }
64 | }
65 | }
66 |
67 | return "", nil
68 | }
69 |
70 | func getPublicIP() (string, error) {
71 | resp, err := http.Get("https://ifconfig.co/ip")
72 | if err != nil {
73 | return "", err
74 | }
75 | defer resp.Body.Close()
76 |
77 | body, err := io.ReadAll(resp.Body)
78 | if err != nil {
79 | return "", err
80 | }
81 |
82 | publicIP := strings.TrimSpace(string(body))
83 | return publicIP, nil
84 | }
85 |
86 | func ShowIP() {
87 | internalIP, err := getInternalIP()
88 | if err != nil {
89 | fmt.Println("Error getting internal IP:", err)
90 | } else {
91 | fmt.Println("Internal IP:", internalIP)
92 | }
93 |
94 | publicIP, err := getPublicIP()
95 | if err != nil {
96 | fmt.Println("Error getting public IP:", err)
97 | } else {
98 | fmt.Println("Public IP:", publicIP)
99 | }
100 | }
101 |
102 | const (
103 | hostName = "ipinfo.io"
104 | port = "80"
105 | )
106 |
107 | func GetIpInfo(host string) {
108 | path := "/" + host + "/json"
109 | url := "http://" + hostName + ":" + port + path
110 |
111 | resp, err := http.Get(url)
112 | if err != nil {
113 | fmt.Println("Error:", err)
114 | os.Exit(1)
115 | }
116 | defer resp.Body.Close()
117 |
118 | if resp.StatusCode != http.StatusOK {
119 | fmt.Printf("HTTP request failed with status code: %v\n", resp.StatusCode)
120 | os.Exit(1)
121 | }
122 |
123 | buffer := make([]byte, 4096)
124 | for {
125 | n, err := resp.Body.Read(buffer)
126 | if n > 0 {
127 | fmt.Print(string(buffer[:n]))
128 | }
129 | if err != nil {
130 | break
131 | }
132 | }
133 | }
134 |
135 | func Getwhois(host string) {
136 | result, err := whois.Whois(host)
137 | if err == nil {
138 | fmt.Println(result)
139 | }
140 | }
141 |
142 | func getWebsiteHeaders(url string) (http.Header, error) {
143 | response, err := http.Head(url)
144 | if err != nil {
145 | return nil, err
146 | }
147 | defer response.Body.Close()
148 |
149 | return response.Header, nil
150 | }
151 |
152 | func HeaderRetrieve(url string) {
153 | headers, err := getWebsiteHeaders(url)
154 | if err != nil {
155 | fmt.Printf("Error: %v\n", err)
156 | return
157 | }
158 |
159 | fmt.Printf("Headers for %v:\n", url)
160 | for key, values := range headers {
161 | fmt.Printf("%v: %v\n", key, values)
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Pegasus - OS-Based Hacking Shell
2 |
3 |
4 |
5 |
6 |
7 | ## IMPORTANT NOTICE
8 | I want to inform you that we're transitioning the project to a full Docker setup. This move will significantly reduce our concerns, providing a more streamlined and reliable environment. Consequently, the current shell version on the main branch (4.4.2) marks the final update for this branch.
9 |
10 |
11 | - [Introduction](#introduction)
12 | - [Requirements](#requirements)
13 | - [Usage](#usage)
14 | - [Prompt Styles](#prompt-styles)
15 | - [Docker Installation](#docker-installation)
16 | - [Local Install](#local-install)
17 | - [Docker Hub Install](#docker-hub-install)
18 | - [Binary Install](#install-the-binary-recommend)
19 | - [Contribution](#contribution)
20 | - [License](#license)
21 | - [Disclaimer](#disclaimer)
22 | - [Todo](#todo)
23 |
24 |
25 | ## Introduction
26 |
27 | Pegasus is a powerful hacking shell designed for Unix-based operating systems. It provides various tools and functionalities that can be used for security testing and ethical hacking purposes. This tool is intended for educational and responsible use only. Please use it responsibly and with proper authorization.
28 |
29 | ## Requirements
30 |
31 | Linux
32 |
33 | bash install/install-pcap
34 |
35 |
36 |
37 |
38 | Windows
39 |
40 | Install [npcap](https://npcap.com/)
41 |
42 |
43 |
44 | ## Usage
45 |
46 | ### Note
47 | If you install the binary for any OS you will need to make the file a sudo binary
48 | - Linux
49 |
50 | `sudo chown root:root /path/to/your/executable`
51 |
52 | `sudo chmod u+s /path/to/your/executable`
53 |
54 | - Mac
55 |
56 |
57 | `sudo visudo`
58 |
59 | `yourusername ALL=(ALL) NOPASSWD: /path/to/your/executable`
60 |
61 | - Windows
62 |
63 | `Run as Administrator`
64 |
65 | Once Pegasus is successfully installed, you can run it by executing the `go run main.go` command in your terminal:
66 |
67 | 
68 |
69 | If you want a new style prompt run `./pegasus -style=`
70 | ## Prompt styles
71 |
72 | - windows
73 | - root
74 | - zsh, zsh-git
75 | - mac
76 | - hacker
77 |
78 | ## Docker installation
79 |
80 | ### Local install
81 | If you prefer to build the Docker image locally, execute the following commands:
82 |
83 | `docker build -t pegasus .`
84 |
85 | `docker run -it pegasus`
86 |
87 | ### Docker hub install (recommend for arm)
88 | For a more straightforward installation, you can pull the Docker image from Docker Hub:
89 |
90 | `docker pull nebrix/pegasus:4.4.2`
91 |
92 | `docker run -it docker.io/nebrix/pegasus:4.4.2`
93 |
94 | Using the Docker Hub image is the recommended and easier approach for most users.
95 |
96 | ## Install the binary (recommend)
97 |
98 | Download the binary [pegasus](https://github.com/Nebrix/Pegasus/releases)
99 |
100 | ## Todo
101 |
102 | - [X] Whois- [Description: Retrieve detailed registration information for a domain, including contact details]
103 | - [X] DNS - [Description: Perform DNS enumeration on a domain to gather information about its DNS records]
104 | - [X] Hashing - [Description: Generate a cryptographic hash value for a given input]
105 | - [X] IP/IP Information - [Description: Retrieve basic information about an IP address, such as its geolocation and ISP]
106 | - [X] Subnet Calculator - [Description: Calculate subnet details, including network and broadcast addresses, and IP ranges]
107 |
108 | - [X] Port Scanner - [Description: Scan for open ports on a specified IP address or domain]
109 | - [X] Packet Sniffer - [Description: Capture and analyze network packets on a specified interface]
110 | - [ ] Discover WiFi Networks - [Description: Discover networks]
111 |
112 | - [X] Ping - [Description: Send ICMP echo requests to check the reachability of a host and measure round-trip times]
113 | - [X] Traceroute - [Description: Reveal the network path and measure transit times of packets to a destination IP address]
114 | - [X] Web Header - [Description: Retrieve basic header information via an HTTP web request]
115 | - [X] IP Addresses - [Description: Display local and public IP addresses for the currently connected network]
116 |
117 | - [X] Shell Prompt Styles - [Description: Customize the style of the shell prompt]
118 | - [ ] Custom Prompt Styles - [Description: Create custom shell prompts]
119 |
120 | - [X] Install Script - [Description: Installer for libpcap (Unix only)]
121 |
122 | ## Contribution
123 |
124 | If you find any bugs or want to contribute to Pegasus, please feel free to open an issue or submit a pull request on the GitHub repository. We welcome your feedback and suggestions to make this tool even better.
125 |
126 | ## License
127 |
128 | Pegasus is open-source software licensed under the [MIT License](https://github.com/Nebrix/Pegasus/blob/main/COPYING). You are free to use, modify, and distribute this software with proper attribution and in compliance with the license terms.
129 |
130 | ## Disclaimer
131 |
132 | Pegasus is provided for educational and ethical hacking purposes only. The authors and contributors of Pegasus are not responsible for any misuse or illegal activities performed using this tool. Please use it responsibly and in compliance with the laws and regulations of your country.
133 |
--------------------------------------------------------------------------------
/src/network/network_tools.go:
--------------------------------------------------------------------------------
1 | package network
2 |
3 | import (
4 | "crypto/md5"
5 | "crypto/sha1"
6 | "crypto/sha256"
7 | "crypto/sha512"
8 | "encoding/hex"
9 | "fmt"
10 | "hash"
11 | "net"
12 | "os"
13 | "time"
14 |
15 | "golang.org/x/net/icmp"
16 | "golang.org/x/net/ipv4"
17 | )
18 |
19 | const (
20 | md5Size = 16 * 2
21 | sha1Size = 20 * 2
22 | sha256Size = 32 * 2
23 | sha512Size = 64 * 2
24 | )
25 |
26 | func Ping(host string, count int, timeout time.Duration) {
27 | addr, err := net.ResolveIPAddr("ip", host)
28 | if err != nil {
29 | fmt.Println(err.Error())
30 | return
31 | }
32 |
33 | conn, err := net.DialIP("ip4:icmp", nil, addr)
34 | if err != nil {
35 | fmt.Println(err.Error())
36 | return
37 | }
38 | defer conn.Close()
39 |
40 | for i := 1; i <= count; i++ {
41 | msg := make([]byte, 64)
42 | msg[0] = 8
43 | msg[1] = 0
44 | msg[2] = 0
45 | msg[3] = 0
46 | msg[4] = 0
47 | msg[5] = 0
48 | msg[6] = 0
49 | msg[7] = byte(i)
50 | checksum := checkSum(msg)
51 | msg[2] = byte(checksum >> 8)
52 | msg[3] = byte(checksum & 0xFF)
53 |
54 | startTime := time.Now()
55 |
56 | _, err = conn.Write(msg)
57 | if err != nil {
58 | fmt.Println(err)
59 | return
60 | }
61 |
62 | reply := make([]byte, 64)
63 | conn.SetReadDeadline(time.Now().Add(timeout))
64 | _, err = conn.Read(reply)
65 | if err != nil {
66 | fmt.Println("Request timed out")
67 | } else {
68 | duration := time.Since(startTime)
69 | fmt.Printf("Reply from %v: time=%v\n", addr.String(), duration)
70 | }
71 |
72 | time.Sleep(1 * time.Second)
73 | }
74 | }
75 |
76 | func checkSum(msg []byte) uint16 {
77 | sum := uint32(0)
78 | for i := 0; i < len(msg); i += 2 {
79 | sum += uint32(msg[i+1]) | (uint32(msg[i]) << 8)
80 | }
81 | sum = (sum >> 16) + (sum & 0xffff)
82 | sum += (sum >> 16)
83 | return uint16(^sum)
84 | }
85 |
86 | func Hash(method, data string) {
87 | var hasher hash.Hash
88 |
89 | switch method {
90 | case "md5":
91 | hasher = md5.New()
92 | case "sha1":
93 | hasher = sha1.New()
94 | case "sha256":
95 | hasher = sha256.New()
96 | case "sha512":
97 | hasher = sha512.New()
98 | default:
99 | fmt.Printf("Unsupported hash method: %s\n", method)
100 | return
101 | }
102 |
103 | hasher.Write([]byte(data))
104 | hash := hex.EncodeToString(hasher.Sum(nil))
105 | fmt.Printf("%v\n", hash)
106 | }
107 |
108 | func DecodeHash(data string) string {
109 | switch len(data) {
110 | case md5Size:
111 | return "MD5"
112 | case sha1Size:
113 | return "SHA-1"
114 | case sha256Size:
115 | return "SHA-256"
116 | case sha512Size:
117 | return "SHA-512"
118 | default:
119 | return "Unknown"
120 | }
121 | }
122 |
123 | func subnetCalculator(ipAddress string, cidr int) {
124 | ip := net.ParseIP(ipAddress)
125 | if ip == nil {
126 | fmt.Println("Invalid IP address")
127 | return
128 | }
129 |
130 | if cidr < 0 || cidr > 32 {
131 | fmt.Println("Invalid CIDR")
132 | return
133 | }
134 |
135 | ipInt := ipToUint32(ip)
136 | ones, bits := cidr, 32
137 | mask := (1<>24), byte(ipInt>>16), byte(ipInt>>8), byte(ipInt))
164 | }
165 |
166 | func ShowCalculation(host string, cidr int) {
167 | if cidr < 0 || cidr > 32 {
168 | fmt.Println("Invalid CIDR")
169 | os.Exit(1)
170 | }
171 |
172 | subnetCalculator(host, cidr)
173 | }
174 |
175 | func Traceroute(host string) {
176 | fmt.Printf("Traceroute to %v...\n", host)
177 |
178 | ipAddr, err := net.ResolveIPAddr("ip", host)
179 | if err != nil {
180 | fmt.Println("Error resolving target host:", err)
181 | os.Exit(1)
182 | }
183 |
184 | conn, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
185 | if err != nil {
186 | fmt.Println("Error opening scoket:", err)
187 | os.Exit(1)
188 | }
189 | defer conn.Close()
190 |
191 | ttl := 1
192 |
193 | for {
194 | message := icmp.Message{
195 | Type: ipv4.ICMPTypeEcho,
196 | Code: 0,
197 | Body: &icmp.Echo{
198 | ID: os.Getpid() & 0xffff,
199 | Seq: ttl,
200 | Data: []byte(""),
201 | },
202 | }
203 |
204 | messageBytes, err := message.Marshal(nil)
205 | if err != nil {
206 | fmt.Println("Error marshalling ICMP message:", err)
207 | os.Exit(1)
208 | }
209 |
210 | if err := conn.IPv4PacketConn().SetTTL(ttl); err != nil {
211 | fmt.Println("Error setting TTL:", err)
212 | os.Exit(1)
213 | }
214 |
215 | _, err = conn.WriteTo(messageBytes, ipAddr)
216 | if err != nil {
217 | fmt.Println("Error sending ICMP message:", err)
218 | os.Exit(1)
219 | }
220 |
221 | reply := make([]byte, 1500)
222 | _, _, err = conn.ReadFrom(reply)
223 | if err != nil {
224 | fmt.Println("Error receiving ICMP reply:", err)
225 | os.Exit(1)
226 | }
227 |
228 | fmt.Printf("%d. %s\n", ttl, ipAddr.String())
229 |
230 | if ipAddr.String() == host {
231 | break
232 | }
233 |
234 | ttl++
235 |
236 | if ttl > 30 {
237 | fmt.Println("Max hops reached. Exiting.")
238 | break
239 | }
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/src/shell.go:
--------------------------------------------------------------------------------
1 | package shell
2 |
3 | import (
4 | "bufio"
5 | "fmt"
6 | "os"
7 | "os/user"
8 | "path/filepath"
9 | "shell/src/cmd"
10 | "shell/src/helper"
11 | "strings"
12 | )
13 |
14 | const (
15 | WindowsPrompt = "windows"
16 | ZshPrompt = "zsh"
17 | ZshGitPrompt = "zsh-git"
18 | RootPrompt = "root"
19 | MacPrompt = "mac"
20 | HackerPrompt = "hacker"
21 | DefaultPrompt = "default"
22 |
23 | EscapeWindows = "%v> \033[0m"
24 | EscapeZsh = "\033[1;32m➜ \033[1;34m%v\033[0m "
25 | EscapeZshGit = "\033[1;32m➜ \033[1;34m%v \033[31m(%v)\033[0m "
26 | EscapeRoot = "%v# "
27 | EscapeMac = "%v:%v$ "
28 | EscapeHacker = "\033[32m%v=%v?\033[0m "
29 | EscapeDefault = "[%v@%v %v]$ "
30 | )
31 |
32 | type ShellConfig struct {
33 | PromptStyle string
34 | }
35 |
36 | var ShellDefaults = ShellConfig{
37 | PromptStyle: DefaultPrompt,
38 | }
39 |
40 | type Shell struct {
41 | UserInfo UserInfo
42 | ShellConfig ShellConfig
43 | shellName string
44 | }
45 |
46 | type UserInfo struct {
47 | Username string
48 | Directory string
49 | Hostname string
50 | Home string
51 | }
52 |
53 | type OSINTShell struct {
54 | mainShell *Shell
55 | }
56 |
57 | func NewShell(config ShellConfig) (*Shell, error) {
58 | currentUser, err := user.Current()
59 | if err != nil {
60 | return nil, fmt.Errorf("error getting current user: %v", err)
61 | }
62 |
63 | currentWorkingDir, err := os.Getwd()
64 | if err != nil {
65 | return nil, fmt.Errorf("error getting current working directory: %v", err)
66 | }
67 |
68 | hostname, err := os.Hostname()
69 | if err != nil {
70 | return nil, fmt.Errorf("error getting hostname: %v", err)
71 | }
72 |
73 | username := helper.ExtractUsername(currentUser.Username)
74 |
75 | return &Shell{
76 | UserInfo: UserInfo{
77 | Username: username,
78 | Directory: currentWorkingDir,
79 | Hostname: hostname,
80 | Home: currentUser.HomeDir,
81 | },
82 | ShellConfig: config,
83 | shellName: "default",
84 | }, nil
85 | }
86 |
87 | func setPrompt(s *Shell) {
88 | switch strings.ToLower(s.ShellConfig.PromptStyle) {
89 | case WindowsPrompt:
90 | setEscapePrompt(EscapeWindows, s.UserInfo.Directory)
91 | case ZshPrompt:
92 | setEscapePrompt(EscapeZsh, filepath.Base(s.UserInfo.Directory))
93 | case ZshGitPrompt:
94 | gitBranch := helper.GetGitBranch(s.UserInfo.Directory)
95 | setEscapePrompt(EscapeZshGit, filepath.Base(s.UserInfo.Directory), gitBranch)
96 | case RootPrompt:
97 | setEscapePrompt(EscapeRoot, filepath.Base(s.UserInfo.Directory))
98 | case MacPrompt:
99 | setEscapePrompt(EscapeMac, s.UserInfo.Username, filepath.Base(s.UserInfo.Directory))
100 | case HackerPrompt:
101 | setEscapePrompt(EscapeHacker, s.UserInfo.Username, filepath.Base(s.UserInfo.Directory))
102 | default:
103 | setEscapePrompt(EscapeDefault, s.UserInfo.Username, s.UserInfo.Hostname, filepath.Base(s.UserInfo.Directory))
104 | }
105 | }
106 |
107 | func setEscapePrompt(escapeFormat string, args ...interface{}) {
108 | fmt.Printf(escapeFormat, args...)
109 | }
110 |
111 | func (s *Shell) setOSINTPrompt() {
112 | fmt.Printf("[%v %v]$ ", s.shellName, filepath.Base(s.UserInfo.Directory))
113 | }
114 |
115 | func (s *Shell) Start() {
116 | s.commandLine()
117 | }
118 |
119 | func (s *Shell) commandLine() {
120 | reader := bufio.NewReader(os.Stdin)
121 | helper.Ascii()
122 |
123 | for {
124 | setPrompt(s)
125 |
126 | userInput, err := reader.ReadString('\n')
127 | if handleInputError(err) {
128 | continue
129 | }
130 |
131 | args := strings.Fields(userInput)
132 | if len(args) == 0 {
133 | continue
134 | }
135 |
136 | command := args[0]
137 | arguments := args[1:]
138 |
139 | switch command {
140 | case "exit":
141 | os.Exit(0)
142 | case "cls", "clear", "Clear-Host":
143 | clearScreen()
144 | case "cd", "Set-Location":
145 | s.changeDirectory(arguments)
146 | case "ls", "dir":
147 | s.listDirectory()
148 | case "ping":
149 | cmd.Ping(arguments)
150 | case "hash":
151 | cmd.Hash(arguments)
152 | case "subnet":
153 | cmd.ShowSubnet(arguments)
154 | case "sniff":
155 | cmd.ShowSnifferPackets(arguments)
156 | case "scan":
157 | cmd.PortScanner(arguments)
158 | case "traceroute":
159 | cmd.Traceroute(arguments)
160 | case "help", "man":
161 | helper.MainHelp()
162 | case "osint":
163 | s.shellName = "osint"
164 | osintShell := newOSINTShell(s)
165 | osintShell.start()
166 | default:
167 | helper.HandleWarn("Command not found", userInput)
168 | }
169 | }
170 | }
171 |
172 | func (osintShell *OSINTShell) start() {
173 | reader := bufio.NewReader(os.Stdin)
174 | for {
175 | osintShell.mainShell.setOSINTPrompt()
176 |
177 | userInput, err := reader.ReadString('\n')
178 | if handleInputError(err) {
179 | continue
180 | }
181 |
182 | args := strings.Fields(userInput)
183 | if len(args) == 0 {
184 | continue
185 | }
186 |
187 | command := args[0]
188 | arguments := args[1:]
189 |
190 | switch command {
191 | case "exit":
192 | return
193 | case "cls", "clear", "Clear-Host":
194 | clearScreen()
195 | case "cd", "Set-Location":
196 | osintShell.mainShell.changeDirectory(arguments)
197 | case "ls", "dir":
198 | osintShell.mainShell.listDirectory()
199 | case "whois":
200 | cmd.Whois(arguments)
201 | case "ip":
202 | cmd.ShowIP()
203 | case "dig":
204 | cmd.GetDNSRecords(arguments)
205 | case "lookup":
206 | cmd.GetIPInfo(arguments)
207 | case "webheader":
208 | cmd.Webheader(arguments)
209 | case "help", "man":
210 | helper.OsintHelp()
211 | default:
212 | helper.HandleWarn("Command not found", userInput)
213 | }
214 | }
215 | }
216 |
217 | func handleInputError(err error) bool {
218 | helper.HandleErr("Error reading input", err)
219 | return false
220 | }
221 |
222 | func clearScreen() {
223 | fmt.Print("\033[H\033[2J")
224 | }
225 |
226 | func newOSINTShell(mainShell *Shell) *OSINTShell {
227 | return &OSINTShell{mainShell: mainShell}
228 | }
229 |
230 | func (s *Shell) changeDirectory(arguments []string) {
231 | newDir := arguments[0]
232 | if newDir == ".." {
233 | newDir = filepath.Dir(s.UserInfo.Directory)
234 | }
235 |
236 | if helper.HandleErr("Error changing directory", os.Chdir(newDir)) {
237 | return
238 | }
239 |
240 | s.UserInfo.Directory = newDir
241 | }
242 |
243 | func (s *Shell) listDirectory() {
244 | if files, err := helper.OSReadDir(s.UserInfo.Directory); !helper.HandleErr("Error listing directory", err) {
245 | fmt.Println(strings.Join(files, "\n"))
246 | }
247 | }
248 |
--------------------------------------------------------------------------------
/src/network/scanning/port_scanner.go:
--------------------------------------------------------------------------------
1 | package scanning
2 |
3 | import (
4 | "fmt"
5 | "net"
6 | "sync"
7 | "time"
8 |
9 | "github.com/go-ping/ping"
10 | )
11 |
12 | var PortsMap = map[int]string{
13 | 6: "zeronet",
14 | 7: "echo",
15 | 9: "WOL",
16 | 20: "ftp data",
17 | 21: "ftp control",
18 | 22: "ssh",
19 | 23: "telnet",
20 | 25: "smtp",
21 | 43: "whois",
22 | 49: "TACACS",
23 | 53: "DNS",
24 | 67: "BOOTP",
25 | 69: "TFTP",
26 | 70: "Gopher",
27 | 71: "NETRJS",
28 | 80: "http",
29 | 81: "TorPark",
30 | 82: "TorPark",
31 | 88: "Kerberos",
32 | 110: "POP3",
33 | 115: "sFTP",
34 | 143: "imap",
35 | 220: "imap3",
36 | 123: "NTP",
37 | 135: "RPC",
38 | 443: "https",
39 | 445: "Microsoft-ds, Samba",
40 | 465: "SMTP over TLS",
41 | 514: "Syslog",
42 | 520: "RIP",
43 | 521: "RIPng",
44 | 540: "UUCP",
45 | 543: "klogin",
46 | 544: "kshell",
47 | 587: "submission",
48 | 993: "IMAP over TLS",
49 | 995: "POP3 over TLS",
50 | 1433: "Microsoft SQL Server",
51 | 3306: "MySQL",
52 | 3389: "rdp",
53 | 5432: "postgres",
54 | 6667: "irc",
55 | 25565: "minecraft server",
56 | }
57 |
58 | var (
59 | ip string
60 | hostname string
61 | err error
62 | )
63 |
64 | func top1000ports() []int {
65 | return []int{
66 | 1, 3, 4, 6, 7, 9, 13, 17, 19, 20, 21, 22, 23, 24, 25, 26, 30, 32, 33, 37, 42, 43, 49, 53, 70, 79, 80, 81, 82, 83, 84, 85, 88, 89, 90, 99, 100, 106, 109, 110, 111, 113, 119, 125, 135, 139, 143, 144, 146, 161, 163, 179, 199, 211, 212, 222, 254, 255, 256, 259, 264, 280, 301, 306, 311, 340, 366, 389, 406, 407, 416, 417, 425, 427, 443, 444, 445, 458, 464, 465, 481, 497, 500, 512, 513, 514, 515, 524, 541, 543, 544, 545, 548, 554, 555, 563, 587, 593, 616, 617, 625, 631, 636, 646, 648, 666, 667, 668, 683, 687, 691, 700, 705, 711, 714, 720, 722, 726, 749, 765, 777, 783, 787, 800, 801, 808, 843, 873, 880, 888, 898, 900, 901, 902, 903, 911, 912, 981, 987, 990, 992, 993, 995, 999, 1000, 1001, 1002, 1007, 1009, 1010, 1011, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1102, 1104, 1105, 1106, 1107, 1108, 1110, 1111, 1112, 1113, 1114, 1117, 1119, 1121, 1122, 1123, 1124, 1126, 1130, 1131, 1132, 1137, 1138, 1141, 1145, 1147, 1148, 1149, 1151, 1152, 1154, 1163, 1164, 1165, 1166, 1169, 1174, 1175, 1183, 1185, 1186, 1187, 1192, 1198, 1199, 1201, 1213, 1216, 1217, 1218, 1233, 1234, 1236, 1244, 1247, 1248, 1259, 1271, 1272, 1277, 1287, 1296, 1300, 1301, 1309, 1310, 1311, 1322, 1328, 1334, 1352, 1417, 1433, 1434, 1443, 1455, 1461, 1494, 1500, 1501, 1503, 1521, 1524, 1533, 1556, 1580, 1583, 1594, 1600, 1641, 1658, 1666, 1687, 1688, 1700, 1717, 1718, 1719, 1720, 1721, 1723, 1755, 1761, 1782, 1783, 1801, 1805, 1812, 1839, 1840, 1862, 1863, 1864, 1875, 1900, 1914, 1935, 1947, 1971, 1972, 1974, 1984, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013, 2020, 2021, 2022, 2030, 2033, 2034, 2035, 2038, 2040, 2041, 2042, 2043, 2045, 2046, 2047, 2048, 2049, 2065, 2068, 2099, 2100, 2103, 2105, 2106, 2107, 2111, 2119, 2121, 2126, 2135, 2144, 2160, 2161, 2170, 2179, 2190, 2191, 2196, 2200, 2222, 2251, 2260, 2288, 2301, 2323, 2366, 2381, 2382, 2383, 2393, 2394, 2399, 2401, 2492, 2500, 2522, 2525, 2557, 2601, 2602, 2604, 2605, 2607, 2608, 2638, 2701, 2702, 2710, 2717, 2718, 2725, 2800, 2809, 2811, 2869, 2875, 2909, 2910, 2920, 2967, 2968, 2998, 3000, 3001, 3003, 3005, 3006, 3007, 3011, 3013, 3017, 3030, 3031, 3052, 3071, 3077, 3128, 3168, 3211, 3221, 3260, 3261, 3268, 3269, 3283, 3300, 3301, 3306, 3322, 3323, 3324, 3325, 3333, 3351, 3367, 3369, 3370, 3371, 3372, 3389, 3390, 3404, 3476, 3493, 3517, 3527, 3546, 3551, 3580, 3659, 3689, 3690, 3703, 3737, 3766, 3784, 3800, 3801, 3809, 3814, 3826, 3827, 3828, 3851, 3869, 3871, 3878, 3880, 3889, 3905, 3914, 3918, 3920, 3945, 3971, 3986, 3995, 3998, 4000, 4001, 4002, 4003, 4004, 4005, 4006, 4045, 4111, 4125, 4126, 4129, 4224, 4242, 4279, 4321, 4343, 4443, 4444, 4445, 4446, 4449, 4550, 4567, 4662, 4848, 4899, 4900, 4998, 5000, 5001, 5002, 5003, 5004, 5009, 5030, 5033, 5050, 5051, 5054, 5060, 5061, 5080, 5087, 5100, 5101, 5102, 5120, 5190, 5200, 5214, 5221, 5222, 5225, 5226, 5269, 5280, 5298, 5357, 5405, 5414, 5431, 5432, 5440, 5500, 5510, 5544, 5550, 5555, 5560, 5566, 5631, 5633, 5666, 5678, 5679, 5718, 5730, 5800, 5801, 5802, 5810, 5811, 5815, 5822, 5825, 5850, 5859, 5862, 5877, 5900, 5901, 5902, 5903, 5904, 5906, 5907, 5910, 5911, 5915, 5922, 5925, 5950, 5952, 5959, 5960, 5961, 5962, 5963, 5987, 5988, 5989, 5998, 5999, 6000, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 6009, 6025, 6059, 6100, 6101, 6106, 6112, 6123, 6129, 6156, 6346, 6389, 6502, 6510, 6543, 6547, 6565, 6566, 6567, 6580, 6646, 6666, 6667, 6668, 6669, 6689, 6692, 6699, 6779, 6788, 6789, 6792, 6839, 6881, 6901, 6969, 7000, 7001, 7002, 7004, 7007, 7019, 7025, 7070, 7100, 7103, 7106, 7200, 7201, 7402, 7435, 7443, 7496, 7512, 7625, 7627, 7676, 7741, 7777, 7778, 7800, 7911, 7920, 7921, 7937, 7938, 7999, 8000, 8001, 8002, 8007, 8008, 8009, 8010, 8011, 8021, 8022, 8031, 8042, 8045, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8088, 8089, 8090, 8093, 8099, 8100, 8180, 8181, 8192, 8193, 8194, 8200, 8222, 8254, 8290, 8291, 8292, 8300, 8333, 8383, 8400, 8402, 8443, 8500, 8600, 8649, 8651, 8652, 8654, 8701, 8800, 8873, 8888, 8899, 8994, 9000, 9001, 9002, 9003, 9009, 9010, 9011, 9040, 9050, 9071, 9080, 9081, 9090, 9091, 9099, 9100, 9101, 9102, 9103, 9110, 9111, 9200, 9207, 9220, 9290, 9415, 9418, 9485, 9500, 9502, 9503, 9535, 9575, 9593, 9594, 9595, 9618, 9666, 9876, 9877, 9878, 9898, 9900, 9917, 9929, 9943, 9944, 9968, 9998, 9999, 10000, 10001, 10002, 10003, 10004, 10009, 10010, 10012, 10024, 10025, 10082, 10180, 10215, 10243, 10566, 10616, 10617, 10621, 10626, 10628, 10629, 10778, 11110, 11111, 11967, 12000, 12174, 12265, 12345, 13456, 13722, 13782, 13783, 14000, 14238, 14441, 14442, 15000, 15002, 15003, 15004, 15660, 15742, 16000, 16001, 16012, 16016, 16018, 16080, 16113, 16992, 16993, 17877, 17988, 18040, 18101, 18988, 19101, 19283, 19315, 19350, 19780, 19801, 19842, 20000, 20005, 20031, 20221, 20222, 20828, 21571, 22939, 23502, 24444, 24800, 25734, 25735, 26214, 27000, 27352, 27353, 27355, 27356, 27715, 28201, 30000, 30718, 30951, 31038, 31337, 32768, 32769, 32770, 32771, 32772, 32773, 32774, 32775, 32776, 32777, 32778, 32779, 32780, 32781, 32782, 32783, 32784, 32785, 33354, 33899, 34571, 34572, 34573, 35500, 38292, 40193, 40911, 41511, 42510, 44176, 44442, 44443, 44501, 45100, 48080, 49152, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160, 49161, 49163, 49165, 49167, 49175, 49176, 49400, 49999, 50000, 50001, 50002, 50003, 50006, 50300, 50389, 50500, 50636, 50800, 51103, 51493, 52673, 52822, 52848, 52869, 54045, 54328, 55055, 55056, 55555, 55600, 56737, 56738, 57294, 57797, 58080, 60020, 60443, 61532, 61900, 62078, 63331, 64623, 64680, 65000, 65129, 65389,
67 | }
68 | }
69 |
70 | func getService(port int) string {
71 | return PortsMap[port]
72 | }
73 |
74 | func measureLatency(ip string, timeout time.Duration) (time.Duration, error) {
75 | pinger, err := ping.NewPinger(ip)
76 | if err != nil {
77 | return 0, err
78 | }
79 |
80 | pinger.Timeout = timeout
81 | pinger.Count = 1
82 |
83 | startTime := time.Now()
84 |
85 | err = pinger.Run()
86 | if err != nil {
87 | return 0, err
88 | }
89 |
90 | elapsedTime := time.Since(startTime)
91 | return elapsedTime, nil
92 | }
93 |
94 | func ScanPort(ip string, port int, wg *sync.WaitGroup) {
95 | defer wg.Done()
96 | address := fmt.Sprintf("%v:%v", ip, port)
97 | conn, err := net.DialTimeout("tcp", address, time.Second)
98 | if err != nil {
99 | return
100 | }
101 | defer conn.Close()
102 |
103 | service := getService(port)
104 | fmt.Printf("%v\topen\t%v\n", port, service)
105 | }
106 |
107 | func getHostname(ip string) (string, error) {
108 | names, err := net.LookupAddr(ip)
109 | if err != nil {
110 | return "", err
111 | }
112 |
113 | if len(names) > 0 {
114 | return names[0], nil
115 | }
116 |
117 | return "", fmt.Errorf("no hostname found for %v", ip)
118 | }
119 |
120 | func PortScanner(target string) {
121 | if net.ParseIP(target) != nil {
122 | ip = target
123 | hostname, err = getHostname(target)
124 | if err != nil {
125 | fmt.Println("Error:", err)
126 | return
127 | }
128 | } else {
129 | ipAddrs, err := net.LookupHost(target)
130 | if err != nil {
131 | fmt.Println("Error:", err)
132 | return
133 | }
134 | ip = ipAddrs[0]
135 | hostname = target
136 | }
137 |
138 | timeout := 2 * time.Second
139 | portList := top1000ports()
140 |
141 | var wg sync.WaitGroup
142 |
143 | latency, err := measureLatency(ip, timeout)
144 | if err != nil {
145 | fmt.Println("Error measuring latency:", err)
146 | return
147 | }
148 |
149 | fmt.Printf("Scan report for (%v) %v\n", hostname, ip)
150 | fmt.Printf("Host is up (%v)\n", latency)
151 | fmt.Print("PORT\tSTATE\tSERIVCE\n")
152 |
153 | for _, port := range portList {
154 | wg.Add(1)
155 | go ScanPort(ip, port, &wg)
156 | }
157 |
158 | wg.Wait()
159 | }
160 |
--------------------------------------------------------------------------------