Golang -代码学习笔记

Golang -代码学习笔记

Created
Jul 23, 2021 08:54 AM
Tags
编程语言
GO

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)
}
效果:
notion image
 

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结构体:
  1. https://www.sojson.com/json/json2go.html
  1. https://mholt.github.io/json-to-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()