0x01 GO 建立HTTP和HTPPS服务端
http
package main
import (
"fmt"
"github.com/fatih/color"
"net/http"
)
func sayhello(w http.ResponseWriter, r *http.Request) {
r.ParseForm() // 解析参数,默认是不会解析的
//fmt.Println("URL:", r.URL)
//fmt.Println("Method:", r.Method)
//fmt.Println("Host:", r.Host)
//fmt.Println("Header:", r.Header)
color.Cyan("RemoteAddr:%s", r.RemoteAddr)
color.Red("Header:")
for k, v := range r.Header {
fmt.Printf("%s:%s\n", k, v)
}
/*
Origin:[http://127.0.0.1:8081]
Content-Type:[application/x-www-form-urlencoded]
Sec-Fetch-Mode:[navigate]
Content-Length:[4]
User-Agent:[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36]
Sec-Fetch-Site:[same-origin]
Sec-Fetch-User:[?1]
Referer:[http://127.0.0.1:8081/?a=123]
Accept-Encoding:[gzip, deflate, br]
Cache-Control:[max-age=0]
Accept-Language:[zh-CN,zh;q=0.9,en;q=0.8]
Connection:[keep-alive]
Sec-Ch-Ua:[".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"]
Sec-Ch-Ua-Platform:["macOS"]
Upgrade-Insecure-Requests:[1]
Accept:[text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,]
Sec-Fetch-Dest:[document]
*/
color.Red("Param:")
for k, v := range r.Form { //包括get、post的参数
fmt.Printf("%s:%s\n", k, v)
}
fmt.Fprintf(w, "Hello T0Night!")
}
func main() {
http.HandleFunc("/", sayhello)
http.ListenAndServe(":8081", nil)
}
https
证书和私钥生成方法:
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt
package main
import (
"fmt"
"log"
"net/http"
)
func sayhello(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "hello")
}
func main() {
http.HandleFunc("/", sayhello)
log.Fatal(http.ListenAndServeTLS(":443", "./server.crt", "./server.key", nil))//参数一是端口,参数二是证书,参数三是私钥
}
https Get添加Authorization认证
func MyGet(url string) (response []byte) {
//想服务器发送服务
req, err_1 := http.NewRequest("GET", url, nil)
checkerr(err_1)
req.Header.Add("Authorization", Authorization)
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
res, err_2 := client.Do(req)
// checkerr(err_2)
if err_2 != nil {
fmt.Println("requests error %s", err_2)
return nil
}
body, _ := ioutil.ReadAll(res.Body)
return body
}
https Post添加Authorization认证
func SubmitFlag(ans string) {
data := url.Values{}
data.Add("answer", ans)
b := bytes.NewBuffer([]byte(data.Encode()))
req, err_1 := http.NewRequest("POST", submitflag_url, b)
checkerr(err_1)
req.Header.Add("Authorization", Authorization)
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
res, err_2 := client.Do(req)
if err_2 != nil {
fmt.Println("download error %s", err_2)
}
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
0x02 发送网络请求
GET
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func checkerr(e error) {
if e != nil {
fmt.Println(e)
}
}
func main() {
url := "http://10.211.55.9/"
res, err := http.Get(url)
checkerr(err)
defer res.Body.Close()
//获取网页内容
body, _ := ioutil.ReadAll(res.Body) //body为byte类型
fmt.Println(string(body))
//获取header信息
header := res.Header
for k, v := range header {
fmt.Println(k, ":", v)
}
//获取网页响应码
status_code := res.StatusCode
fmt.Printf("状态码:%d", status_code)
/*添加请求头
client := &http.Client{}
req,_ := http.NewRequest("GET","http://www.xxx.com",nil)
req.Header.Add("name","zhaofan")
resp,_ := client.Do(req)
defer resp.Body.close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf(string(body))
*/
}
POST
package main
import (
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
func checkerr(e error) {
if e != nil {
fmt.Println(e)
}
}
func main() {
myurl := "http://10.211.55.9/"
post_data := url.Values{}
post_data.Add("user", "radish")
res, err := http.PostForm(myurl, post_data)
checkerr(err)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
/*
另一种方法
myurl := "http://10.211.55.9/"
res, err := http.Post(myurl, "application/x-www-form-urlencoded", strings.NewReader("user=radish"))
checkerr(err)
body, _ := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
*/
}
0x03 GO调用Windows API
package main
import (
"fmt"
"syscall"
"unsafe"
)
var (
user32 = syscall.NewLazyDLL("user32.dll")
messageBox = user32.NewProc("MessageBoxW")
MB_YESNOCANCEL = 0x00000003
)
func main() {
ret, _, _ := messageBox.Call(0,
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("woo~"))),
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("nb"))),
uintptr(MB_YESNOCANCEL))
fmt.Printf("Return: %d\n", ret)
}
效果:
0x04 查看GO build支持的系统
radish ➜ arm_demo go tool dist list
android/386
android/amd64
android/arm
android/arm64
darwin/386
darwin/amd64
darwin/arm
darwin/arm64
dragonfly/amd64
freebsd/386
freebsd/amd64
freebsd/arm
linux/386
linux/amd64
linux/arm
linux/arm64
linux/mips
linux/mips64
linux/mips64le
linux/mipsle
linux/ppc64
linux/ppc64le
linux/s390x
nacl/386
nacl/amd64p32
nacl/arm
netbsd/386
netbsd/amd64
netbsd/arm
openbsd/386
openbsd/amd64
openbsd/arm
plan9/386
plan9/amd64
plan9/arm
solaris/amd64
windows/386
windows/amd64
0x05 普通指针类型、unsafe.Pointer、uintptr之间的关系
1、普通指针类型(*类型),用于传递对象地址,不能进行指针运算
2、unsafe.Pointer为通用指针类型,用于转换不同类型的指针,不能进行指针运算,不能读取内存存储的值,必须转换到某一类型的普通指针。
3、uintptr用于指针运算,GC不能把uintptr当指针,它无法持有对象。
0x06 执行shellcode
Linux
func ExecShellcode(shellcode []byte) {
shellcodeAddr := uintptr(unsafe.Pointer(&shellcode[0]))
page := getPage(shellcodeAddr)
syscall.Mprotect(page, syscall.PROT_READ|syscall.PROT_EXEC)
shellPtr := unsafe.Pointer(&shellcode)
shellcodeFuncPtr := *(*func())(unsafe.Pointer(&shellPtr))
go shellcodeFuncPtr()
}
Windows
const (
MEM_COMMIT = 0x1000
MEM_RESERVE = 0x2000
PAGE_EXECUTE_READWRITE = 0x40 // Execute
)
func ExecShellcode(shellcode []byte) {
// Resolve kernell32.dll, and VirtualAlloc
kernel32 := syscall.MustLoadDLL("kernel32.dll")
VirtualAlloc := kernel32.MustFindProc("VirtualAlloc")
// Reserve space to drop shellcode
address, _, _ := VirtualAlloc.Call(0, uintptr(len(shellcode)), MEM_RESERVE|MEM_COMMIT, PAGE_EXECUTE_READWRITE)
// Ugly, but works
addrPtr := (*[990000]byte)(unsafe.Pointer(address))
// Copy shellcode
for i, value := range shellcode {
addrPtr[i] = value
}
go syscall.Syscall(address, 0, 0, 0, 0)
}
0x06 设置GOProxy
export GO111MODULE=on#在go build之前,要把此选项归置为auto
export GOPROXY=https://goproxy.io
0x07 函数
strings.HasPrefix(src,"start")//返回一个布尔值,如果字符串src是以第二个参数开头,则返回true,否则返回false
0x08 字符串操作
strings.Contains(filename, "flag")#是否包含子串
strings.Index(string(filename), "flag")#是否包含子串,不包含返回-1
strings.Split(user_input, " ")#字符串以指定字符进行切割
strings.Replace(filename, "\n", "", -1))#字符串替换
0x09 处理Json
json转Go结构体:
type heart_res struct {
Status int `json:"status"`
Msg string `json:"msg"`
}
tmp := heart_res{}
json.Unmarshal(response, &tmp)//response就是byte的json字符串
0x0A 获取文件MD5值
func CalcFileMD5(filename string) (string, error) {
f, err := os.Open(filename) //打开文件
if nil != err {
fmt.Println(err)
return "", err
}
defer f.Close()
md5Handle := md5.New() //创建 md5 句柄
_, err = io.Copy(md5Handle, f) //将文件内容拷贝到 md5 句柄中
if nil != err {
fmt.Println(err)
return "", err
}
md := md5Handle.Sum(nil) //计算 MD5 值,返回 []byte
md5str := fmt.Sprintf("%x", md) //将 []byte 转为 string
return md5str, nil
}
0x0B 多线程框架
var wg sync.WaitGroup
wg.Add(3)
go func() {
defer wg.Done()
for {
/*
print your code
*/
}
}()
go func() {
defer wg.Done()
for {
/*
print your code
*/
}
}()
go func() {
defer wg.Done()
for {
/*
print your code
*/
}
}()
wg.Wait()