点击关注我的Telegram群组和微信公众号

MENU

PyClipboardSender: 绕过Lockdown Browser限制将剪贴板发送至其它主机的小工具

2021 年 04 月 08 日 • 阅读: 6316 • 技术,分享

程序完整代码:Masterain98/PyClipboardSender


client


前言

Lockdown Browser 的功能之一就是限制系统剪贴板的使用。作为系统组件的一部分,Windows 剪贴板实际上一直在运行中,因此我们可以使用第三方软件收集剪贴板内容。在最新的 Windows 10 系统中,用户可以在登录微软帐号后在不同的 Windows 10 设备之间通过 Win + V 快捷键同步剪贴板。但是这一功能在旧版的系统中并不存在,常见的第三方云剪贴板软件也被拉进 Lockdown Broswer 黑名单,所以自己整一个类似的小工具是有必要的。

思路

因为仅仅是考虑到少数几个设备之间的传输,且大概率是在内网环境下由个人使用,所以做成帐号登录形式的多设备同步是没必要的。我们可以将接受剪贴板的设备考虑为一个服务端,发送剪贴板内容的设备考虑为一个客户端,端对端地直接传输数据。HTTP 请求是一个常见易用的方案,以 json 的形式 POST 请求也容易处理数据。而在剪贴板功能上,我们可以直接使用 pyperclip 库中的功能。

服务端

  • 首先需要为服务器做一个配置文件 config.json

    • 需要包含两个字段来储存密码和客户端白名单作为验证
{
  "passwd" : "123456",
  "allowedPC" : "MasterainPC1,MasterainPC2, MasterainPC3"
}
  • 主程序中导入必要的库
import pyperclip    # 用于Windows剪贴板相关功能
import json        # 用于处理json数据
from flask import Flask, jsonify, request    # Flask作为Web程序,jsonify和request处理HTTP请求
  • 设置 Flask 接收 HTTP 请求的函数
app = Flask(__name__)
app.config["JSON_AS_ASCII"] = False

# 剪贴板函数,接收一个HTTP POST请求
# content为剪贴板内容
# passwd为用于验证的密码字段
# pcName为用于验证的计算机名白名单
@app.route("/clipboardReceiver", methods=["POST"])
def clipboardReceiver():
    # Expect to receive json posts
    content = request.json.get("content").strip()
    passwd = request.json.get("passwd").strip()
    pcName = request.json.get("pcName").strip()
  
    # 处理验证内容
    if server_passwd != "" and server_passwd == passwd or server_passwd == "":
        # 当白名单为空时,允许所有计算机客户端发送内容
        if server_allowedPC == "":
            # 将content中的内容加载到本地剪贴板中
            pyperclip.copy(content)
            return jsonify({"code": 2000, "msg": "Clipboard content received"})
        elif server_allowedPC != "" and pcName in server_allowedPC_list:
            pyperclip.copy(content)
            return jsonify({"code": 2000, "msg": "Clipboard content received"})
        else:
            return jsonify({"code": 2001, "msg": "Client not in white list"})
    else:
        return jsonify({"code": 2002, "msg": "Wrong password"})
  • 主程序
if __name__ == '__main__':
    # 读取本地config.json
    configFile = json.loads(config.read())
    server_passwd = configFile["passwd"].replace(' ', '')
    server_allowedPC = configFile["allowedPC"].replace(' ', '')
    server_allowedPC_list = server_allowedPC.split(",")
  
    # 将Flask程序跑在本地5951端口上
    app.run(host="0.0.0.0", port=5951, debug=True)

客户端

  • 和服务端一样,创建一个 config.json 配置文件

    • 包含服务端的目标 IP(理论上域名也行)和服务端密码
{
  "server": "192.168.50.219",
  "passwd" : "123456"
}
  • 主程序中加载必要的库
# 剪贴板库
import pyperclip
# 处理json
import json
# HTTP请求
import requests
# 获取本地计算机名
import socket
# time.sleep()
import time
  • 主程序中以一个 Infinite loop 来不断读取客户端本地的剪贴板内容,当监测到内容变化时发起一个 HTTP POST 将内容发送到目标服务端
if __name__ == '__main__':
    """
    省略读取本地config.json的过程
    """
    # 获取计算机名
    hostname = socket.gethostname()
    # 初始化
    lastRecord = ""
    while True:
        # 读取本地剪贴板内容
        clipboard_content = pyperclip.paste()

        if clipboard_content != lastRecord:
            # 将内容加载到json中并发送请求
            payload = {"content": clipboard_content, "passwd": passwd, "pcName": hostname}
            lastRecord = clipboard_content
            response = requests.post(targetURL, data=json.dumps(payload), headers=headers).text
            # 处理返回的结果(其实非必要)
            returnInfoJson = json.loads(response)
            responseCode = returnInfoJson.get("code")
            print("Return Code " + str(responseCode))
            time.sleep(0.5)

模拟请求

  • 在收到 2000 的返回码时,成功将 测试内容 加载到剪贴板中
    screenshot
最后编辑于: 2021 年 04 月 10 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码