├── code
├── img
└── banner.png
├── requirements.txt
├── go.mod
├── install.sh
├── printcolors.py
├── LICENSE
├── README.md
├── go.sum
├── scan
├── .gitignore
├── main.go
└── scan.py
/code:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/img/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xadhrit/d9scan/HEAD/img/banner.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | beautifulsoup4==4.9.3
2 | requests==2.26.0
3 | urllib3==1.26.6
4 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module main.go
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/google/gopacket v1.1.19 // indirect
7 | golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect
8 | )
9 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | if [[ "$OSTYPE" == "linux-gnu" || "darwin" || "cygwin" || "msys" || "freebsd" ]];
4 | then
5 | echo -e "Donwloading requirements\n"
6 | python3 -m pip install -r requirements.txt && python3 scan.py -h
7 |
8 | else
9 | echo -e "Donwloading requirements\n"
10 | python -m pip install -r requirements.txt && python scan.py -h
11 |
12 | fi
13 |
14 | exit 0
15 |
16 |
--------------------------------------------------------------------------------
/printcolors.py:
--------------------------------------------------------------------------------
1 | """enable some pretty colors
2 | colors module
3 |
4 | """
5 |
6 | import sys
7 |
8 | if sys.platform.lower().startswith(('os','win','darwin','ios')):
9 | end = red = white = green = yellow = run = bad = good = info = que = ''
10 |
11 | else:
12 | white = '\033[97m'
13 | blue = '\033[94m'
14 | green = '\033[92m'
15 | red = '\033[91m'
16 | yellow = '\033[93m'
17 | end = '\033[0m'
18 | bold = '\033[1m'
19 | back = '\033[7;91m'
20 | info = '\033[93m[!]\033[0m'
21 | que = '\033[94m[?]\033[0m'
22 | bad = '\033[91m[-]\033[0m'
23 | good = '\033[92m[+]\033[0m'
24 | run = '\033[97m[~]\033[0m'
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 ADHRIT. (github.com/xadhrit)
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.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # d9scan
2 | ### Python Network Scanner with Backdoor Detection on Network
3 |
4 | d9scan is a script written in Python3 that allows port scanning, Backdoor Detection on networks. The program is interactive and simply requires you to run it to begin. Obtain open ports , asks for option which script you want to run. All scripts are backed by NMAP.
5 |
6 |
7 |
8 |
9 |
10 |
11 | ```
12 | **Usage**
13 |
14 | ./d9scan~$ python3 scan.py
15 |
16 |
17 | ```
18 |
19 | or
20 |
21 | ```
22 | ~$ chmod +x scan.sh
23 | ~$ ./scan.sh
24 |
25 | ```
26 |
27 | **Scripts**
28 |
29 | ```bash
30 | > nmap -v -A scan
31 | > http-malware-host Detection (recommanded malware detection)
32 | > http-dlink-backdoor Detection (dlink backdoor detection)
33 | > ftp-proftpd-backdoor Detection (ftp proftpd detection runs on port 21)
34 |
35 | ```
36 |
37 | ## Requirements
38 | Python3 must be installed on your system in order to function
39 | Install bs4 via pip using `pip install bs4`
40 |
41 | or
42 |
43 | ```
44 | chmod +x install.sh
45 |
46 | ./install.sh
47 | ```
48 |
49 | ## Installation
50 |
51 | **Install via Git**
52 |
53 | ```bash
54 | git clone https://github.com/xadhrit/d9scan.git
55 | ```
56 |
57 | ```bash
58 | sudo ln -s $(pwd)/scan.py /usr/local/bin/scan
59 | ```
60 |
61 | **SYN protection Detection**
62 |
63 | ```
64 | go run main.go
65 | ```
66 |
67 | ## LICENSE
68 | *Distributed under MIT LICENSE*
69 |
70 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
2 | github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
3 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
4 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
5 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
6 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
7 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
8 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
9 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
10 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
11 | golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
12 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
13 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
14 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
15 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
16 |
--------------------------------------------------------------------------------
/scan:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | CYAN="\e[36m"
4 | GREEN="\e[32m"
5 | ENDCOLOR="\e[0m"
6 |
7 | echo -e "${GREEN}"
8 | pyfiglet d9scan
9 |
10 | printf "${CYAN} d9scan from shell :) \n\n"
11 | printf "Enter target's domain or IP : "
12 | read IP
13 |
14 | function options(){
15 | echo -e "${ENDCOLOR}----------------- Choose One option -----------------------${GREEN} "
16 | echo -e " 1 for http-malware-host scan"
17 | echo -e " 2 for http-dlink-backdoor scan"
18 | echo -e " 3 for ftp-proftpd-backdoor scan"
19 | echo -e " 4 for all "
20 | echo -e " 5 Exit "
21 | read OPTION
22 |
23 |
24 | if [[ $OPTION == '1' ]] ;
25 | then
26 | echo -e "${GREEN} nmap -sv --script=http-malware-host ${IP} \n"
27 | nmap -sV --script=http-malware-host $IP
28 | elif [[ $OPTION == '2' ]] ;
29 | then
30 | echo -e "${GREEN} nmap -sV --script http-dlink-backdoor ${IP}\n "
31 | nmap -sV --script http-dlink-backdoor $IP
32 | elif [[ $OPTION == '3' ]];
33 | then
34 | echo -e "${GREEN} nmap --script ftp-proftpd-backdoor -p 21 ${IP}\n "
35 | nmap --script ftp-proftpd-backdoor -p 21 $IP
36 | elif [[ $OPTION == '4' ]] ;
37 | then
38 | echo -e "${CYAN} Running all Scripts\n "
39 | nmap -sV --script=http-malware-host $IP
40 | nmap -sV --script http-dlink-backdoor $IP
41 | nmap --script ftp-proftpd-backdoor -p 21 $IP
42 | elif [[ $OPTION == '5' ]];
43 | then
44 | exit 0
45 | else
46 | printf "Invalid Option, Exiting..... \n"
47 | exit 0
48 | fi
49 |
50 | }
51 | echo -e "${GREEN} nmap -v -A ${IP}"
52 | nmap -v -A $IP
53 | options
54 | exit
55 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # Tool specific extensions
132 | *.grep
133 | *.nmap
134 | *.xml
135 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | // port scanning through syn-flood protections
2 | /*
3 | For ensure if a service exist on a port :
4 | if you receive any additional packets from the target after you've established a connection.
5 | 1. Capture the packets
6 | 2. Check if they are trasmitted with a TCP flag (CWR,ECE,URG, ACK, PSH, RST, SYN, FIN)
7 | */
8 |
9 | package main
10 |
11 | import (
12 | "fmt"
13 | "log"
14 | "net"
15 | "os"
16 | "strings"
17 | "time"
18 |
19 | "github.com/google/gopacket"
20 | "github.com/google/gopacket/pcap"
21 | )
22 |
23 | var (
24 | snaplen = int32(320)
25 | promise = true
26 | timeout = pcap.BlockForever
27 | filter = "tcp[13] == 0x11 ot tcp[13] == 0x10 or tcp[13] == 0x18"
28 | /*
29 | only looking for
30 | * ACK && FIN : 0x11
31 | * ACK: 0x10
32 | * ACK and PSH 0x18
33 | */
34 | devFound = false
35 | results = make(map[string]int)
36 | )
37 |
38 | func capture(targetDev, target string) {
39 | handle, err := pcap.OpenLive(targetDev, snaplen, promise, timeout)
40 |
41 | if err != nil {
42 | log.Panicln(err)
43 | }
44 |
45 | defer handle.Close()
46 |
47 | if err := handle.SetBPFFilter(filter); err != nil {
48 | log.Panicln(err)
49 | }
50 |
51 | source := gopacket.NewPacketSource(handle, handle.LinkType())
52 |
53 | fmt.Println("Capturing packets")
54 | for packet := range source.Packets() {
55 | networkLayer := packet.NetworkLayer()
56 | if networkLayer == nil {
57 | continue
58 | }
59 |
60 | transportLayer := packet.TransportLayer()
61 | if transportLayer == nil {
62 | continue
63 | }
64 |
65 | sourceHost := networkLayer.NetworkFlow().Src().String()
66 | sourcePort := transportLayer.TransportFlow().Src().String()
67 |
68 | if sourceHost != target {
69 | continue
70 | }
71 |
72 | results[sourcePort] += 1
73 | }
74 | }
75 |
76 | func explode (portString string) ([]string , error){
77 | ret := make([]string, 0)
78 |
79 | ports := strings.Split(portString, ",")
80 | for _, port := range ports {
81 | port := strings.TrimSpace(port)
82 | ret = append(ret, port)
83 | }
84 |
85 | return ret, nil
86 | }
87 |
88 |
89 | func main() {
90 | if len(os.Args) != 4 {
91 | log.Fatalln("Usage: main.go ")
92 | }
93 |
94 | devices, err := pcap.FindAllDevs()
95 |
96 | if err != nil {
97 | log.Panicln(err)
98 | }
99 |
100 | targetDevice := os.Args[1]
101 |
102 | for _, device := range devices {
103 | if device.Name == targetDevice {
104 | devFound = true
105 | }
106 | }
107 |
108 | if !devFound {
109 | log.Panicf("Device named %s' does not exist\n ", targetDevice)
110 | }
111 |
112 | ip := os.Args[2]
113 |
114 | go capture(targetDevice, ip)
115 |
116 | time.Sleep(1 * time.Second)
117 |
118 | ports, err := explode(os.Args[3])
119 |
120 | if err != nil {
121 | log.Panicln(err)
122 | }
123 |
124 | for _, port := range ports {
125 | target := fmt.Sprintf("%s %s", ip, port)
126 |
127 | fmt.Println("Trying ", target)
128 |
129 | e, err := net.DialTimeout("tcp", target, 1000*time.Millisecond)
130 |
131 | if err != nil {
132 | continue
133 | }
134 |
135 | e.Close()
136 | }
137 |
138 | time.Sleep(2 * time.Second)
139 |
140 | for port, probability := range results {
141 | if probability >= 1 {
142 | fmt.Println("port %s open (probability: %d)\n", port, probability)
143 | }
144 | }
145 | }
146 |
--------------------------------------------------------------------------------
/scan.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | """
4 | d9scan - by Adhrit
5 | https://github.com/xadhrit/d9scan
6 |
7 | """
8 |
9 | import socket
10 | import os
11 | import time
12 | import sys
13 | import argparse
14 | import subprocess
15 | import requests
16 | from printcolors import *
17 | from datetime import datetime
18 | from urllib.parse import urljoin
19 | from bs4 import BeautifulSoup as bs
20 |
21 | # Main Function
22 | def main():
23 | socket.setdefaulttimeout(0.30)
24 | #argument parser
25 | parser = argparse.ArgumentParser(description='Network Scanning with d9scan')
26 | parser.add_argument('target', type=str, help='Domain or IP address of Target')
27 | args = parser.parse_args()
28 | target = args.target
29 |
30 | # Start scan with clear terminal
31 | subprocess.call('clear', shell=True)
32 |
33 | #welcome d9scan poison banner.
34 |
35 | print("""
36 |
37 | @@@@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@@@@@
38 | @@@@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@@ @@@@ @@@
39 | @@! @@@ @@! @@@ !@@ !@@ @@! @@@ @@!@!@@@
40 | !@! @!@ !@! @!@ !@! !@! !@! @!@ !@!!@!@!
41 | @!@ !@! !!@!!@!! !!@@!! !@! @!@!@!@! @!@ !!@!
42 | !@! !!! !!@!!! !!@!!! !!! !!!@!!!! !@! !!!
43 | !!: !!! !!! !:! :!! !!: !!! !!: !!!
44 | :!: !:! !:! !:! :!: :!: !:! :!: !:!
45 | :::: :: ::::: :: :::: :: ::: ::: :: ::: :: ::
46 | :: : : : : : :: : : :: :: : : : : :: : """)
47 | print(" \n")
48 | print("%s\t\td9scan - Network Scanner with Backdoor Detection + SYN protection filter scanning "%(yellow))
49 |
50 | time.sleep(1)
51 | print("\n")
52 | #target = input("Enter your target IP address or URL here: ")
53 | error = ("%sInvalid Input"%red)
54 | try:
55 | t_ip = socket.gethostbyname(target)
56 | except (UnboundLocalError, socket.gaierror):
57 | print("\n%s%sInvalid format. Please use a correct IP or web address\n"%(bad, red))
58 | sys.exit()
59 |
60 |
61 | print("Scanning target : {} - {} ".format(target,t_ip), end='')
62 | print(" | Time started: "+ str(datetime.now()))
63 |
64 | t1 = datetime.now()
65 |
66 |
67 | def generalscan(target):
68 |
69 | s = "nmap -v -A {}".format(target)
70 | os.mkdir(target)
71 | os.chdir(target)
72 | print("%s"%(green))
73 | os.system(s)
74 |
75 |
76 | generalscan(target)
77 | t2 = datetime.now()
78 | total = t2 - t1
79 | #print("Port scan completed in "+str(total))
80 | print("^" * 60)
81 | print("%s Recommended Nmap scan:"%white)
82 | print("-" * 60)
83 |
84 | #print("%snmap -p{ports} -sV -sC -T4 -Pn -oA {ip} {ip}".format(ports=",".join(discovered_ports), ip=target)%blue)
85 |
86 | outfile = "nmap -sV --script=http-malware-host {ip}".format(ip=target)
87 | print(outfile)
88 | print("-" * 60)
89 | backdoor = "nmap -sV --script http-dlink-backdoor {ip}".format(ip=target)
90 | ftpbackdoor = "nmap --script ftp-proftpd-backdoor -p 21 {ip}".format(ip=target)
91 | t3 = datetime.now()
92 | total1 = t3 - t1
93 |
94 |
95 | #Nmap Integration
96 |
97 | def automate():
98 | choice = '0'
99 | while choice =='0':
100 | print("Would you like to run Nmap or quit to terminal?")
101 |
102 | print("%s0 = Run suggested Nmap scan"%green)
103 | print("%s1 = Run Ftp backdoor Detection "%green)
104 | print("%s2 = Run http-dlink BackDoor Detection"%green)
105 | print("%s3 = Run another d9 scan"%green)
106 | print("%s4 = Exit to terminal"%green)
107 |
108 | choice = input("Option Selection: ")
109 | if choice == "0":
110 | try:
111 | #print(yellow+outfile)
112 | os.mkdir(target)
113 | os.chdir(target)
114 | os.system(outfile)
115 | t3 = datetime.now()
116 | total1 = t3 - t1
117 | print("-" * 60)
118 | print("Malware Detection scan completed in "+str(total1))
119 | print("")
120 | print("%sPress 1 to go back or enter to quit..."% white)
121 | input()
122 | except FileExistsError as e:
123 | print(e)
124 | exit()
125 | elif choice == "1":
126 | try:
127 | #print(white+ftpbackdoor)
128 | os.mkdir(target)
129 | os.chdir(target)
130 | os.system(ftpbackdoor)
131 | t3 = datetime.now()
132 | total1 = t3-t1
133 | print("Ftp Backdoor Scan completed in "+str(total1))
134 | print("%sPress 2 to go back and enter to quit..."%white)
135 | uinput = input()
136 | if uinput == '2':
137 | automate()
138 | elif uinput():
139 | exit()
140 | else:
141 | sys.exit(0)
142 | except FileExistsError as e:
143 | print(e)
144 | exit()
145 | elif choice == "2":
146 | try:
147 | #print(red+backdoor)
148 | os.mkdir(target)
149 | os.chdir(target)
150 | os.system(backdoor)
151 | t3 = datetime.now()
152 | total1 = t3-t1
153 | print("Combined scan completed in " + str(total1))
154 | print("%s Press 3 to go back and enter to quit..."%white)
155 | uinput = input()
156 | if uinput == '3':
157 | automate()
158 | elif uinput():
159 | exit()
160 | else:
161 | sys.exit(0)
162 | except FileExistsError as e:
163 | print(e)
164 | exit()
165 | elif choice =="3":
166 | main()
167 | elif choice =="4":
168 | sys.exit()
169 | else:
170 | print("%sPlease make a valid selection"%yellow)
171 | automate()
172 | automate()
173 |
174 | if __name__ == '__main__':
175 | try:
176 | main()
177 | except KeyboardInterrupt:
178 | print("\n%sGoodbye!"%red)
179 | quit()
180 |
--------------------------------------------------------------------------------