跳到主要内容

发送 HTTP 原始数据包

在 Yak 中除了可以使用 Golang 原生封装的 http 模块之外,提供了一种专门为安全优化的 "直接发送原始数据包" 的办法。

rsp, req, err := poc.HTTP(`
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)

`)
die(err)

println(string(rsp))
自动修复数据包但是不会自动问题

一般来说,您并不需要重新计算 Content-Length,yak 会替你完成这一步。

在重新计算 Content-Length 的时候,并不会伤害其他的部分编码。

也就是说,用户需要对自己的编码行为负责。发出去的数据包一般就是原始数据包(除了 Content-Length 部分)。

上述脚本输出内容为:

HTTP/1.1 200 OK
Age: 341744
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Sat, 05 Mar 2022 14:01:06 GMT
Etag: "3147526947+ident"
Expires: Sat, 12 Mar 2022 14:01:06 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (dcb/7F83)
Vary: Accept-Encoding
X-Cache: HIT
Connection: close
Content-Length: 1256

<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
...
...}
</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

解释

poc.HTTP 是最基础的函数功能,核心定义为:

func poc.HTTP(req, ...params) returns (rsp []byte, req []byte, err error)

一般处理 err 使用 die(err) 即可实现。

poc 模块其他常见操作

poc.HTTP 增加高级参数

Yak 大多数功能包中 "小写字母" 的导出一般意味着他是一个 "参数"。

我们需要制定一些高级参数,来控制 poc 中 "细微" 的操作步骤。例如,我们需要增加 "代理" 功能,同时强制开启 HTTPS 可以执行如下代码

rsp, req, err := poc.HTTP(`
GET / HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)

`, poc.proxy("http://127.0.0.1:7890"), poc.https(true))
die(err)

poc.HTTP 动态修改数据包

一般来说,我们的数据包通常不会是固定的,为了更自由的发送一些 "内容"。我们需要 "标注" 那些地方需要被动态替换,然后使用 poc.params 高级参数来动态替换。

// 构建一个想要动态渲染的参数值
targetHost = "www.baidu.com"
port = 80
target = str.HostPort(targetHost, port)

// 构建请求模版,通过 {{params(*)}} 动态渲染参数
rsp, req, err := poc.HTTP(`
GET /admin/ HTTP/1.1
Host: {{params(target)}}
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)

`, poc.params({
"target": target, // 设置参数
}))
die(err)

printf("http.Response' s MD5: %v", codec.Md5(rsp))

poc.ParseBytesToHTTPResponse 将字节码转换成原生http.Response对象

rsp, req, err := poc.HTTP(`
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)

`,poc.proxy("http://127.0.0.1:8083"))
die(err)


httpRsp,err = poc.ParseBytesToHTTPResponse(rsp) //将字节码转换成http.Response对象

http.show(httpRsp)

输出结果如下

HTTP/1.1 200 OK
Connection: close
Content-Length: 1256
Accept-Ranges: bytes
Age: 562610
Cache-Control: max-age=604800
Content-Encoding: identity
Content-Type: text/html; charset=UTF-8
Date: Mon, 07 Mar 2022 03:20:04 GMT
Etag: "3147526947"
Expires: Mon, 14 Mar 2022 03:20:04 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECS (sab/56F1)
Vary: Accept-Encoding
X-Cache: HIT

<!doctype html>
<html>
<head>
<title>Example Domain</title>

<meta charset="utf-8" />
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
body {
background-color: #f0f0f2;
margin: 0;
padding: 0;
font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;

}
div {
width: 600px;
margin: 5em auto;
padding: 2em;
background-color: #fdfdff;
border-radius: 0.5em;
box-shadow: 2px 3px 7px 2px rgba(0,0,0,0.02);
}
a:link, a:visited {
color: #38488f;
text-decoration: none;
}
@media (max-width: 700px) {
div {
margin: 0 auto;
width: auto;
}
}
</style>
</head>

<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>

poc.ParseBytesToHTTPRequest 将字节码转换成原生http.Request对象

rsp, req, err := poc.HTTP(`
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)

`,poc.proxy("http://127.0.0.1:8083"))
die(err)

httpReq,err = poc.ParseBytesToHTTPRequest(req) //将字节码转换成http.Request对象

http.show(httpReq)

输出结果如下

GET / HTTP/1.1
Host: www.example.com
Content-Length: 0
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)