做网站需要具备什么语言,网站更新方案,国内永久免费crm听说,品牌网站建设968手写HTTP抓包工具——可视化界面 项目描述语言golang可视化fynev2功能代理抓包、重发、记录 目录 1. 示例1.1 主界面1.2 开启反向代理1.3 抓包1.4 历史记录1.5 重发 2. 核心代码2.1 GUI2.1 抓包 3. 结语3.1 传送门 1. 示例
1.1 主界面 1.2 开启反向代理 1.3 抓包 1.4 历史记录… 手写HTTP抓包工具——可视化界面 项目描述语言golang可视化fynev2功能代理抓包、重发、记录 目录 1. 示例1.1 主界面1.2 开启反向代理1.3 抓包1.4 历史记录1.5 重发 2. 核心代码2.1 GUI2.1 抓包 3. 结语3.1 传送门 1. 示例
1.1 主界面 1.2 开启反向代理 1.3 抓包 1.4 历史记录 1.5 重发 2. 核心代码
2.1 GUI
func (cf *Config) CreateUi() {myApp : app.New()mainWin : myApp.NewWindow(Request Handling Tool v1.0)// 创建数据绑定对象cf.MainWin mainWin// 创建可以多行输入的 Entry 并绑定数据requestEntry : widget.NewEntryWithData(types.RequestData)requestEntry.MultiLine truerequestEntry.Wrapping fyne.TextWrapBreakresponseEntry : widget.NewEntryWithData(types.ResponseData)responseEntry.MultiLine trueresponseEntry.Wrapping fyne.TextWrapBreakErrEntry : widget.NewEntryWithData(types.ErrData)ErrEntry.MultiLine trueErrEntry.Wrapping fyne.TextWrapBreakhisreq1Entry : widget.NewEntryWithData(types.History_RequestD)hisreq1Entry.MultiLine truehisreq1Entry.Wrapping fyne.TextWrapBreakhisres2Entry : widget.NewEntryWithData(types.History_ResponseD)hisres2Entry.MultiLine truehisres2Entry.Wrapping fyne.TextWrapBreakrepeat_req1Entry : widget.NewEntryWithData(types.Repeat_RequestD)repeat_req1Entry.MultiLine truerepeat_req1Entry.Wrapping fyne.TextWrapBreakrepeat_res2Entry : widget.NewEntryWithData(types.Repeat_ResponseD)repeat_res2Entry.MultiLine truerepeat_res2Entry.Wrapping fyne.TextWrapBreaktargetAddrEntry : widget.NewEntryWithData(types.TargetAD)types.TargetAD.Set(127.0.0.1:3443)serverAddrEntry : widget.NewEntryWithData(types.ServerAD)types.ServerAD.Set(0.0.0.0:8089)targetPMEntry : widget.NewEntryWithData(types.TargetPM)types.TargetPM.Set(https)targetAddrLabel : widget.NewLabel(TargetAddr:)serverAddrLabel : widget.NewLabel(ServerAddr:)targetPMLabel : widget.NewLabel(TargetPM:)// 设置请求和响应 Entry 控件铺满父容器check1 : widget.NewCheckWithData(AutoSend, types.AutoSData)check1.SetChecked(true)check_history : widget.NewCheckWithData(HistoryOK, types.HistoryOK)check_history.SetChecked(true)sendButton : widget.NewButton(Send, func() {cf.GUI_Send()})send2Button : widget.NewButton(SendRAW, func() {cf.GUI_Send_repeat()})discardButton : widget.NewButton(Discard, func() {cf.GUI_Discard()})nextButton : widget.NewButton(Next, func() {cf.GUI_Next()})sRepeatButton : widget.NewButton(Repeat, func() {cf.GUI_sRepeat()})clearButton : widget.NewButton(ClearHistory, func() {cf.GUI_Clear()})_history_dir_Button : widget.NewButton(ClearHistoryDirFile, func() {cf.GUI_history_dir_Button()})nextButton.Disable()sendButton.Disable()discardButton.Disable()cf.Sendbt sendButtoncf.Nextbt nextButtoncf.Discardbt discardButtonOKconfig : widget.NewButton(Save, func() {cf.GUI_Save_config()})OpenProxyconfig : widget.NewButton(OpenProxy, func() {cf.GUI_OpenProxyconfig()})CloseProxyconfig : widget.NewButton(CloseProxy, func() {cf.GUI_CloseProxyconfig()})CloseProxyconfig.Disable()OKconfig.Disable()cf.OpenProxybt OpenProxyconfigcf.CloseProxybt CloseProxyconfigcf.Savebt OKconfig// 创建 Grid 布局grid_capture : container.NewGridWithColumns(3,container.NewStack(requestEntry),container.NewStack(responseEntry),container.NewVBox(check1, sendButton, discardButton, nextButton, sRepeatButton),)grid_config : container.NewGridWithColumns(3,container.NewVBox(container.NewVBox(targetAddrLabel, targetAddrEntry),container.NewVBox(serverAddrLabel, serverAddrEntry),container.NewVBox(targetPMLabel, targetPMEntry)),container.NewVBox(check_history, OKconfig, OpenProxyconfig, CloseProxyconfig, clearButton, _history_dir_Button),container.NewStack(ErrEntry),)table : widget.NewTable(// 返回表格的行数和列数func() (int, int) {return len(types.History_Data), len(types.History_Data[0]) // 第三列为按钮},// 返回每个单元格的 CanvasObjectfunc() fyne.CanvasObject {entry : widget.NewEntry()ccButton : widget.NewButton(Select, nil)repeatButton : widget.NewButton(Repeat, nil)buttonContainer : container.NewGridWithColumns(2, ccButton, repeatButton)en1 : container.NewVBox(entry, buttonContainer)return en1},// 更新每个单元格的内容func(id widget.TableCellID, obj fyne.CanvasObject) {en1 : obj.(*fyne.Container)entry : en1.Objects[0].(*widget.Entry)buttonContainer : en1.Objects[1].(*fyne.Container)ccButton : buttonContainer.Objects[0].(*widget.Button)repeatButton : buttonContainer.Objects[1].(*widget.Button)if id.Col 1 { // 前两列显示数据entry.Show() // 显示 EntrybuttonContainer.Hide() // 隐藏按钮容器entry.SetText(types.History_Data[id.Row][id.Col])} else if id.Col 1 { // 第三列显示按钮entry.Hide() // 隐藏 EntrybuttonContainer.Show() // 显示按钮容器ccButton.OnTapped func(row int) func() {return func() {cf.GUI_Table_bt(row)}}(id.Row)repeatButton.OnTapped func(row int) func() {return func() {cf.GUI_Table_Repeat_bt(row)}}(id.Row)}})cf.Table_history table// 创建带有垂直滚动条的容器tableContainer : container.NewVScroll(table)// 创建histroy布局grid_history : container.NewGridWithRows(2,container.NewStack(tableContainer),container.NewGridWithColumns(2,container.NewStack(hisreq1Entry),container.NewStack(hisres2Entry),),)grid_repeat : container.NewGridWithColumns(3,container.NewStack(repeat_req1Entry),container.NewStack(repeat_res2Entry),container.NewVBox(send2Button),)tab2 : container.NewTabItem(capture, grid_capture)tab1 : container.NewTabItem(config, grid_config)tab3 : container.NewTabItem(history, grid_history)tab4 : container.NewTabItem(repeat, grid_repeat)tabContainer : container.NewAppTabs(tab1, tab2, tab3, tab4)tabContainer.SetTabLocation(container.TabLocationTop)// 布局// 拦截关闭事件mainWin.SetCloseIntercept(func() {mainWin.Hide() // 隐藏窗口})mainWin.SetContent(tabContainer)// 添加窗口大小变化监听器mainWin.Resize(fyne.NewSize(800, 600))mainWin.ShowAndRun()}2.1 抓包
func Run(conf *Config) {for {select {case -conf.RunTH:types.ErrMainData fmt.Sprintln([] Close-Proxy-OK)// fmt.Println(1)returndefault:// fmt.Println(0)}if conf.ServerAddr || conf.TargetAddr || conf.TargetPM || conf.Nextbt nil {time.Sleep(2 * time.Second)types.ErrMainData fmt.Sprintln([-] Parameters not saved or initialization not completed)} else {break}}Init(conf)// 创建 HTTP 处理函数的中间件middleware : func(http.Handler) http.Handler {return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {types.CHT - truehisD1 : []string{}hisD2 : []string{}defer func() { -types.CHT }()// 获取原始请求的字符串表示dump, err : httputil.DumpRequest(r, true)utils.HandleErr(utils.GCFN(), err)dump, err conf.HostFix(dump)utils.HandleErr(utils.GCFN(), err)if ok, err : types.HistoryOK.Get(); ok {utils.HandleErr(utils.GCFN(), err)hisD1 append(hisD1, string(dump))hisD2 append(hisD2, fmt.Sprintf(%v %v, r.Method, r.URL.String()))}// // 打印原始请求字符串// fmt.Printf(\033[32m%s\033[0m\n, dump)if ok, err : types.AutoSData.Get(); !ok {utils.HandleErr(utils.GCFN(), err)err types.RequestData.Set(string(dump))utils.HandleErr(utils.GCFN(), err)conf.Cf_Enable()CC:for {select {case -types.SendCH:rdata, err : types.RequestData.Get()utils.HandleErr(utils.GCFN(), err)// 将 rdata 解析成 *http.Request 对象r, err http.ReadRequest(bufio.NewReader(bytes.NewBufferString(rdata)))utils.HandleErr(utils.GCFN(), err)break CCcase -types.DiscardCH:returndefault:}time.Sleep(100 * time.Millisecond)}} else {err types.RequestData.Set()utils.HandleErr(utils.GCFN(), err)err types.ResponseData.Set()utils.HandleErr(utils.GCFN(), err)}recorder : httptest.NewRecorder()recorder.Header().Add(Waf, Coraza-v3)// 使用反向代理转发请求conf.Proxy.ServeHTTP(recorder, r)// 创建 http.Response 对象response : recorder.Result()// 使用 httputil.DumpResponse 来获取完整响应包res1, err : httputil.DumpResponse(response, true)utils.HandleErr(utils.GCFN(), err)if ok, _ : types.HistoryOK.Get(); ok {hisD1 append(hisD1, string(res1))ff : utils.Wrtie_history_response(hisD1, conf.TargetAddr)hisD2 append(hisD2, ff)types.History_Data append(types.History_Data, hisD2)}if ok, err : types.AutoSData.Get(); !ok {utils.HandleErr(utils.GCFN(), err)err types.ResponseData.Set(string(res1))utils.HandleErr(utils.GCFN(), err)}conf.TxProcessResponse(recorder, w, r)if ok, err : types.AutoSData.Get(); !ok {utils.HandleErr(utils.GCFN(), err)BB:for {select {case -types.NextCH:err types.RequestData.Set()utils.HandleErr(utils.GCFN(), err)err types.ResponseData.Set()utils.HandleErr(utils.GCFN(), err)break BBdefault:}time.Sleep(100 * time.Millisecond)}} else {err types.RequestData.Set()utils.HandleErr(utils.GCFN(), err)err types.ResponseData.Set()utils.HandleErr(utils.GCFN(), err)conf.Cf_Disable()}})}server : http.Server{Addr: conf.ServerAddr,Handler: middleware(http.DefaultServeMux), // 使用中间件包裹默认的 ServeMux}go func() {types.ErrMainData fmt.Sprintf([] Starting server at %v\n, conf.ServerAddr)if err : server.ListenAndServe(); err ! nil err ! http.ErrServerClosed {utils.HandleErr(utils.GCFN(), err)}}()AA:for {select {case -conf.RunTH:break AAdefault:time.Sleep(500 * time.Millisecond)}}// 通过 context 实现优雅关闭ctx, cancel : context.WithTimeout(context.Background(), 10*time.Second)defer cancel()if err : server.Shutdown(ctx); err ! nil {types.ErrMainData fmt.Sprintf([-] Server shutdown failed:%v\n, err)if err : server.Close(); err ! nil {types.ErrMainData fmt.Sprintf([!] Server Close failed:%v\n, err)} else {types.ErrMainData fmt.Sprintln([] Close-Proxy-OK)}} else {types.ErrMainData fmt.Sprintln([] Close-Proxy-OK)}}3. 结语
3.1 传送门
MiniBurp.exe(仅供学习)