有一天突发奇想,很好奇那些抓包软件是如何做的,所以就特地去研究了一下。
分享一下如何通过程序的方式设置Windows全局代理,包括代理模式的开启或关闭以及代理服务器IP、端口的动态改变。
关于全局代理有比较多的应用场景,如抓包工具Wireshark、Fiddler、Fiddler、VPN都会涉及到Windows的代理,就拿Wireshark抓包工具来说,为什么它可以拦截到我们所有请求?下面介绍一下设计到的原理和代码实现。
在开始讲解原理之前,我们先来看一下如何通过界面的方式开启Windows全局代理。首先在自己的电脑上搜索代理服务器设置
,找到后打开可看到如下界面:
然后点击设置,我们就可以看到下面这个界面,在这里主要关注3个部分,分别是代理的开关、代理ip地址和端口。
当我们在这里打开全局代理的开关后,Windows中所有的请求都会首先通过这里,这一点很重要,然后再将请求发送出去,因此我们就可以在我们自己的程序中编写程序监听这个ip和端口,实现拦截的操作,下面是一些抓包工具的简要原理图。
从上图我们可以看出,如果需要拦截到程序中所有的请求并进行处理,首先就需要开启代理服务并知道IP地址和端口号,那么是如何通过程序进行控制的呢?这里会设计到Windows注册表的使用,下面进行介绍。
为了方便下面的讲解,这里特别说明一下,本文涉及到的代理ip和端口都以上图的为准,也就是127.0.0.1和33210,下文以抓包工具案例进行讲解。
在抓包软件中,对代理的操作,一般有4步,分别是开启代理、关闭代理、设置代理地址、删除代理地址,其实,本质上在程序中控制这4个操作,是通过操作Windows注册表
来实现的。
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f
在下面这个指令中,我们添加了参数127.0.0.1:33210,这个就是设置代理ip和端口。
reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /t REG_SZ /d "127.0.0.1:33210" /f
reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /f
从上面我们知道它是通过注册表命令reg
实现的,可以在cmd窗口执行,因此它也具备了通过程序方式的调用,从而在我们的业务逻辑中进行动态操作,比如Java程序可以通过Runtime.getRuntime().exec(command)
调用上面的注册表命令,Go语言可以使用exec.Command(command)
调用。
为了减少代码行数,下面以Go语言为例介绍如何通过程序的方式操作代理以及如何拦截Windows中所有的请求,这也是抓包工具的应用。
这一步就是把全局代理的开关给打开。
package main
import (
"log"
"os/exec"
)
func main() {
// 使用 exec.Command 执行 reg add 命令
// reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 1 /f
cmd := exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyEnable", "/t", "REG_DWORD", "/d", "1", "/f")
// 执行命令
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
log.Println("全局代理已开启")
}
当我们在代码中执行这段程序以后,就会发现在Windows代理配置中多了127.0.0.1:33210
的配置。
package main
import (
"log"
"os/exec"
)
func main() {
// 使用 exec.Command 执行 reg add 命令
// reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /t REG_SZ /d "127.0.0.1:12888" /f
cmd := exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyServer", "/t", "REG_SZ", "/d", "127.0.0.1:33210", "/f")
// 执行命令
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
log.Println("代理信息已添加")
}
这里需要注意,这里只是将代理的开关给关掉了,并没有删除上面添加的代理信息,所有就有了下面的一个步骤。
package main
import (
"log"
"os/exec"
)
func main() {
// 使用 exec.Command 执行 reg add 命令
// reg add "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyEnable /t REG_DWORD /d 0 /f
cmd := exec.Command("reg", "add", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyEnable", "/t", "REG_DWORD", "/d", "0", "/f")
// 执行命令
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
log.Println("代理已关闭")
}
这一步就会删除注册表中的配置的代理信息(不想删也可以不删,随意)。
package main
import (
"log"
"os/exec"
)
func main() {
// 使用 exec.Command 执行 reg delete 命令
// reg delete "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings" /v ProxyServer /f
cmd := exec.Command("reg", "delete", "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", "/v", "ProxyServer", "/f")
// 执行命令
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
log.Println("代理信息已删除")
}
其实这里就是通过Socket监听上面配置的代理ip:port
,从而达到拦截所有TCP请求的目的,这里会设计到网络编程
的应用,下面以Go语言为例,用代码简单演示一下。
package main
import (
"fmt"
"log"
"net"
)
func main() {
// 在本地地址127.0.0.1:33210上启动TCP监听
listener, err := net.Listen("tcp", "127.0.0.1:33210")
if err != nil {
log.Fatal("监听失败:", err)
}
fmt.Println("等待连接...") // 输出等待连接的提示消息
// 接受连接并处理数据
for {
conn, err := listener.Accept() // 接受连接请求
if err != nil {
log.Fatal("接收连接失败:", err)
}
go handleConnection(conn) // 在协程中处理连接
}
}
func handleConnection(conn net.Conn) {
defer conn.Close() // 延迟关闭连接,确保在函数返回时连接被关闭
buffer := make([]byte, 1024) // 创建一个缓冲区用于接收数据
for {
readLen, err := conn.Read(buffer) // 读取数据到缓冲区
if err != nil {
log.Println("读取数据失败:", err)
break
}
data := string(buffer[:readLen]) // 将字节数据转换为字符串
fmt.Println("接收到数据:", data) // 打印接收到的数据
}
}
启动上面代码后,然后去浏览器随便打开一个页面,可以发现请求的报文都被我们编写的程序拦截到了,还有就是,如果我们电脑中有一些守护进程定时发送的请求也会被拦截到(这就有点儿意思啦,有些公司就是就喜欢偷偷默默搞一些隐藏程序监控员工电脑),下面是演示运行截图。
上面若有手误或错误的地方请在评论区留言。
无线路由攻击和WiFi密码破解实战[渗透技术]