找回密码
 立即注册
首页 业界区 安全 Go红队开发—格式导出

Go红队开发—格式导出

穆望 2025-6-1 21:13:23
目录

  • 输出功能

    • CSV输出

      • CSV 转 结构体
      • 结构体 转 CSV
      • 端口扫描结果使用CSV格式导出

    • HTML输出
    • Sqlite输出

      • nmap扫描

    • JSON

      • map转json
      • 结构体转json
      • json写入文件
      • json编解码
      • json转结构体
      • json转map
      • json转string
      • 练习:nmap扫描结果导出json格式



输出功能

在我们使用安全工具的时候基本都会有一个输出功能,同样也很重要,所以下面介绍csv、json、html、sqlite的输出格式。
CSV输出
  1. 下载包:go get -u github.com/gocarina/gocsv
复制代码
使用之前先明确我们要csv格式干什么:

  • 首先一些数据可能就是存在csv文件里面,需要我们提取出来的话就需要另外写函数,但是现在有现成的包使用就很方便了
  • 其次我们使用一些安全工具的时候经常会有导出格式为csv格式的,所以在开发过程中也是一个很重要的需求,使用Gocsv包会很方便
    同理我们往后的其他格式也一样的需求。
CSV 转 结构体

test.csv文件内容为:
1.png

1.在CSV转结构体的时候,我们需要构造一个结构体,用来接收CSV文件中的表头
  1. type Person struct {
  2.     Id   string `csv:"id"`
  3.     Name string `csv:"name"`
  4.     Age  int    `csv:"age"`
  5. }
复制代码
2.解析csv文件
  1. // 解析CSV文件
  2. func anlyzeCSV() {
  3.     file, err := os.OpenFile(
  4.         "test.csv",
  5.         os.O_RDWR|os.O_CREATE,
  6.         0666,
  7.     )
  8.     defer file.Close()
  9.     if err != nil {
  10.         fmt.Println("打开文件失败:", err)
  11.     }
  12.   
  13.     person := []*Person{}
  14.     if err := gocsv.UnmarshalFile(file, &person); err != nil { //UnmarshalFile将文件解析为结构体
  15.         fmt.Println("解析文件失败:", err)
  16.     }
  17.     fmt.Println("id,name,age")
  18.     for _, p := range person {
  19.         fmt.Println(p.Id, p.Name, p.Age)
  20.     }
  21. }
复制代码
结构体 转 CSV
  1. // 写入CSV文件
  2. func writeCSV() {
  3.     file, err := os.OpenFile("test.csv", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
  4.     if err != nil {
  5.         fmt.Println("打开文件失败:", err)
  6.     }
  7.     defer file.Close()
  8.     person := []*Person{}
  9.     person = append(person, &Person{
  10.         Id:   "1",
  11.         Name: "李四",
  12.         Age:  20,
  13.     })
  14.     err = gocsv.MarshalFile(&person, file) //MarshalFile将数据写入文件
  15.     if err != nil {
  16.         fmt.Println("写入文件失败:", err)
  17.     }
  18. }
复制代码
端口扫描结果使用CSV格式导出

结合之前的端口扫描练习,将结果通过所学的知识CSV格式输出
这里我对之前的练习进行了一个改造,就是让输出美观一点,同时修改了传参与返回值,目的都是为了拿到扫描完成的端口结果。
为了写进csv还创建了一个结构体。
函数中大部分代码其实都是格式的转换,主要功能其实学会了上面基本都能做了。
所以这里我在放代码前说一下我遇到的问题:

  • csv的表头要修改的话是比较困难,我没有找到一个比较好的办法,就是在写入csv的代码过程中,修改csv表头,我的解决办法是通过开一个新的结构体,通过老结构体的数据传递到新的结构体中就能够修改csv头写进文件里了(这里有大佬知道解决办法可以告诉我一下)
  • 时间格式化有问题,时间格式一定只能用他给出的几种时间:- "2006-01-02 15:04:05":表示 年-月-日 时:分:秒 格式,如果你修改一下2006年改为2002年都是会格式化出错,这一点尝试了几回发现原来是格式时间数字也固定的表达的。
  • 你要写入的结构体的变量名首个字母要大写,一定要大写,否则他会报错,可能这也是一种规范吧,反正不大写就会报错。  最后的那个示例代码你可以尝试把HostPort结构体中的ScanTime修改首字母小写scanTime,很好的验证了小写的时候出现的错误,当然我运行的时候没有报错,但是他实际上是他没有吧你的时间写进csv中,也代码出错了,可以观察验证一下确实不能小写只能首字母大写。
  • 自定义格式实现MarshalCSV接口后,在写入的时候会自动调用该函数,你可以在该函数进行一些初始化或者格式化动作等等。
这补充一下时间格式化的代码:
  1. // 格式化时间time.Time类型
  2. func timeFormat(t time.Time) string {
  3.     return t.Format("2006年1月2日") //转为string类型
  4. }
  5. // Parse将string类型转为time.Time类型
  6. func timeParse(t string) time.Time {
  7.     tm, _ := time.Parse("2006-01-02 15:04:05", t)
  8.     return tm
  9. }
复制代码
代码示例:(成功将扫描结果存到csv中保存)
2.png

[code]// 稍微改一下代码,return一个port回来,然后输出到csv中func start_WaitGroup_scan_port(host string) ([]int, time.Time) {    var (        wg      sync.WaitGroup        ch      = make(chan int, 1024) // 增加缓冲区,减少阻塞        count   int        workers = 100 // 控制并发数    )      var scanPort = func(hostname string, port int) {        defer wg.Done()        address := fmt.Sprintf("%s:%d", hostname, port)        conn, err := net.DialTimeout("tcp", address, 2*time.Second)        if err == nil {            conn.Close()            ch
您需要登录后才可以回帖 登录 | 立即注册