前言

这个工具起因是看到了 soapffz 师傅写的 《搭建本地 ip 代理池》

通过注册表修改本地代理设置,从而自动修改代理访问站点

正好这几天在学习Go,想着自己也整一个,开搞开搞

环境

Windows10 1803
Chrome 76
Go

效果

使用方法如下:

proxy.exe -u http://127.0.0.1:5010/get_all/ -t 10

会从 http://127.0.0.1:5010/get_all/ 地址抓取ip代理,然后每隔 10 秒更换新代理,遍历结束后恢复原本代理设置

帮助:

C:\Users\xxx\proxy.exe -h
Usage of proxy.exe:
  -c string
        -c cls 重置代理设置为自动代理
  -l int
        循环次数 (default 1)
  -t int
        自动切换代理时间间隔 (default 30)
  -u string
        代理 Url,例如 http://127.0.0.1:5010/get_all

github:https://github.com/Lhaihai/Go_Auto_Proxy

目前比较遗憾的是获取到的IP不一定是HTTPS,如果师傅们有资源可以自行修改下 getproxy 函数和 Proxy_Pool 结构体

获取IP代理

逛了一圈下来,觉得 proxy_pool 使用起来效果不错

github:https://github.com/jhao104/proxy_pool

作者已经制作好docker,但还需要我们自己安装redis,那就整个redis的docker吧,可以直接docker run,但如果两个docker不在同一个C段,可以加上 --net=host 让docker能访问在主机的网络,但这样明显不太安全

启动redis
docker run -d --name redisDynamic redis:latest

docker pull jhao104/proxy_pool

拿到redis的ip,修改下面的db_host参数
docker inspect  redisDynamic | grep IPAddress

docker run --env db_type=REDIS --env db_host=172.17.0.3 --env db_port=6379 --env db_password= -p 5010:5010 --net=host jhao104/proxy_pool

为什么不整个docker-compose呢,多方便

version: '2'
services:
 web:
   image: jhao104/proxy_pool
   ports:
    - "5010:5010"
   environment:
    - db_type=REDIS
    - db_host=redis
    - db_port=6379
    - db_password=
   depends_on:
    - redis
   links:
    - redis:redis
 redis:
   image: redis:latest

复制上面内容到docker-compose.yml文件里,docker-compose up -d 启动即可

然后等几分钟,访问 ip:5010 即可

通过 /get_all 接口可以拿到所有代理的Json数据

json to go 可以根据 json 数据生成对应的 struct ,十分方便
https://mholt.github.io/json-to-go/

随便起个名字,就 Proxy_Pool ,关键代码如下,这样就解析好json的代理数据了,保存在 proxys 变量里

r, err := http.Get(Url)
    if err != nil{
        fmt.Println("超时")
    }
    defer r.Body.Close()
    body, err := ioutil.ReadAll(r.Body)
    data := string(body)


    var proxys Proxy_Pool
    _ = json.Unmarshal([]byte(data), &proxys)

检查IP可用性

虽然可以自己实现走代理访问站点检测一下,但在找代理的时候发现有帮忙代理检测的接口,还检测了匿名度和延迟,真好

关键代码

rooturl := "http://www.xdaili.cn/ipagent/checkIp/ipList?"

    for _, r := range proxys{
        if r.FailCount == 0 {
            rooturl = rooturl+"ip_ports%5B%5D="+r.Proxy+"&"
        }
    }

    data2 := Get(rooturl)
    var f ipresult
    _ = json.Unmarshal([]byte(data2), &f)

    proxy := StoreProxy{}
    fmt.Println(len(f.RESULT))
    for _, r := range f.RESULT {
    //如果Anony不为空且不为透明,延时不超过1s,就保存起来
        if r.Anony != "\"透明\"" && r.Anony != "" && len(r.Time) < 6 {
            proxy = append(proxy,r)
            fmt.Println(r)
        }
    }

这样就拿到一些可以用的代理了,接下来就要修改本地代理设置了

Windows 10 修改代理

一般修改代理,操作就是刚开始用burpsuite的时候,打开internet设置 -> 连接 -> 局域网设置 -> 修改代理服务器为 127.0.0.1 8080

同时 IE 代理可以通过注册表去修改,位置是

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections

默认情况下有下面两个KEY

DefaultConnectionSettings
SavedLegacySettings

DefaultConnectionSettings:保存了浏览器当前配置的连接设置

SavedLegacySettings:是DefaultConnectionSettings的副本,不是默认连接外的网络 连接使用的配置

于是DefaultConnectionSettings和SavedLegacySettings的设置时一样的

接下来分析下怎么修改 DefaultConnectionSettings

打开代理和注册表,可以看到配置脚本和IP都存在注册表的数据里面

  1. 每个设置间隔三个00,即000000
  2. 最开始46固定,然后间隔
  3. 第0x04位开始的 39 16 是自增位,可以设置为00
  4. 第0x08位 05 是代理开关设置,然后间隔
  5. 第0x0C位 0C 是后面IP的长度,然后间隔
  6. 第0x10位 开始ip:port地址,ip信息最后一位是指下一个间隔数据的长度,即<local>的长度(看下一张图),然后间隔
  7. <local>后固定2B结尾,然后间隔
  8. 最后是自动配置脚本链接

<local> 存在表示勾选了 对于本地地址不使用代理服务器

再讲讲代理开关设置

  • 0F全部开启(ALL);01全部禁用(Off)
  • 03使用代理服务器(ProxyOnly);05使用自动脚本(PacOnly);
  • 07使用脚本和代理(ProxyAndPac);09打开自动检测设置(D);
  • 0B打开自动检测并使用代理(DIP);0D打开自动检测并使用脚本(DS);

我们主要要修改 代理开关设置,IP长度,IP:Port地址

因为是要走代理服务器,所以代理开关设置为 03

原理大概讲清楚了,下面就来用 Go 修改注册表

Go 修改注册表

Go 有封装一个修改注册表的包:golang.org/x/sys/windows/registry

官方文档在这里:https://godoc.org/golang.org/x/sys/windows/registry#Key.GetBinaryValue

比如要获取 注册表 某个key的内容

func get_DefaultConnectionSettingsValue() string{
    key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections`, registry.ALL_ACCESS)
    defer key.Close()
    if err != nil{
        panic(err)
    }

    s, _, _ := key.GetBinaryValue(`DefaultConnectionSettings`)
    d := ""
    for _,x := range s{
        d = d + fmt.Sprintf("%02x",x)
    }
    return d
}

如果要修改内容,DefaultConnectionSettings 是 Binary 类型,用SetBinaryValue函数来设置,注意传入的是 []byte 类型的内容

func (k Key) SetBinaryValue(name string, value []byte) error

于是,封装个设置代理的函数

//传入要修改keyname和16进制字符串
// data 参数 举个例子:46000000431600000500000000000000070000003c6c6f63616c3e2b000000687474703a2f2f3132372e302e3
func set_proxy(keyname string,data string){
    key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections`, registry.ALL_ACCESS)
    defer key.Close()
    if err != nil{
        panic(err)
    }

    //把16进制字符串转为byte切片
    bytedata := []byte{}
    for i:=0 ; i<len(data)-2; i=i+2{
        t := data[i:i+2]
        n, err := strconv.ParseUint(t, 16, 32)
        if err != nil {
            panic(err)
        }
        n2 := byte(n)
        bytedata = append(bytedata,n2)
    }

    err = key.SetBinaryValue(keyname,bytedata)
    if err != nil{
        panic(err)
    }
    fmt.Println("代理设置成功")
}

接下来只要生成相应IP的设置数据即可,关键代码如下

ip := "127.0.0.1:8080"
    p1 := d[:16] //460000003A160000
    switch_proxy :=  "03" // d[16:18]

    leng := fmt.Sprintf("%02x",(len(ip)))  //如果ip长度小于16,前面补0
    iphex := hex.EncodeToString([]byte(ip))

    data := p1 + switch_proxy + "000000" + leng + "000000" + iphex + "070000003c6c6f63616c3e2b000000"

    //调用上面写好的设置代理函数
    set_proxy("DefaultConnectionSettings",data)

完整代码放在github上了:https://github.com/Lhaihai/Go_Auto_Proxy

参考文章

[1] 搭建本地 ip 代理池 (完结)

https://soapffz.com/94.html

[2] Windows上利用Python自动切换代理IP

https://segmentfault.com/a/1190000004315166

[3] What is DefaultConnectionSettings key?

https://blogs.msdn.microsoft.com/askie/2017/06/20/what-is-defaultconnectionsettings-key/

点击收藏 | 1 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖