首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
编程技术
发新帖
0
1
[原创]gominipwn
发表于: 2025-10-7 19:17
1296
[原创]gominipwn
Jtian
1
2025-10-7 19:17
1296
# 说明 这是一个实验性质的项目,方便在离线场景下使用golang编写exp,编码风格参考了pwntools。 # 代码gominipwn ``` package main import ( "bufio" "bytes" "encoding/binary" "encoding/hex" "errors" "fmt" "io" "net" "os" "runtime" "strings" "sync" "time" ) // ============================= // // Packing/Unpacking // // ============================= // func getEndian(endian string) (binary.ByteOrder, error) { e := strings.ToLower(endian) switch e { case "little", "le", "": return binary.LittleEndian, nil case "big", "be": return binary.BigEndian, nil default: return nil, fmt.Errorf("endian must be 'little' or 'big'") } } func p8(x uint8, _ ...any) []byte { return []byte{byte(x)} } // b: helper to convert string to []byte, similar to Python's b"..." func b(s string) []byte { return []byte(s) } // cat: concatenate multiple byte slices efficiently func cat(parts ...[]byte) []byte { total := 0 for _, p := range parts { total += len(p) } out := make([]byte, 0, total) for _, p := range parts { out = append(out, p...) } return out } // rep: repeat a byte slice n times, like Python b"..." * n func rep(p []byte, n int) []byte { if n < 0 { panic("rep: negative count") } if n == 0 || len(p) == 0 { return []byte{} } out := make([]byte, 0, len(p)*n) for i := 0; i < n; i++ { out = append(out, p...) } return out } // fromhex: decode hex string (whitespace ignored) to bytes, like Python bytes.fromhex func fromhex(s string) []byte { s = strings.ReplaceAll(s, " ", "") if len(s)%2 != 0 { panic("fromhex: odd length hex string") } b, err := hex.DecodeString(s) if err != nil { panic(err) } return b } func p16(x uint16, endian ...string) []byte { var buf bytes.Buffer e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if err := binary.Write(&buf, order, x); err != nil { panic(err) } return buf.Bytes() } func p32(x uint32, endian ...string) []byte { var buf bytes.Buffer e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if err := binary.Write(&buf, order, x); err != nil { panic(err) } return buf.Bytes() } func p64(x uint64, endian ...string) []byte { var buf bytes.Buffer e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if err := binary.Write(&buf, order, x); err != nil { panic(err) } return buf.Bytes() } func u8(b []byte, _ ...any) uint8 { if len(b) < 1 { panic("u8: buffer too small") } return uint8(b[0]) } func u16(b []byte, endian ...string) uint16 { e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if len(b) < 2 { panic("u16: buffer too small") } return order.Uint16(b[:2]) } func u32(b []byte, endian ...string) uint32 { e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if len(b) < 4 { panic("u32: buffer too small") } return order.Uint32(b[:4]) } func u64(b []byte, endian ...string) uint64 { e := "" if len(endian) > 0 { e = endian[0] } order, err := getEndian(e) if err != nil { panic(err) } if len(b) < 8 { panic("u64: buffer too small") } return order.Uint64(b[:8]) } // ============================= // // Pwn // // ============================= // type Pwn struct { conn net.Conn rw *bufio.ReadWriter logPrefix map[string]string // 交互模式:在 Windows 使用 goroutine 实现 interactiveStop chan struct{} onceClose sync.Once } func NewPwn() *Pwn { return &Pwn{ logPrefix: map[string]string{ "info": "[*] ", "success": "[+] ", "error": "[-] ", }, interactiveStop: make(chan struct{}), } } func (p *Pwn) log(level, msg string) { prefix := p.logPrefix[level] fmt.Printf("%s%s\n", prefix, msg) } // ============================= // // Core Methods // // ============================= // func remote(host string, port int) *Pwn { p := NewPwn() address := net.JoinHostPort(host, fmt.Sprintf("%d", port)) conn, err := net.Dial("tcp", address) if err != nil { panic(err) } p.conn = conn p.rw = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn)) return p } func (p *Pwn) send(data []byte) { if p == nil || p.conn == nil { panic("send: socket is not connected") } if _, err := p.rw.Write(data); err != nil { panic(fmt.Errorf("send write: %w", err)) } if err := p.rw.Flush(); err != nil { panic(fmt.Errorf("send flush: %w", err)) } } func (p *Pwn) sendline(data []byte) { line := append(data, '\n') p.send(line) } func (p *Pwn) recv(bufsize int, timeoutSec ...float64) []byte { if p == nil || p.conn == nil { panic("recv: socket is not connected") } if bufsize <= 0 { bufsize = 4096 } // 无超时参数则阻塞(清除读超时);否则按给定超时设置 if len(timeoutSec) == 0 { if err := p.conn.SetReadDeadline(time.Time{}); err != nil { panic(err) } } else { deadline := time.Now().Add(time.Duration(timeoutSec[0]*1000) * time.Millisecond) if err := p.conn.SetReadDeadline(deadline); err != nil { panic(err) } } buf := make([]byte, bufsize) n, err := p.rw.Read(buf) if ne, ok := err.(net.Error); ok && ne.Timeout() { //panic("recv: timeout") return buf[:n] } if err != nil { panic(fmt.Errorf("recv: %w", err)) } return buf[:n] } func (p *Pwn) recvuntil(delims []byte, timeoutSec ...float64) []byte { if p == nil || p.conn == nil { panic("recvuntil: socket is not connected") } if len(delims) == 0 { panic("recvuntil: empty delimiter") } var out bytes.Buffer // 单字节逐步读取,仿照 Python 版行为 // 无超时参数则无限等待(清除读超时);否则设置超时 if len(timeoutSec) == 0 { if err := p.conn.SetReadDeadline(time.Time{}); err != nil { panic(err) } } else { deadline := time.Now().Add(time.Duration(timeoutSec[0]*1000) * time.Millisecond) if err := p.conn.SetReadDeadline(deadline); err != nil { panic(err) } } for { b, err := p.rw.ReadByte() if ne, ok := err.(net.Error); ok && ne.Timeout() { //panic("recvuntil: timeout") return out.Bytes() } if err != nil { panic(fmt.Errorf("recvuntil: %w", err)) } out.WriteByte(b) if bytes.Contains(out.Bytes(), delims) { break } } return out.Bytes() } func (p *Pwn) interactive() { if p == nil || p.conn == nil { panic("interactive: socket is not connected") } p.log("info", "Switching to interactive mode.") if runtime.GOOS == "windows" { p.interactiveWindows() } else { p.interactivePosix() } } func (p *Pwn) interactivePosix() { // 简化版:使用两个 goroutine 分别复制 stdin->conn 和 conn->stdout stop := make(chan struct{}) go func() { defer close(stop) if _, err := io.Copy(os.Stdout, p.conn); err != nil && !errors.Is(err, io.EOF) { panic(err) } }() go func() { if _, err := io.Copy(p.conn, os.Stdin); err != nil && !errors.Is(err, io.EOF) { panic(err) } // 结束时关闭写端以通知远端 if err := p.conn.SetWriteDeadline(time.Now()); err != nil { panic(err) } }() // 等待用户 Ctrl+C 或连接关闭 <-stop p.close() } func (p *Pwn) interactiveWindows() { // Windows 下用超时 + goroutine 模拟 stop := make(chan struct{}) go func() { defer close(stop) reader := bufio.NewReader(p.conn) for { if err := p.conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { panic(err) } buf := make([]byte, 4096) n, err := reader.Read(buf) if ne, ok := err.(net.Error); ok && ne.Timeout() { continue } if n > 0 { _, _ = os.Stdout.Write(buf[:n]) } if err != nil { panic(err) } } }() go func() { scanner := bufio.NewScanner(os.Stdin) for scanner.Scan() { line := scanner.Bytes() p.send(append(append([]byte{}, line...), '\n')) } if err := scanner.Err(); err != nil { panic(err) } }() <-stop p.close() } func (p *Pwn) close() { if p == nil { return } p.onceClose.Do(func() { if p.conn != nil { if err := p.conn.Close(); err != nil { panic(err) } p.conn = nil } p.log("info", "Connection closed.") }) } // ============================= // // Main // // ============================= // func main() { fmt.Println("--- Testing Endianness Packing ---") val := uint32(0x11223344) lePacked := p32(val) bePacked := p32(val, "big") fmt.Printf("Value 0x%x packed as little-endian: %v (Hex: %x)\n", val, lePacked, lePacked) fmt.Printf("Value 0x%x packed as big-endian: %v (Hex: %x)\n", val, bePacked, bePacked) fmt.Printf("%v\n", b("abc")) fmt.Printf("%v\n", cat(b("中文"), b("def"), p32(123, "big"), rep(p16(0x4241), 12), fromhex("01024142434445464748"))) fmt.Println(strings.Repeat("-", 34)) // 这里给出一个尝试连接本地 4444 的示例。 // 可配合 `nc -lnvp 4444` 测试(Windows 用 ncat 或 busybox nc)。 p := remote("localhost", 4444) p.send(cat(b("中文"), b("def"), p32(123, "big"), rep(p16(0x4241), 12), fromhex("01024142434445464748"))) p.send(b("\n")) welcome := p.recvuntil([]byte("\n"), 2.0) if len(welcome) > 0 { fmt.Printf("Received from server: %s\n", string(welcome)) } p.sendline(b("Hello from minipwn!")) fmt.Println("Initial message sent!") p.interactive() } ``` # 效果  # 其他说明 ## 打包了go1.25.1环境 cmd_go1.25.1.bat ``` @echo off set "GOROOT=%~dp0\env\go1.25.1" set "GOPATH=%~dp0\env\gopath1.25.1" set path=%GOROOT%\bin;%GOPATH%\bin;%~dp0\env;%PATH% cmd ``` 网盘分享 ``` 通过网盘分享的文件:gominipwn_v1.0.0.7z 链接: https://pan.baidu.com/s/1B7QxQr04E2E6WeBd_INH-Q?pwd=rykk 提取码: rykk ``` ## 可能有用的信息 ``` go env -w GO111MODULE=on go env -w GOPROXY=https://goproxy.cn,direct ``` 如果在Win11上执行go run xx.go时巨卡,可以尝试通过任务管理器关闭 PCManager Service Store服务。 ## 相关项目 python版本的minipwn [https://bbs.kanxue.com/thread-287571.htm](https://bbs.kanxue.com/thread-287571.htm) pyoneGUI,绿色版python,带完整pwntools [https://bbs.kanxue.com/thread-280053.htm](https://bbs.kanxue.com/thread-280053.htm)
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
#开源分享
#开发技巧
#工具脚本
收藏
・
0
点赞
・
1
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
wx_晨梦
你的帖子非常有用,感谢分享!
2026-7-16 10:57
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
0
)
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
Jtian
1
35
发帖
99
回帖
105
RANK
关注
私信
他的文章
[原创]记一次有趣的木马样本恢复之旅_使用已知明文攻击恢复样本文件
1681
[原创]一种通用的将Linux命令进行MCP封装的方法
1407
[原创]一个GDB MCP服务
2613
[原创]gominipwn
1296
[原创]fastmcp服务端通信分析
1478
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部