吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4749|回复: 36
上一主题 下一主题
收起左侧

[原创] Proxifier强制代{过}{滤}理HTTP绕过身份检测

[复制链接]
跳转到指定楼层
楼主
alexsuntop 发表于 2024-3-20 10:46 回帖奖励
本帖最后由 alexsuntop 于 2024-3-20 10:51 编辑

题主非逆向专业,如有不足请多多海涵。这是题主第一次发帖,这里描述的内容可能过于抽象或不详细,如果有其他问题我将继续更新以供学习交流。

似乎所有代==理,都被加了 {过}{滤},第一次用 52,额

最近发现一个付费软件使用 HTTP 验证是否购买,所以想绕过直接使用。考虑到软件方商业权益和本帖合法性,暂时不提供相关软件的任何信息,本帖只提供思路。

这里提醒一下,如果你没有已经购买过的样本来学习,那这一点还是很难实现的,还是老老实实脱壳破解吧。题主有幸得到一份已经购买过朋友的样本,所以学到了验证方法。

首先题主通过 Fiddler 拦截请求,实现了上述过程,把有效的返回替换了原有返回内容,成功实现了注册。然后在虚拟机中试验成功了。

软件使用了 HTTP 没用 HTTPS,直接访问 IP 地址的。现在的思路是使用 Proxifier 强制软件走代{过}{滤}理,然后自己编写一个 HTTP 服务作为代{过}{滤}理服务器。Proxifier 默认不允许 HTTP 代{过}{滤}理,需要手动开启一下。

本来想软件如果通过域名访问,直接修改 hosts 把域名重定向到本地就好了,发现只访问 IP 还挺麻烦,目前没想到能不使用 Proxifier 的方法,如有方法还请评论区建议。

题主主修人工智能,因此擅长 Python,通过 Python aiohttp 框架编写一个 HTTP 服务器,并代{过}{滤}理一个 IP 下的服务:

import asyncio
import re
import socket
from datetime import datetime, timedelta
from multiprocessing import Queue

from aiohttp import ClientSession
from aiohttp.web import Application, Request, Response, RouteTableDef, run_app

from src.config import LOCK_VERSION, TARGET_HOST, TARGET_PORT, TEMPLATE

routes = RouteTableDef()

def is_port_available(host: str, port: int) -> bool:
    """检查端口是否可用"""
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    result = sock.connect_ex((host, port))
    sock.close()
    return result != 0

async def _make_proxy(request: Request) -> Response:
    """返回代{过}{滤}理数据"""
    async with ClientSession() as session:
        async with session.request(
            method=request.method,
            url=f"http://{TARGET_HOST}:{TARGET_PORT}{request.path}",
            headers=request.headers,
            params=request.query,
            data=await request.read() if request.can_read_body else None,
        ) as response:
            headers = {
                "Accept": response.headers.get("Accept", ""),
                "Host": response.headers.get("Host", ""),
                "Content-type": response.headers.get("Content-type", ""),
                "Set-Cookie": response.headers.get("Set-Cookie", ""),
                "Expires": response.headers.get("Expires", ""),
                "Referer": response.headers.get("Referer", ""),
                "Location": response.headers.get("Location", ""),
                "User-Agent": response.headers.get("User-Agent", ""),
                "Cookie": response.headers.get("Cookie", ""),
            }
            headers.pop("Transfer-Encoding", None)
            return Response(
                body=await response.read(),
                headers=headers,
                status=response.status,
            )

软件通过字符串匹配获取软件的余剩使用日期(不得不说太 low 了),直接注册到两年后。

这就是一个基本的 HTTP 代{过}{滤}理服务,下面是代{过}{滤}理 GET 请求:

@routes.get("/{tail:.*}")
async def proxy_get(request: Request):
    """代{过}{滤}理所有 GET 请求"""
    queue: Queue = request.app["queue"]
    current_date = datetime.now().strftime("%Y-%m-%d")
    code = request.query.get("s_code", "")
    # 注册拦截器
    if "/reg.php":
        end_date = (datetime.now() + timedelta(days=730)).strftime("%Y-%m-%d")
        queue.put(f"获取到机器码:{code},正在注册到 {end_date}。")
        return Response(
            text=TEMPLATE.format(
                code=code,
                current_date=current_date,
                end_date=end_date,
            ),
            headers={
                "Content-type": "text/html; charset=UTF-8",
            },
        )

    is_locked = request.app.get("is_locked", False)
    # 检查是否锁版本
    if "/update.php" in request.path and is_locked:
        queue.put(f"检测到版本请求,已锁定版本")
        return Response(
            text=LOCK_VERSION.format(
                current_date=current_date,
            ),
            headers={
                "Content-type": "text/html; charset=UTF-8",
            },
        )
    return await _make_proxy(request)

解释一下:

  • queue:进程队列
  • LOCK_VERSION:是否锁定版本,如果有需求可以自己设计
  • TARGET_HOST:目标主机 IP
  • TARGET_PORT:代{过}{滤}理目标端口
  • TEMPLATE:返回的模板代码,自己根据需要写

锁定版本是防止软件强制更新,我已经抓到以前的响应模板,这样如果需要锁定版本可以直接发送之前的更新请求的响应。

这里进程队列用于和其他进程通信,这里我使用 Python 标准库 TK 来设计 UI。可以通过 UI 查看日志信息。

下面是运行服务的代码:

@routes.post("/{tail:.*}")
async def proxy_post(request: Request):
    """代{过}{滤}理所有 POST 请求"""
    return await _make_proxy(request)

def run_simple_server(queue: Queue, host: str, port: int):
    """运行服务器"""
    app = Application()
    app["queue"] = queue
    app.add_routes(routes)
    if not is_port_available(host, port):
        queue.put(f"端口 {port} 被占用!请勿重复打开程序,现在请关闭全部程序后重试。")
        return
    try:
        queue.put(f"注册机启动成功!")
        queue.put({"msg": "ready"})
        run_app(app, host=host, port=port)
    except RuntimeError:
        pass

if __name__ == "__main__":
    run_simple_server(Queue(), "127.0.0.1", 8899)

我这里还使用多进程以便能通过进程通信:

import multiprocessing as mp

from src.server import run_simple_server
from src.ui import simple_tkinker_ui

HOST = "127.0.0.1"
PORT = 8899

if __name__ == "__main__":
    mp.freeze_support()
    queue = mp.Queue()

    p1 = mp.Process(target=run_simple_server, args=(queue, HOST, PORT))
    p1.start()

    p2 = mp.Process(target=simple_tkinker_ui, args=(queue, HOST, PORT))
    p2.start()

如果你觉得你不需要 UI,可以删除对应部分运行,直接打印日志。

UI 的代码太长,没有放出来。其实也无关紧要,以上代码用来学习测试即可。

这里使用 Nuitka 打包代码:

@echo off
python -m nuitka --standalone --onefile ^
    --mingw64 --show-progress --disable-console ^
    --plugin-enable=tk-inter --output-dir=dist ^
    --assume-yes-for-downloads main.py

这样每次使用软件之前启动一下脚本和 Proxifier,软件就以为自己已经注册过了。

不知道有没有更简单的,在 Windows 上实现 HTTP 拦截的方法。因为请求是 IP 地址没有加密,理论上可以在网关上拦截然后不再需要注册机和 Proxifier,但是有点复杂,Linux 似乎有工具直接支持拦截 HTTP 包。

先写到这,如果有不详细的地址再更新。

屏幕截图 2024-03-20 101013.png (104.73 KB, 下载次数: 1)

屏幕截图 2024-03-20 101013.png

免费评分

参与人数 3吾爱币 +9 热心值 +3 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
youngdh + 1 + 1 谢谢@Thanks!
roninZ + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
pentest686 发表于 2024-3-20 23:49
cyhcuichao 发表于 2024-3-20 23:40
APP有代{过}{滤}理检测 只要打开就不能截包有什么办法吗

1、使用基于VPN模式的Postern
vproxid、rproxid、
https://github.com/postern-overwal/postern-stuff
2、使用基于iptables的ProxyDroid
https://github.com/cxf-boluo/mag ... /org.proxydroid.apk
推荐
moonlune 发表于 2024-3-20 21:52
此类似类方法很久以前用过,但是当时使用的是Proxomitron。原理是,某个软件每次启动都会http联网发送一个验证,如果是符合的验证码,那么会返回某段注册成功信息。然后只要把返回的某段信息无论是什么,都给修改为返回注册成功信息,就可以了。
沙发
夏驰 发表于 2024-3-20 13:10
3#
lambchasr 发表于 2024-3-20 13:15
mark,收藏备用
4#
听说哥 发表于 2024-3-20 13:23
虽然不知道怎么用,感谢分享
5#
pentest686 发表于 2024-3-20 13:24
mitmproxy应该可以,mitm监听80端口,再通过host将域名定位到本机。只启动mitmproxy就可以,不是开发,不擅长编程,仅提供思路
6#
juqkai 发表于 2024-3-20 13:42
如果是你自己用,感觉可以去路由器里面找找,看有没有拦截转发的功能,
7#
risingsun 发表于 2024-3-20 13:52
pentest686 发表于 2024-3-20 13:24
mitmproxy应该可以,mitm监听80端口,再通过host将域名定位到本机。只启动mitmproxy就可以,不是开发,不擅 ...

我使用mitmproxy,安装了证书,但是https的包还是都抓不到,不知道为啥。
8#
dd1ka 发表于 2024-3-20 14:03
很好的思路,值得学习,感谢大佬分享
9#
n1ghtc4t 发表于 2024-3-20 14:22
思路很好 值得学习 点赞
10#
pjy612 发表于 2024-3-20 15:27
以前易语言里面有个 网络拦截组件 还挺强的。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-5 20:45

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表