IoT security is the area of endeavor concerned with safeguarding connected devices and networks in the Internet of things.



The Internet of Things involves the increasing prevalence of objects and entities – known, in this context as things — provided with unique identifiers and the ability to automatically transfer data over a network. Much of the increase in IoT communication comes from computing devices and embedded sensor systems used in industrial machine-to-machine (M2M) communication, smart energy gridshome and building automationvehicle to vehicle communication and wearable computing devices. 

The main problem is that because the idea of networking appliances and other objects is relatively new, security has not always been considered in product design.  IoT products are often sold with old and unpatched embedded operating systems and software. Furthermore, purchasers often fail to change the default passwords on smart devices — or if they do change them, fail to select sufficiently strong passwords. To improve security, an IoT device that needs to be directly accessible over the Internet, should be segmented into its own network and have network access restricted. The network segment should then be monitored to identify potential anomalous traffic, and action should be taken if there is a problem.

Security experts have warned of the potential risk of large numbers of unsecured devices connecting to the Internet since the IoT concept was first proposed in the late 1990s. In December of 2013, a researcher at Proofpoint, an enterprise security firm, discovered the first IoT botnet. According to Proofpoint, more than 25 percent of the botnet was made up of devices other than computers, including smart TVs, baby monitors and other household appliances.


IOT Security Project :

Video below shows demo of IOT devices different types of Hacks and a final patch to secure IOT devices here Smart light is used to showcase the Attack & Patch.

 Check out this video, code below follows the video to help

f you like videos like this consider donating $1, or simply turn off AdBlocker. Either helps me to continue making tutorials.

Transcript / Cheat Sheet :


Level 1 Hack :

Level 1 device just uses get operation to control the led and can be easily hacked by extracting out the Get headers using tcpdump & netcat tool.






































































































#include <ESP8266WiFi.h>


const char* ssid = "kavin";

const char* password = "12345612";
int ledPin = D1; // GPIO13
WiFiServer server(80);
void setup() {
Serial.begin(115200);
delay(10);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
// Connect to WiFi network
Serial.println();
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Start the server
server.begin();
Serial.println("Server started");
// Print the IP address
Serial.print("Use this URL to connect: ");
Serial.print("http://");
Serial.print(WiFi.localIP());
Serial.println("/");
}
void loop() {
// Check if a client has connected
WiFiClient client = server.available();
if (!client) {
return;
}
// Wait until the client sends some data
Serial.println("new client");
while(!client.available()){
delay(1);
}
// Read the first line of the request
String request = client.readStringUntil('r');
Serial.println(request);
client.flush();
// Match the request
int value = LOW;
if (request.indexOf("/LED=ON") != -1) {
digitalWrite(ledPin, HIGH);
value = HIGH;
}
if (request.indexOf("/LED=OFF") != -1) {
digitalWrite(ledPin, LOW);
value = LOW;
}
// Set ledPin according to the request
//digitalWrite(ledPin, value);
// Return the response
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println(""); // do not forget this one
client.println("<!DOCTYPE HTML>");
client.println("<html>");
client.print("Led pin is now: ");
if(value == HIGH) {
client.print("On");
} else {
client.print("Off");
}
client.println("<br><br>");
client.println("<a href="/LED=ON""><button>Turn On </button></a>");
client.println("<a href="/LED=OFF""><button>Turn Off </button></a><br />");
client.println("</html>");
delay(1);
Serial.println("Client disonnected");
Serial.println("");
}


Level 2 Hack :
In level 2 we increase the security level little bit by authenticating the user, using a login which uses POST operation. but attacker will use wireshark and capture the typed user credentials.




















































































































































































































#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
MDNSResponder mdns;
const char* ssid = "kavin"; // your connection name
const char* password = "12345612"; // your connection password
ESP8266WebServer server(80);
int gpio1_pin = D1; // D4 of nodemcu
int gpio2_pin = D2; // D7 of nodemcu
int gpio3_pin =14; // D5 of nodemcu
//Check if header is present and correct
bool is_authentified(){
Serial.println("Enter is authentified");
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
if (cookie.indexOf("ESPSESSIONID=1") != -1) {
Serial.println("Authentification Successful");
return true;
}
}
Serial.println("Authentification Failed");
return false;
}
//login page, also called for disconnect
void handleLogin(){
String msg;
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
}
if (server.hasArg("DISCONNECT")){
Serial.println("Disconnection");
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=0");
server.send(301);
return;
}
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
if (server.arg("USERNAME") == "admin" && server.arg("PASSWORD") == "root" ) // enter ur username and password you want
{
server.sendHeader("Location","/");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=1");
server.send(301);
Serial.println("Log in Successful");
return;
}
msg = "Wrong username/password! try again.";
Serial.println("Log in Failed");
}
String content = "<html><body style='background-color:MediumAquaMarine'><form action='/login' method='POST'><p align ='center' style='font-size:300%;'><u><b><i> Log In </i></b></u></p><br>";
content += " <p align ='center' style='font-size:160%'><b> UserName:<input type='text' name='USERNAME' placeholder='user name' required></b></p><br>";
content += "<p align ='center' style='font-size:160%'><b>Password:<input type='password' name='PASSWORD' placeholder='password' required></b></p><br>";
content += "<p align ='center' style='font-size:160%'><input type='submit' name='SUBMIT' value='Submit'></form>" + msg + "</p><br> </body></html>";
server.send(200, "text/html", content);
}
//root page can be accessed only if authentification is ok
void handleRoot(){
Serial.println("Enter handleRoot");
String header;
if (!is_authentified()){
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.send(301);
return;
}
String content = "<body style='background: #80c6f7'><h1 align ='center'><b><u><i><strong>HOME AUTOMATION</strong></i></u></b></h1><br><p align ='center'>Switch #1 <a href="switch1On"><button>ON</button></a>&nbsp;<a href="switch1Off"><button>OFF</button></a></p>";
content += "<br><p align ='center'>Switch #2 <a href="switch2On"><button>ON</button></a>&nbsp;<a href="switch2Off"><button>OFF</button></a></p>";
content += "<br><p align ='center'>Switch #3 <a href="switch3On"><button>ON</button></a>&nbsp;<a href="switch3Off"><button>OFF</button></a></p>";
content += "<br><p><marquee direction='right'>Developed by Cyber Access </marquee></p>";
content += "<br><br><br><br></body>";
if (server.hasHeader("User-Agent")){
content += "the user agent used is : " + server.header("User-Agent") + "<br><br>";
}
content += "You can access this page until you <a href="/login?DISCONNECT=YES">disconnect</a></body></html>";
server.send(200, "text/html", content);
}
//no need authentification
void handleNotFound(){
String message = "File Not Foundnn";
message += "URI: ";
message += server.uri();
message += "nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "nArguments: ";
message += server.args();
message += "n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "n";
}
server.send(404, "text/plain", message);
}
void setup(void){
// preparing GPIOs
pinMode(gpio1_pin, OUTPUT);
digitalWrite(gpio1_pin, LOW);
pinMode(gpio2_pin, OUTPUT);
digitalWrite(gpio2_pin, LOW);
pinMode(gpio3_pin, OUTPUT);
digitalWrite(gpio3_pin, LOW);
delay(1000);
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/login", handleLogin);
server.on("/inline", [](){
server.send(200, "text/plain", "this works without need of authentification");
});
server.onNotFound(handleNotFound);
//here the list of headers to be recorded
const char * headerkeys[] = {"User-Agent","Cookie"} ;
size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
//ask server to track these headers
server.collectHeaders(headerkeys, headerkeyssize );
server.on("/",[](){
//
});
server.on("/switch1On", [](){
//
if (is_authentified()){
digitalWrite(gpio1_pin, HIGH);
delay(1000);}
});
server.on("/switch1Off", [](){
//
if (is_authentified()){
digitalWrite(gpio1_pin, LOW);
delay(1000); }
});
server.on("/switch2On", [](){
//
digitalWrite(gpio2_pin, HIGH);
delay(1000);
});
server.on("/switch2Off", [](){
//
digitalWrite(gpio2_pin, LOW);
delay(1000);
});
server.on("/switch3On", [](){
digitalWrite(gpio3_pin, HIGH);
delay(1000);
});
server.on("/switch3Off", [](){
digitalWrite(gpio3_pin, LOW);
delay(1000);
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}

Level 3 Hack :

In level 3 we will increase security level by using encryption technique here we will encrypt user credentials so that attacker will not able to use user credentials. But here attacker will use Fiddler tool used for packet capturing and have the capability of replaying the captured packet, here attacker will replay the packet which is used for control the smart led.




















































































































































































































#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
MDNSResponder mdns;
const char* ssid = "kavin"; // your connection name
const char* password = "12345612"; // your connection password
ESP8266WebServer server(80);
int gpio1_pin = D1; // D4 of nodemcu
int gpio2_pin = D2; // D7 of nodemcu
int gpio3_pin =14; // D5 of nodemcu
//Check if header is present and correct
bool is_authentified(){
Serial.println("Enter is authentified");
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
if (cookie.indexOf("ESPSESSIONID=1") != -1) {
Serial.println("Authentification Successful");
return true;
}
}
Serial.println("Authentification Failed");
return false;
}
//login page, also called for disconnect
void handleLogin(){
String msg;
if (server.hasHeader("Cookie")){
Serial.print("Found cookie: ");
String cookie = server.header("Cookie");
Serial.println(cookie);
}
if (server.hasArg("DISCONNECT")){
Serial.println("Disconnection");
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=0");
server.send(301);
return;
}
if (server.hasArg("USERNAME") && server.hasArg("PASSWORD")){
if (server.arg("PASSWORD") == "t$o$o$r$" ) // enter ur username and password you want
{
server.sendHeader("Location","/");
server.sendHeader("Cache-Control","no-cache");
server.sendHeader("Set-Cookie","ESPSESSIONID=1");
server.send(301);
Serial.println("Log in Successful");
return;
}
msg = "Wrong username/password! try again.";
Serial.println("Log in Failed");
}
String content = "<html><script type='text/javascript'>function encodeMyHtml(){var htmlToEncode = document.getElementById('password').value;var str = String(htmlToEncode) ;var newString = '';for (var i = str.length - 1; i >= 0; i--) { newString += str[i]+'$';}var encodedHtml = escape(htmlToEncode);document.getElementById('password').value=newString;return true;} </script>";
content += "<body style='background-color:MediumAquaMarine'><form id='form1' action='/login' method='POST'><p align ='center' style='font-size:300%;'><u><b><i> Log In </i></b></u></p><br>";
content += " <p align ='center' style='font-size:160%'><b> UserName:<input type='text' name='USERNAME' placeholder='user name' required></b></p><br>";
content += "<p align ='center' style='font-size:160%'><b>Password:<input type='password' id='password' name='PASSWORD' placeholder='password' required></b></p><br>";
content += "<p align ='center' style='font-size:160%'><input type='submit' name='SUBMIT' onclick='return encodeMyHtml()' value='Submit'></form>" + msg + "</p><br> </body></html>";
server.send(200, "text/html", content);
}
//root page can be accessed only if authentification is ok
void handleRoot(){
Serial.println("Enter handleRoot");
String header;
if (!is_authentified()){
server.sendHeader("Location","/login");
server.sendHeader("Cache-Control","no-cache");
server.send(301);
return;
}
String content = "<body style='background: #80c6f7'><h1 align ='center'><b><u><i><strong>HOME AUTOMATION</strong></i></u></b></h1><br><p align ='center'>Switch #1 <a href="switch1On"><button>ON</button></a>&nbsp;<a href="switch1Off"><button>OFF</button></a></p>";
//content += "<br><p align ='center'>Switch #2 <a href="switch2On"><button>ON</button></a>&nbsp;<a href="switch2Off"><button>OFF</button></a></p>";
//content += "<br><p align ='center'>Switch #3 <a href="switch3On"><button>ON</button></a>&nbsp;<a href="switch3Off"><button>OFF</button></a></p>";
content += "<br><p><marquee direction='right'>Developed by Cyber Xs </marquee></p>";
content += "<br><br><br><br></body>";
if (server.hasHeader("User-Agent")){
content += "the user agent used is : " + server.header("User-Agent") + "<br><br>";
}
content += "You can access this page until you <a href="/login?DISCONNECT=YES">disconnect</a></body></html>";
server.send(200, "text/html", content);
}
//no need authentification
void handleNotFound(){
String message = "File Not Foundnn";
message += "URI: ";
message += server.uri();
message += "nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "nArguments: ";
message += server.args();
message += "n";
for (uint8_t i=0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "n";
}
server.send(404, "text/plain", message);
}
void setup(void){
// preparing GPIOs
pinMode(gpio1_pin, OUTPUT);
digitalWrite(gpio1_pin, LOW);
pinMode(gpio2_pin, OUTPUT);
digitalWrite(gpio2_pin, LOW);
pinMode(gpio3_pin, OUTPUT);
digitalWrite(gpio3_pin, LOW);
delay(1000);
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}
server.on("/", handleRoot);
server.on("/login", handleLogin);
server.on("/inline", [](){
server.send(200, "text/plain", "this works without need of authentification");
});
server.onNotFound(handleNotFound);
//here the list of headers to be recorded
const char * headerkeys[] = {"User-Agent","Cookie"} ;
size_t headerkeyssize = sizeof(headerkeys)/sizeof(char*);
//ask server to track these headers
server.collectHeaders(headerkeys, headerkeyssize );
server.on("/",[](){
//
});
server.on("/switch1On", [](){
//
if (is_authentified()){
digitalWrite(gpio1_pin, HIGH);
delay(1000);}
});
server.on("/switch1Off", [](){
//
if (is_authentified()){
digitalWrite(gpio1_pin, LOW);
delay(1000); }
});
server.on("/switch2On", [](){
//
digitalWrite(gpio2_pin, HIGH);
delay(1000);
});
server.on("/switch2Off", [](){
//
digitalWrite(gpio2_pin, LOW);
delay(1000);
});
server.on("/switch3On", [](){
digitalWrite(gpio3_pin, HIGH);
delay(1000);
});
server.on("/switch3Off", [](){
digitalWrite(gpio3_pin, LOW);
delay(1000);
});
server.begin();
Serial.println("HTTP server started");
}
void loop(void){
server.handleClient();
}

Final Patch :

In final patch we will use access token along with encrypted user credentials so will not able do any type of attack rather it be packet capturing, packet replay – because replay packet token will not match &amp; packet get refused.

For source code here 


So, that end up with great tutorials on IOT security i hope you guys enjoyed it, if facing any query feel free to comment out 🙂








Categorized in: