master
兔子 10 months ago
parent e5db22aa52
commit 88a3fdf2bf

@ -36,10 +36,18 @@ var Cmd = &cobra.Command{
starlog.Errorln("unsupport server type:", serverType) starlog.Errorln("unsupport server type:", serverType)
os.Exit(1) os.Exit(1)
} }
localdns := GetDNSServers()
for _, v := range localdns {
fmt.Println("本地DNS:", v.String())
}
if dnsServer == "" { if dnsServer == "" {
switch itype { switch itype {
case 0, 1: case 0, 1:
dnsServer = "223.5.5.5:53" if len(localdns) != 0 {
dnsServer = localdns[0].String()
} else {
dnsServer = "223.5.5.5:53"
}
case 2: case 2:
dnsServer = "dns.b612.me:853" dnsServer = "dns.b612.me:853"
case 3: case 3:
@ -54,7 +62,7 @@ var Cmd = &cobra.Command{
return return
} }
queryType = strings.ToUpper(queryType) queryType = strings.ToUpper(queryType)
fmt.Println("dns服务器:", dnsServer) fmt.Println("查询DNS:", dnsServer)
fmt.Println("查询类型:", queryType) fmt.Println("查询类型:", queryType)
for _, target := range args { for _, target := range args {
data, err := QueryDns(target, queryType, itype, dnsServer) data, err := QueryDns(target, queryType, itype, dnsServer)
@ -64,9 +72,7 @@ var Cmd = &cobra.Command{
} }
fmt.Println("\n") fmt.Println("\n")
fmt.Println("Query:", target) fmt.Println("Query:", target)
for _, v := range data { fmt.Println(data.Str)
fmt.Printf("%s\tRTT=%v\n", v.Res, v.Rtt)
}
} }
}, },
} }

@ -3,6 +3,7 @@ package dns
import ( import (
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt"
"github.com/miekg/dns" "github.com/miekg/dns"
"io" "io"
"net" "net"
@ -11,17 +12,15 @@ import (
) )
type Result struct { type Result struct {
Res string Res *dns.Msg
Type string Str string
Alias string
Rtt int64
} }
type DnsClient interface { type DnsClient interface {
Exchange(req *dns.Msg, address string) (r *dns.Msg, rtt time.Duration, err error) Exchange(req *dns.Msg, address string) (r *dns.Msg, rtt time.Duration, err error)
} }
func QueryDns(domain string, queryType string, serverType int, dnsServer string) ([]Result, error) { func QueryDns(domain string, queryType string, serverType int, dnsServer string) (Result, error) {
var c DnsClient var c DnsClient
c = new(dns.Client) c = new(dns.Client)
m := new(dns.Msg) m := new(dns.Msg)
@ -41,7 +40,6 @@ func QueryDns(domain string, queryType string, serverType int, dnsServer string)
case 3: case 3:
c = NewDoHClient(WithTimeout(10 * time.Second)) c = NewDoHClient(WithTimeout(10 * time.Second))
} }
var res []Result
switch queryType { switch queryType {
case "A": case "A":
m.SetQuestion(dns.Fqdn(domain), dns.TypeA) m.SetQuestion(dns.Fqdn(domain), dns.TypeA)
@ -90,17 +88,16 @@ func QueryDns(domain string, queryType string, serverType int, dnsServer string)
case "URI": case "URI":
m.SetQuestion(dns.Fqdn(domain), dns.TypeURI) m.SetQuestion(dns.Fqdn(domain), dns.TypeURI)
default: default:
return nil, errors.New("not support query type,only support A,CNAME,MX,NS,SOA,SRV,AAAA,PTR,ANY,CAA,TLSA,DS,DNSKEY,NSEC,NSEC3,NSEC3PARAM,RRSIG,SPF,SSHFP,TKEY,TSIG,URI") return Result{}, errors.New("not support query type,only support A,CNAME,MX,NS,SOA,SRV,AAAA,PTR,ANY,CAA,TLSA,DS,DNSKEY,NSEC,NSEC3,NSEC3PARAM,RRSIG,SPF,SSHFP,TKEY,TSIG,URI")
} }
r, rtt, err := c.Exchange(m, dnsServer) r, rtt, err := c.Exchange(m, dnsServer)
if err != nil { if err != nil {
return nil, err return Result{}, err
} }
for _, ans := range r.Answer { return Result{
res = append(res, Result{Res: ans.String(), Type: queryType, Rtt: rtt.Milliseconds()}) Res: r,
} Str: r.String() + "\n" + ";; RTT:\n" + fmt.Sprintf("%v milliseconds", rtt.Milliseconds()),
return res, nil }, nil
} }
const DoHMediaType = "application/dns-message" const DoHMediaType = "application/dns-message"

@ -10,8 +10,6 @@ func TestDefaultDns(t *testing.T) {
if e != nil { if e != nil {
t.Error(e) t.Error(e)
} }
for _, v := range p { fmt.Println(p)
fmt.Printf("%+v\n", v)
}
} }

@ -0,0 +1,51 @@
//go:build !js && !windows
package dns
import (
"net/netip"
"os"
"strings"
)
func GetDNSServers() (nameservers []netip.AddrPort) {
const filename = "/etc/resolv.conf"
return getLocalNameservers(filename)
}
func getLocalNameservers(filename string) (nameservers []netip.AddrPort) {
const defaultNameserverPort = 53
defaultLocalNameservers := []netip.AddrPort{
netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), defaultNameserverPort),
netip.AddrPortFrom(netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 1}), defaultNameserverPort),
}
data, err := os.ReadFile(filename)
if err != nil {
return defaultLocalNameservers
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
if line == "" {
continue
}
fields := strings.Fields(line)
if len(fields) == 0 || fields[0] != "nameserver" {
continue
}
for _, field := range fields[1:] {
ip, err := netip.ParseAddr(field)
if err != nil {
continue
}
nameservers = append(nameservers,
netip.AddrPortFrom(ip, defaultNameserverPort))
}
}
if len(nameservers) == 0 {
return defaultLocalNameservers
}
return nameservers
}

@ -0,0 +1,275 @@
package dns
import (
"errors"
"fmt"
"net/netip"
"syscall"
"unsafe"
)
func GetDNSServers() (nameservers []netip.AddrPort) {
const defaultDNSPort = 53
defaultLocalNameservers := []netip.AddrPort{
netip.AddrPortFrom(netip.AddrFrom4([4]byte{127, 0, 0, 1}), defaultDNSPort),
netip.AddrPortFrom(netip.AddrFrom16([16]byte{0, 0, 0, 0, 0, 0, 0, 1}), defaultDNSPort),
}
adapterAddresses, err := getAdapterAddresses()
if err != nil {
return defaultLocalNameservers
}
for _, adapterAddress := range adapterAddresses {
const statusUp = 0x01
if adapterAddress.operStatus != statusUp {
continue
}
if adapterAddress.firstGatewayAddress == nil {
// Only search DNS servers for adapters having a gateway
continue
}
dnsServerAddress := adapterAddress.firstDnsServerAddress
for dnsServerAddress != nil {
ip, ok := sockAddressToIP(dnsServerAddress.address.rawSockAddrAny)
if !ok || ipIsSiteLocalAnycast(ip) {
// fec0/10 IPv6 addresses are site local anycast DNS
// addresses Microsoft sets by default if no other
// IPv6 DNS address is set. Site local anycast is
// deprecated since 2004, see
// https://datatracker.ietf.org/doc/html/rfc3879
dnsServerAddress = dnsServerAddress.next
continue
}
nameserver := netip.AddrPortFrom(ip, defaultDNSPort)
nameservers = append(nameservers, nameserver)
dnsServerAddress = dnsServerAddress.next
}
}
if len(nameservers) == 0 {
return defaultLocalNameservers
}
return nameservers
}
var (
errBufferOverflowUnexpected = errors.New("unexpected buffer overflowed because buffer was large enough")
)
func getAdapterAddresses() (
adapterAddresses []*ipAdapterAddresses, err error) {
var buffer []byte
const initialBufferLength uint32 = 15000
sizeVar := initialBufferLength
for {
buffer = make([]byte, sizeVar)
err := runProcGetAdaptersAddresses(
(*ipAdapterAddresses)(unsafe.Pointer(&buffer[0])),
&sizeVar)
if err != nil {
if err.(syscall.Errno) == syscall.ERROR_BUFFER_OVERFLOW {
if sizeVar <= uint32(len(buffer)) {
return nil, fmt.Errorf("%w: buffer size variable %d is "+
"equal or lower to the buffer current length %d",
errBufferOverflowUnexpected, sizeVar, len(buffer))
}
continue
}
return nil, fmt.Errorf("getting adapters addresses: %w", err)
}
noDataFound := sizeVar == 0
if noDataFound {
return nil, nil
}
break
}
adapterAddress := (*ipAdapterAddresses)(unsafe.Pointer(&buffer[0]))
for adapterAddress != nil {
adapterAddresses = append(adapterAddresses, adapterAddress)
adapterAddress = adapterAddress.next
}
return adapterAddresses, nil
}
var (
procGetAdaptersAddresses = syscall.NewLazyDLL("iphlpapi.dll").
NewProc("GetAdaptersAddresses")
)
func runProcGetAdaptersAddresses(adapterAddresses *ipAdapterAddresses,
sizePointer *uint32) (errcode error) {
const family = syscall.AF_UNSPEC
const GAA_FLAG_SKIP_UNICAST = 0x0001
const GAA_FLAG_SKIP_ANYCAST = 0x0002
const GAA_FLAG_SKIP_MULTICAST = 0x0004
const GAA_FLAG_SKIP_FRIENDLY_NAME = 0x0020
const GAA_FLAG_INCLUDE_GATEWAYS = 0x0080
const flags = GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_FRIENDLY_NAME |
GAA_FLAG_INCLUDE_GATEWAYS
const reserved = 0
// See https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getadaptersaddresses
r1, _, err := syscall.SyscallN(procGetAdaptersAddresses.Addr(),
uintptr(family), uintptr(flags), uintptr(reserved),
uintptr(unsafe.Pointer(adapterAddresses)),
uintptr(unsafe.Pointer(sizePointer)))
switch {
case err != 0:
return err
case r1 != 0:
return syscall.Errno(r1)
default:
return nil
}
}
func sockAddressToIP(rawSockAddress *syscall.RawSockaddrAny) (ip netip.Addr, ok bool) {
if rawSockAddress == nil {
return netip.Addr{}, false
}
sockAddress, err := rawSockAddress.Sockaddr()
if err != nil {
return netip.Addr{}, false
}
switch sockAddress := sockAddress.(type) {
case *syscall.SockaddrInet4:
return netip.AddrFrom4([4]byte{
sockAddress.Addr[0], sockAddress.Addr[1], sockAddress.Addr[2], sockAddress.Addr[3]}),
true
case *syscall.SockaddrInet6:
return netip.AddrFrom16([16]byte{
sockAddress.Addr[0], sockAddress.Addr[1], sockAddress.Addr[2], sockAddress.Addr[3],
sockAddress.Addr[4], sockAddress.Addr[5], sockAddress.Addr[6], sockAddress.Addr[7],
sockAddress.Addr[8], sockAddress.Addr[9], sockAddress.Addr[10], sockAddress.Addr[11],
sockAddress.Addr[12], sockAddress.Addr[13], sockAddress.Addr[14], sockAddress.Addr[15]}),
true
default:
return netip.Addr{}, false
}
}
func ipIsSiteLocalAnycast(ip netip.Addr) bool {
if !ip.Is6() {
return false
}
array := ip.As16()
return array[0] == 0xfe && array[1] == 0xc0
}
// See https://learn.microsoft.com/en-us/windows/win32/api/iptypes/ns-iptypes-ip_adapter_addresses_lh
type ipAdapterAddresses struct {
// The order of fields DOES matter since they are read
// raw from a bytes buffer. However, we are only interested
// in a few select fields, so unneeded fields are either
// named as "_" or removed if they are after the fields
// we are interested in.
_ uint32
_ uint32
next *ipAdapterAddresses
_ *byte
_ *ipAdapterUnicastAddress
_ *ipAdapterAnycastAddress
_ *ipAdapterMulticastAddress
firstDnsServerAddress *ipAdapterDnsServerAdapter
_ *uint16
_ *uint16
_ *uint16
_ [syscall.MAX_ADAPTER_ADDRESS_LENGTH]byte
_ uint32
_ uint32
_ uint32
_ uint32
operStatus uint32
_ uint32
_ [16]uint32
_ *ipAdapterPrefix
_ uint64
_ uint64
_ *ipAdapterWinsServerAddress
firstGatewayAddress *ipAdapterGatewayAddress
// Additional fields not needed here
}
type ipAdapterUnicastAddress struct {
// The order of fields DOES matter since they are read raw
// from a bytes buffer. However, we are not interested in
// the value of any field, so they are all named as "_".
_ uint32
_ uint32
_ *ipAdapterUnicastAddress
_ ipAdapterSocketAddress
_ int32
_ int32
_ int32
_ uint32
_ uint32
_ uint32
_ uint8
}
type ipAdapterAnycastAddress struct {
// The order of fields DOES matter since they are read raw
// from a bytes buffer. However, we are not interested in
// the value of any field, so they are all named as "_".
_ uint32
_ uint32
_ *ipAdapterAnycastAddress
_ ipAdapterSocketAddress
}
type ipAdapterMulticastAddress struct {
// The order of fields DOES matter since they are read raw
// from a bytes buffer. However, we are only interested in
// a few select fields, so unneeded fields are named as "_".
_ uint32
_ uint32
_ *ipAdapterMulticastAddress
_ ipAdapterSocketAddress
}
type ipAdapterDnsServerAdapter struct {
// The order of fields DOES matter since they are read raw
// from a bytes buffer. However, we are only interested in
// a few select fields, so unneeded fields are named as "_".
_ uint32
_ uint32
next *ipAdapterDnsServerAdapter
address ipAdapterSocketAddress
}
type ipAdapterPrefix struct {
_ uint32
_ uint32
_ *ipAdapterPrefix
_ ipAdapterSocketAddress
_ uint32
}
type ipAdapterWinsServerAddress struct {
_ uint32
_ uint32
_ *ipAdapterWinsServerAddress
_ ipAdapterSocketAddress
}
type ipAdapterGatewayAddress struct {
_ uint32
_ uint32
_ *ipAdapterGatewayAddress
_ ipAdapterSocketAddress
}
type ipAdapterSocketAddress struct {
rawSockAddrAny *syscall.RawSockaddrAny
}

@ -11,13 +11,18 @@ require (
b612.me/starssh v0.0.2 b612.me/starssh v0.0.2
b612.me/startext v0.0.0-20220314043758-22c6d5e5b1cd b612.me/startext v0.0.0-20220314043758-22c6d5e5b1cd
b612.me/wincmd v0.0.3 b612.me/wincmd v0.0.3
github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9
github.com/goftp/server v0.0.0-20200708154336-f64f7c2d8a42 github.com/goftp/server v0.0.0-20200708154336-f64f7c2d8a42
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/inconshreveable/mousetrap v1.1.0 github.com/inconshreveable/mousetrap v1.1.0
github.com/likexian/whois v1.15.1
github.com/miekg/dns v1.1.58 github.com/miekg/dns v1.1.58
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/spf13/cobra v1.8.0 github.com/spf13/cobra v1.8.0
github.com/things-go/go-socks5 v0.0.5
) )
require ( require (
@ -28,7 +33,6 @@ require (
github.com/kr/fs v0.1.0 // indirect github.com/kr/fs v0.1.0 // indirect
github.com/pkg/sftp v1.13.4 // indirect github.com/pkg/sftp v1.13.4 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.8.0 // indirect
golang.org/x/crypto v0.21.0 // indirect golang.org/x/crypto v0.21.0 // indirect
golang.org/x/image v0.6.0 // indirect golang.org/x/image v0.6.0 // indirect
golang.org/x/mod v0.14.0 // indirect golang.org/x/mod v0.14.0 // indirect

@ -24,7 +24,10 @@ b612.me/wincmd v0.0.3/go.mod h1:nWdNREHO6F+2PngEUcyYN3Eo7DzYEVa/fO6czd9d/fo=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5 h1:m62nsMU279qRD9PQSWD1l66kmkXzuYcnVJqL4XLeV2M=
github.com/elazarl/goproxy v0.0.0-20231117061959-7cc037d33fb5/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2 h1:dWB6v3RcOy03t/bUadywsbyrQwCqZeNIEX6M1OtSZOM=
github.com/elazarl/goproxy/ext v0.0.0-20190711103511-473e67f1d7d2/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 h1:cC0Hbb+18DJ4i6ybqDybvj4wdIDS4vnD0QEci98PgM8= github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9 h1:cC0Hbb+18DJ4i6ybqDybvj4wdIDS4vnD0QEci98PgM8=
github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss= github.com/goftp/file-driver v0.0.0-20180502053751-5d604a0fc0c9/go.mod h1:GpOj6zuVBG3Inr9qjEnuVTgBlk2lZ1S9DcoFiXWyKss=
github.com/goftp/server v0.0.0-20200708154336-f64f7c2d8a42 h1:JdOp2qR5PF4O75tzHeqrwnDDv8oHDptWyTbyYS4fD8E= github.com/goftp/server v0.0.0-20200708154336-f64f7c2d8a42 h1:JdOp2qR5PF4O75tzHeqrwnDDv8oHDptWyTbyYS4fD8E=
@ -39,6 +42,9 @@ github.com/jlaffaye/ftp v0.1.0 h1:DLGExl5nBoSFoNshAUHwXAezXwXBvFdx7/qwhucWNSE=
github.com/jlaffaye/ftp v0.1.0/go.mod h1:hhq4G4crv+nW2qXtNYcuzLeOudG92Ps37HEKeg2e3lE= github.com/jlaffaye/ftp v0.1.0/go.mod h1:hhq4G4crv+nW2qXtNYcuzLeOudG92Ps37HEKeg2e3lE=
github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/likexian/gokit v0.25.13 h1:p2Uw3+6fGG53CwdU2Dz0T6bOycdb2+bAFAa3ymwWVkM=
github.com/likexian/whois v1.15.1 h1:6vTMI8n9s1eJdmcO4R9h1x99aQWIZZX1CD3am68gApU=
github.com/likexian/whois v1.15.1/go.mod h1:/nxmQ6YXvLz+qTxC/QFtEJNAt0zLuRxJrKiWpBJX8X0=
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
@ -47,17 +53,17 @@ github.com/pkg/sftp v1.13.4 h1:Lb0RYJCmgUcBgZosfoi9Y9sbl6+LJgOIgk/2Y4YjMFg=
github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8= github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/things-go/go-socks5 v0.0.5 h1:qvKaGcBkfDrUL33SchHN93srAmYGzb4CxSM2DPYufe8=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/things-go/go-socks5 v0.0.5/go.mod h1:mtzInf8v5xmsBpHZVbIw2YQYhc4K0jRwzfsH64Uh0IQ=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=

@ -0,0 +1,43 @@
package httproxy
import (
"b612.me/starlog"
"github.com/elazarl/goproxy"
"github.com/elazarl/goproxy/ext/auth"
"github.com/spf13/cobra"
"net/http"
)
var username, password string
var listen string
func init() {
Cmd.Flags().StringVarP(&username, "username", "u", "", "用户名")
Cmd.Flags().StringVarP(&password, "password", "p", "", "密码")
Cmd.Flags().StringVarP(&listen, "listen", "l", ":8000", "监听地址")
}
var Cmd = &cobra.Command{
Use: "httproxy",
Short: "http代理",
Long: "http代理",
Run: func(cmd *cobra.Command, args []string) {
run()
},
}
func run() {
// Create a http server
p := goproxy.NewProxyHttpServer()
p.Verbose = true
starlog.Infof("start http proxy server on %s username %s password %s \n", listen, username, password)
if username != "" && password != "" {
auth.ProxyBasic(p, "B612 Http Proxy Need Password", func(user, pwd string) bool {
return user == username && pwd == password
})
}
err := http.ListenAndServe(listen, p)
if err != nil {
starlog.Errorln("http proxy server error:", err)
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -5,6 +5,7 @@ import (
"b612.me/starlog" "b612.me/starlog"
"b612.me/staros" "b612.me/staros"
"context" "context"
_ "embed"
"encoding/base64" "encoding/base64"
"errors" "errors"
"fmt" "fmt"
@ -43,6 +44,15 @@ type HttpServer struct {
HttpServerCfg HttpServerCfg
} }
//go:embed bootstrap.css
var bootStrap []byte
//go:embed jquery.js
var jquery []byte
//go:embed upload.html
var uploadPage []byte
var htmlTitle string = `<!DOCTYPE html> var htmlTitle string = `<!DOCTYPE html>
<html lang="zh_CN"> <html lang="zh_CN">
<head> <head>
@ -378,13 +388,19 @@ func (h *HttpServer) BasicAuth(log *starlog.StarLogger, w http.ResponseWriter, r
func (h *HttpServer) SetUpload(w http.ResponseWriter, r *http.Request, path string) bool { func (h *HttpServer) SetUpload(w http.ResponseWriter, r *http.Request, path string) bool {
if h.uploadFolder != "" { if h.uploadFolder != "" {
if r.URL.Query().Get("bootstrap") == "true" {
w.Header().Set("Content-Type", "text/css")
w.Write(bootStrap)
return true
}
if r.URL.Query().Get("jquery") == "true" {
w.Header().Set("Content-Type", "application/javascript")
w.Write(jquery)
return true
}
if len(r.URL.Query()["upload"]) != 0 { if len(r.URL.Query()["upload"]) != 0 {
w.Write([]byte(`<html><body><form id= "uploadForm" action= "/recv?upload=true" method= "post" enctype ="multipart/form-data"> w.Header().Set("Content-Type", "text/html")
<h1 >B612 File Upload Page </h1> w.Write(uploadPage)
<p > <input type ="file" name="victorique" /></p>
<input type ="submit" value="上传"/>
</form>
<h2>Copyright@b612.me </h2></body></html>`))
return true return true
} }
} }

@ -0,0 +1,185 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>B612 File Upload Page</title>
<link rel="stylesheet" href="/css?bootstrap=true">
<script src="/js?jquery=true"></script>
<style>
@media (max-width: 600px) {
.progress-bar, p {
width: 100%;
}
}
.file-upload {
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<div class="container">
<h1 class="text-center">B612 File Upload Page</h1>
<form id="uploadForm" action="/recv?upload=true" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="victorique">上传文件:</label>
<input type="file" class="form-control-file" id="victorique" name="victorique" multiple>
</div>
<button type="submit" class="btn btn-primary">上传</button>
<button type="button" id="clearButton" class="btn btn-secondary">清除</button>
<button type="button" id="cancelAllButton" class="btn btn-danger">取消所有上传</button>
</form>
<div id="progressContainer"></div>
</div>
<script>
var completedUploads = 0;
var anyUploadFailed = false;
var xhrs = []; // Array to hold all the XHR objects
$("#victorique").on("change", function(e){
document.getElementById('progressContainer').innerHTML = '';
var files = document.getElementById('victorique').files;
for (var i = 0; i < files.length; i++) {
createProgressBar(files[i]);
}
});
$("#clearButton").on("click", function(e){
document.getElementById('victorique').value = '';
document.getElementById('progressContainer').innerHTML = '';
});
$("#cancelAllButton").on("click", function(e){
for (var i = 0; i < xhrs.length; i++) {
xhrs[i].abort();
}
});
$("#uploadForm").on("submit", function(e){
e.preventDefault();
completedUploads = 0; // Reset the counter
anyUploadFailed = false; // Reset the flag
var files = document.getElementById('victorique').files;
var fileUploads = document.querySelectorAll('.file-upload');
for (var i = 0; i < files.length; i++) {
uploadFile(files[i], fileUploads[i]);
}
});
function createProgressBar(file) {
var progressContainer = document.getElementById('progressContainer');
var fileUpload = document.createElement('div');
fileUpload.className = 'file-upload';
progressContainer.appendChild(fileUpload);
var fileNameLabel = document.createElement('p');
fileNameLabel.innerHTML = file.name;
fileUpload.appendChild(fileNameLabel);
var progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
progressBar.setAttribute('role', 'progressbar');
progressBar.style.width = '0%';
progressBar.setAttribute('aria-valuenow', '0');
progressBar.setAttribute('aria-valuemin', '0');
progressBar.setAttribute('aria-valuemax', '100');
fileUpload.appendChild(progressBar);
var speedLabel = document.createElement('p');
var sizeLabel = document.createElement('p');
var cancelButton = document.createElement('button');
cancelButton.innerHTML = '取消上传';
cancelButton.className = 'btn btn-danger';
fileUpload.appendChild(speedLabel);
fileUpload.appendChild(sizeLabel);
fileUpload.appendChild(cancelButton);
// Save these elements as custom properties
fileUpload.progressBar = progressBar;
fileUpload.speedLabel = speedLabel;
fileUpload.sizeLabel = sizeLabel;
fileUpload.cancelButton = cancelButton;
return fileUpload;
}
function uploadFile(file, fileUpload) {
var formData = new FormData();
formData.append('victorique', file);
var start = Date.now();
var lastLoaded = 0;
var progressBar = fileUpload.progressBar;
var speedLabel = fileUpload.speedLabel;
var sizeLabel = fileUpload.sizeLabel;
var cancelButton = fileUpload.cancelButton;
var xhr = $.ajax({
xhr: function(){
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt){
if(evt.lengthComputable){
var percentComplete = ((evt.loaded / evt.total) * 100).toFixed(2);
var timeElapsed = (Date.now() - start) / 1000; // Time elapsed in seconds
var bytesLoaded = evt.loaded - lastLoaded;
lastLoaded = evt.loaded;
var speed = bytesLoaded / timeElapsed; // Speed in bytes/second
var formattedSpeed = formatSize(speed);
progressBar.style.width = percentComplete + '%';
progressBar.innerHTML = percentComplete + '%';
speedLabel.innerHTML = "上传速度: " + formattedSpeed + "/秒";
sizeLabel.innerHTML = "已上传: " + formatSize(evt.loaded) + " / " + formatSize(evt.total);
start = Date.now();
}
}, false);
return xhr;
},
url: '/recv?upload=true',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(response){
completedUploads++;
if (completedUploads === document.getElementById('victorique').files.length) {
if (anyUploadFailed) {
alert('一些文件上传失败!');
} else {
alert('所有文件上传成功!');
}
}
},
error: function(response){
anyUploadFailed = true;
completedUploads++;
if (completedUploads === document.getElementById('victorique').files.length) {
alert('一些文件上传失败!');
}
}
});
xhrs.push(xhr); // Add the XHR object to the array
// Add click event to the cancel button
cancelButton.onclick = function() {
xhr.abort();
};
}
function formatSize(size) {
var i = 0;
var units = ['字节', 'KB', 'MB', 'GB'];
while (size >= 1024) {
size /= 1024;
i++;
}
return size.toFixed(2) + ' ' + units[i];
}
</script>
<footer class="footer mt-auto py-3">
<div class="container text-center">
<span class="text-muted">Copyright@b612.me</span>
</div>
</footer>
</body>
</html>

@ -43,8 +43,8 @@ func init() {
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "keygen", Use: "keygen",
Short: "keygen", Short: "rsa与ecdsa密钥生成工具",
Long: "keygen", Long: "rsa与ecdsa密钥生成工具支持加密私钥生成证书",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
var err error var err error
if startdate != "" { if startdate != "" {

@ -14,6 +14,7 @@ import (
"b612.me/apps/b612/generate" "b612.me/apps/b612/generate"
"b612.me/apps/b612/hash" "b612.me/apps/b612/hash"
"b612.me/apps/b612/httpreverse" "b612.me/apps/b612/httpreverse"
"b612.me/apps/b612/httproxy"
"b612.me/apps/b612/httpserver" "b612.me/apps/b612/httpserver"
"b612.me/apps/b612/image" "b612.me/apps/b612/image"
"b612.me/apps/b612/keygen" "b612.me/apps/b612/keygen"
@ -21,10 +22,12 @@ import (
"b612.me/apps/b612/net" "b612.me/apps/b612/net"
"b612.me/apps/b612/rmt" "b612.me/apps/b612/rmt"
"b612.me/apps/b612/search" "b612.me/apps/b612/search"
"b612.me/apps/b612/socks5"
"b612.me/apps/b612/split" "b612.me/apps/b612/split"
"b612.me/apps/b612/tcping" "b612.me/apps/b612/tcping"
"b612.me/apps/b612/uac" "b612.me/apps/b612/uac"
"b612.me/apps/b612/vic" "b612.me/apps/b612/vic"
"b612.me/apps/b612/whois"
"b612.me/stario" "b612.me/stario"
"b612.me/starlog" "b612.me/starlog"
"github.com/inconshreveable/mousetrap" "github.com/inconshreveable/mousetrap"
@ -41,7 +44,7 @@ func init() {
cmdRoot.AddCommand(tcping.Cmd, uac.Cmd, httpserver.Cmd, httpreverse.Cmd, cmdRoot.AddCommand(tcping.Cmd, uac.Cmd, httpserver.Cmd, httpreverse.Cmd,
base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd, base64.Cmd, base85.Cmd, base91.Cmd, attach.Cmd, detach.Cmd, df.Cmd, dfinder.Cmd,
ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd, ftp.Cmd, generate.Cmd, hash.Cmd, image.Cmd, merge.Cmd, search.Cmd, split.Cmd, vic.Cmd,
calc.Cmd, net.Cmd, rmt.Cmds, rmt.Cmdc, keygen.Cmd, dns.Cmd) calc.Cmd, net.Cmd, rmt.Cmds, rmt.Cmdc, keygen.Cmd, dns.Cmd, whois.Cmd, socks5.Cmd, httproxy.Cmd)
} }
func main() { func main() {

@ -7,7 +7,7 @@ import (
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "net", Use: "net",
Short: "net tools", Short: "网络工具包括nat穿透端口转发等",
} }
func init() { func init() {
@ -38,7 +38,7 @@ func init() {
var CmdNatClient = &cobra.Command{ var CmdNatClient = &cobra.Command{
Use: "natc", Use: "natc",
Short: "nat client", Short: "nat穿透客户端",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if natc.ServiceTarget == "" || natc.CmdTarget == "" { if natc.ServiceTarget == "" || natc.CmdTarget == "" {
cmd.Help() cmd.Help()
@ -50,7 +50,7 @@ var CmdNatClient = &cobra.Command{
var CmdNatServer = &cobra.Command{ var CmdNatServer = &cobra.Command{
Use: "nats", Use: "nats",
Short: "nat server", Short: "nat穿透服务端",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
nats.Run() nats.Run()

@ -24,8 +24,8 @@ func init() {
var CmdNetforward = &cobra.Command{ var CmdNetforward = &cobra.Command{
Use: "forward", Use: "forward",
Short: "net forward", Short: "端口转发工具",
Long: "forward tcp and udp packet", Long: "端口转发工具支持tcp和udp转发",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 { if len(args) == 0 {
starlog.Errorln("please enter a target uri") starlog.Errorln("please enter a target uri")

@ -29,7 +29,7 @@ func init() {
var Cmdc = &cobra.Command{ var Cmdc = &cobra.Command{
Use: "rmtc", Use: "rmtc",
Short: "simple remote shell client", Short: "远程命令执行客户端",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if rmtRmt == "" { if rmtRmt == "" {
starlog.Errorln("Please Enter Remote Path") starlog.Errorln("Please Enter Remote Path")

@ -41,7 +41,7 @@ func init() {
var Cmds = &cobra.Command{ var Cmds = &cobra.Command{
Use: "rmts", Use: "rmts",
Short: "simple remote shell server", Short: "远程命令执行服务端",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if rmtListenPort == "" { if rmtListenPort == "" {
starlog.Errorln("Please Enter Port") starlog.Errorln("Please Enter Port")

@ -0,0 +1,48 @@
package socks5
import (
"b612.me/starlog"
"github.com/spf13/cobra"
"github.com/things-go/go-socks5"
"log"
"os"
)
var username, password string
var listen string
func init() {
Cmd.Flags().StringVarP(&username, "username", "u", "", "用户名")
Cmd.Flags().StringVarP(&password, "password", "p", "", "密码")
Cmd.Flags().StringVarP(&listen, "listen", "l", ":8000", "监听地址")
}
var Cmd = &cobra.Command{
Use: "socks5",
Short: "socks5代理",
Long: "socks5代理",
Run: func(cmd *cobra.Command, args []string) {
run()
},
}
func run() {
// Create a SOCKS5 server
var opt []socks5.Option
opt = append(opt, socks5.WithLogger(socks5.NewLogger(log.New(os.Stdout, "socks5: ", log.LstdFlags))))
if username != "" && password != "" {
opt = append(opt, socks5.WithAuthMethods([]socks5.Authenticator{
socks5.UserPassAuthenticator{Credentials: socks5.StaticCredentials{username: password}},
}))
}
server := socks5.NewServer(
opt...,
)
starlog.Infof("socks5 server listen on %s", listen)
// Create SOCKS5 proxy on localhost port 8000
if err := server.ListenAndServe("tcp", listen); err != nil {
starlog.Errorln("socks5 server error:", err)
os.Exit(1)
}
}

@ -28,7 +28,7 @@ var (
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "tcping", Use: "tcping",
Short: "tcp/http dns", Short: "tcp/http ping 工具",
Long: "使用进行Tcp或Http协议进行ping探测", Long: "使用进行Tcp或Http协议进行ping探测",
Example: ` Example: `
1. dns over tcp 1. dns over tcp

@ -24,9 +24,9 @@ func init() {
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "uac", Use: "uac",
Short: "run process with administrator permission", Short: "以管理员权限运行程序",
Example: "vtqe uac 'c:\\program.exe arg1 arg2'", Example: "b612 uac 'c:\\program.exe arg1 arg2'",
Version: "2.0.0", Version: "2.1.0",
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
showWindow = !showWindow showWindow = !showWindow
workdir, _ = filepath.Abs(workdir) workdir, _ = filepath.Abs(workdir)

@ -21,10 +21,6 @@ var Cmd = &cobra.Command{
pwd, _ := this.Flags().GetString("key") pwd, _ := this.Flags().GetString("key")
rep, _ := this.Flags().GetBool("replace") rep, _ := this.Flags().GetBool("replace")
ext, _ := this.Flags().GetBool("extension") ext, _ := this.Flags().GetBool("extension")
if len(args) != 2 || args[1] != "sakura" {
starlog.Errorln("ヴィクトリカだけが使えるよ")
return
}
shell := func(pect float64) { shell := func(pect float64) {
if pect == 100 { if pect == 100 {
fmt.Println("已处理100.000000%") fmt.Println("已处理100.000000%")

@ -0,0 +1,47 @@
package whois
import (
"b612.me/staros"
"github.com/likexian/whois"
"github.com/spf13/cobra"
"os"
"time"
)
var timeout int
var output string
func init() {
Cmd.Flags().IntVarP(&timeout, "timeout", "t", 20, "超时时间")
Cmd.Flags().StringVarP(&output, "output", "o", "", "输出文件夹")
}
var Cmd = &cobra.Command{
Use: "whois",
Short: "whois查询",
Long: "whois查询",
Run: func(cmd *cobra.Command, args []string) {
if len(args) == 0 {
cmd.Help()
return
}
if !staros.Exists(output) {
cmd.Println("输出文件夹不存在,将使用标准输出")
output = ""
}
c := whois.NewClient()
c.SetTimeout(time.Second * time.Duration(timeout))
for _, v := range args {
data, err := c.Whois(v)
cmd.Println("Query:", v)
if err != nil {
cmd.Println("查询失败:", err)
cmd.Println("-----------------------------------------------------")
continue
}
cmd.Println(data)
cmd.Println("-----------------------------------------------------")
os.WriteFile(output+"/"+v+".txt", []byte(data), 0644)
}
},
}
Loading…
Cancel
Save