ipscan.html 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
  5. <meta name="apple-mobile-web-app-capable" content="yes" />
  6. <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
  7. <meta charset="UTF-8">
  8. <meta name="theme-color" content="#4b75ff">
  9. <link rel="icon" type="image/png" href="./favicon.png" />
  10. <title>IP Scanner | Zoraxy</title>
  11. <link rel="stylesheet" href="../script/semantic/semantic.min.css">
  12. <script src="../script/jquery-3.6.0.min.js"></script>
  13. <script src="../script/semantic/semantic.min.js"></script>
  14. <script src="../script/tablesort.js"></script>
  15. <link rel="stylesheet" href="../main.css">
  16. <script src="../script/utils.js"></script>
  17. <style>
  18. .offlinehost{
  19. display: none;
  20. }
  21. </style>
  22. </head>
  23. <body>
  24. <link rel="stylesheet" href="../darktheme.css">
  25. <script src="../script/darktheme.js"></script>
  26. <div class="ui container">
  27. <br>
  28. <div class="ui segment">
  29. <div style="padding: 1em;">
  30. <div class="ui stackable grid">
  31. <div class="eight wide column">
  32. <h4 class="ui dividing header">Scan IP Range</h4>
  33. <div class="ui form">
  34. <div class="field">
  35. <label>Start IP</label>
  36. <input type="text" id="start-ip" name="start-ip">
  37. </div>
  38. <div class="field">
  39. <label>End IP</label>
  40. <input type="text" id="end-ip" name="end-ip">
  41. </div>
  42. <button class="ui basic button scanbtn" id="ip-scan-btn"><i class="blue search icon"></i> Scan</button>
  43. </div>
  44. <br>
  45. </div>
  46. <div class="eight wide column">
  47. <h4 class="ui dividing header">Scan CIDR Range</h4>
  48. <div class="ui form">
  49. <div class="field">
  50. <label>CIDR</label>
  51. <input type="text" id="cidr" name="cidr">
  52. </div>
  53. <button class="ui basic button scanbtn" id="cidr-scan-btn"><i class="blue search icon"></i> Scan</button>
  54. </div>
  55. </div>
  56. </div>
  57. </div>
  58. </div>
  59. <button class="ui basic button" onclick="toggleOfflineHost();"><i class="grey eye icon"></i>View Offline Hosts</button>
  60. <div class="ui divider"></div>
  61. <br>
  62. <div id="scan-results" style="overflow-x: auto;">
  63. </div>
  64. <br>
  65. <div style="float: right;">
  66. <button class="ui basic button" style="margin-right: 1em;" onclick="window.open('', '_self', ''); window.close();"><i class="ui red remove icon"></i> Close</button>
  67. </div>
  68. <br><br><br>
  69. </div>
  70. <script>
  71. $(document).ready(function() {
  72. $('#ip-scan-btn').click(function(event) {
  73. event.preventDefault();
  74. var start = $('#start-ip').val().trim();
  75. var end = $('#end-ip').val().trim();
  76. if (start === '' || end === '') {
  77. alert('Please enter start and end IP range');
  78. return;
  79. }
  80. if (!isValidIPv4(start) || !isValidIPv4(end)){
  81. alert('Invalid start or end ip address');
  82. return;
  83. }
  84. $(".scanbtn").addClass("disabled");
  85. $("#scan-results").html(`
  86. <div class="ui basic segment" align="center">
  87. <i class="loading spinner icon"></i> Scanning
  88. </div>`);
  89. $.cjax({
  90. url: "/api/tools/ipscan",
  91. data: {start: start, end: end},
  92. method: "POST",
  93. success: function(data){
  94. displayResults(data);
  95. $(".scanbtn").removeClass("disabled");
  96. }
  97. });
  98. });
  99. $('#cidr-scan-btn').click(function(event) {
  100. event.preventDefault();
  101. var cidr = $('#cidr').val().trim();
  102. if (cidr === '') {
  103. alert('Please enter CIDR notation');
  104. return;
  105. }
  106. if (!isValidCIDR(cidr)){
  107. alert("Invalid CIDR notation string given");
  108. return;
  109. }
  110. $(".scanbtn").addClass("disabled");
  111. $("#scan-results").html(`
  112. <div class="ui basic segment" align="center">
  113. <i class="loading spinner icon"></i> Scanning
  114. </div>`);
  115. $.cjax({
  116. url: "/api/tools/ipscan",
  117. method: "POST",
  118. data: {cidr: cidr},
  119. success: function(data) {
  120. displayResults(data);
  121. $(".scanbtn").removeClass("disabled");
  122. }
  123. });
  124. });
  125. function isValidCIDR(str) {
  126. const cidrRegex = /^(\d{1,3}\.){3}\d{1,3}\/\d{1,2}$/;
  127. return cidrRegex.test(str);
  128. }
  129. function isValidIPv4(ip) {
  130. var regex = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/;
  131. if (!regex.test(ip)) {
  132. return false;
  133. }
  134. var parts = ip.split(".");
  135. for (var i = 0; i < parts.length; i++) {
  136. if (parseInt(parts[i], 10) > 255) {
  137. return false;
  138. }
  139. }
  140. return true;
  141. }
  142. function displayResults(data) {
  143. var table = $('<table class="ui celled unstackable table"></table>');
  144. var header = $(`<thead>
  145. <tr>
  146. <th>IP Address</th>
  147. <th>Ping</th>
  148. <th>Hostname</th>
  149. <th>HTTP Detected</th>
  150. <th>HTTPS Detected</th>
  151. <th>Port Scan</th>
  152. </tr>
  153. </thead>`);
  154. table.append(header);
  155. var body = $('<tbody></tbody>');
  156. var offlineHostCounter = 0;
  157. for (var i = 0; i < data.length; i++) {
  158. var classname = "offlinehost";
  159. let hostIsOnline = data[i].Ping >= 0;
  160. if (hostIsOnline){
  161. classname = "onlinehost";
  162. }else{
  163. offlineHostCounter++;
  164. }
  165. var row = $('<tr class="' + classname + '"></tr>');
  166. var status = data[i].Ping >= 0 ? '<i class="green circle icon"></i>' : '<i class="grey circle icon"></i>';
  167. row.append($('<td>' + status + data[i].IP + '</td>'));
  168. row.append($('<td>' + ((data[i].Ping>=0)?data[i].Ping+"ms":"Host Unreachable") + '</td>'));
  169. row.append($('<td>' + data[i].Hostname + '</td>'));
  170. row.append($('<td>' + (data[i].HttpPortDetected ? '<i class="green check icon"></i>' : '') + '</td>'));
  171. row.append($('<td>' + (data[i].HttpsPortDetected ? '<i class="green check icon"></i>' : '') + '</td>'));
  172. row.append($(`<td>${hostIsOnline ? `<button class="ui small basic button" onclick='launchToolWithSize("portscan.html?ip=${data[i].IP}", 1000, 640);'>Scan</button>`:''}</td>`));
  173. body.append(row);
  174. }
  175. if (data.length == 0){
  176. var body = $(`<tbody>
  177. <tr>
  178. <td colspan="5">
  179. <i class="green circle check icon"></i> Discover no devices in given IP range
  180. </td>
  181. </tr>
  182. </tbody>`);
  183. }
  184. if (offlineHostCounter == data.length){
  185. //All offline
  186. var body = $(`<tbody>
  187. <tr>
  188. <td colspan="5">
  189. <i class="green circle check icon"></i> All hosts in given IP range are offline
  190. </td>
  191. </tr>
  192. </tbody>`);
  193. }
  194. table.append(body);
  195. $('#scan-results').empty().append(table);
  196. }
  197. });
  198. function toggleOfflineHost(){
  199. $(".offlinehost").toggle();
  200. }
  201. function launchToolWithSize(url, width, height){
  202. let windowName = Date.now();
  203. window.open(url,'w'+windowName,
  204. `toolbar=no,
  205. location=no,
  206. status=no,
  207. menubar=no,
  208. scrollbars=yes,
  209. resizable=yes,
  210. width=${width},
  211. height=${height}`);
  212. }
  213. </script>
  214. </body>
  215. </html>