correct update-check

This commit is contained in:
Hyatt 2024-01-19 20:17:50 -06:00
parent 567cfe8083
commit ef68e8c4a2
Signed by: nhyatt
GPG Key ID: C50D0BBB5BC40BEA
4 changed files with 31 additions and 367 deletions

9
go.mod
View File

@ -1,12 +1,3 @@
module istheinternetonfire.app
go 1.21.6
require github.com/miekg/dns v1.1.57
require (
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/tools v0.17.0 // indirect
)

12
go.sum
View File

@ -1,12 +0,0 @@
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=

View File

@ -4,12 +4,10 @@ import (
"bytes"
"fmt"
"net"
"strconv"
"strings"
"os/exec"
"github.com/miekg/dns"
"istheinternetonfire.app/internal/config"
)
@ -33,33 +31,24 @@ var (
}
)
func (c NsUpdateStruct) Update(record, recordType, value string) error {
if strings.ToUpper(recordType) == "TXT" {
// sanitize TXT value
for _, v := range specialChars {
value = strings.ReplaceAll(value, v, fmt.Sprintf("\\%s", v))
}
// convert to rune
a := []rune(value)
// split into 255 character blocks
value = ""
for i, r := range a {
value += string(r)
if i > 0 && (i+1)%254 == 0 {
value += string(`" "`)
}
}
// convert new lines into safe string
value = strings.ReplaceAll(value, "\n", "%n")
func (c NsUpdateStruct) UpdateTXT(record, recordType, value string) error {
for _, v := range specialChars {
value = strings.ReplaceAll(value, v, fmt.Sprintf("\\%s", v))
}
r, err := getRecord(c.Server, c.Port, recordType, record)
value = sanitizeTXT(value)
r, err := net.LookupTXT(record)
if err != nil {
config.Cfg.Log.Info("unable to get existing record", "record", record, "error", err)
}
config.Cfg.Log.Debug("comparing records", "old value", r, "new value", value)
if r != value {
var oldTXT string
for _, v := range r {
oldTXT += v
}
if strings.ReplaceAll(oldTXT, `" "`, ``) != strings.ReplaceAll(value, `" "`, ``) {
config.Cfg.Log.Debug("deleting record", "record", record)
if err := c.Delete(record, recordType); err != nil {
return err
@ -139,328 +128,24 @@ nsupdate -v -k <(printf '%%s' "${DDNS_KEY}") <(printf '%%s\n\n' "${COMMAND}")
return nil
}
func getRecord(server string, port int, queryType, query string) (string, error) {
config.Cfg.Log.Debug("looking up dns record", "query", query, "type", queryType)
recordType, err := getRecordType(queryType)
if err != nil {
return "", err
func sanitizeTXT(s string) string {
// convert to rune
a := []rune(s)
// split into 255 character blocks
s = ""
for i, r := range a {
s += string(r)
if i > 0 && (i+1)%254 == 0 {
s += string(`" "`)
}
}
// convert new lines into safe string
s = strings.ReplaceAll(s, "\n", "%n")
c := new(dns.Client)
m := new(dns.Msg)
m.SetQuestion(fmt.Sprintf("%s.", query), recordType)
m.RecursionDesired = true
r, _, err := c.Exchange(m, net.JoinHostPort(server, strconv.Itoa(port)))
if err != nil {
return "", err
}
if r.Rcode != dns.RcodeSuccess {
return "", err
}
for _, a := range r.Answer {
return getRecordFromResult(a, queryType)
}
return "", fmt.Errorf("no result")
return s
}
func getRecordFromResult(a dns.RR, queryType string) (string, error) {
switch strings.ToLower(queryType) {
case "a":
if res, ok := a.(*dns.A); ok {
return res.String(), nil
}
case "aaaa":
if res, ok := a.(*dns.AAAA); ok {
return res.String(), nil
}
case "afsdb":
if res, ok := a.(*dns.AFSDB); ok {
return res.String(), nil
}
case "apl":
if res, ok := a.(*dns.APL); ok {
return res.String(), nil
}
case "caa":
if res, ok := a.(*dns.CAA); ok {
return res.String(), nil
}
case "cdnskey":
if res, ok := a.(*dns.CDNSKEY); ok {
return res.String(), nil
}
case "cds":
if res, ok := a.(*dns.CDS); ok {
return res.String(), nil
}
case "cert":
if res, ok := a.(*dns.CERT); ok {
return res.String(), nil
}
case "cname":
if res, ok := a.(*dns.CNAME); ok {
return res.String(), nil
}
case "csync":
if res, ok := a.(*dns.CSYNC); ok {
return res.String(), nil
}
case "dhcid":
if res, ok := a.(*dns.DHCID); ok {
return res.String(), nil
}
case "dlv":
if res, ok := a.(*dns.DLV); ok {
return res.String(), nil
}
case "dname":
if res, ok := a.(*dns.DNAME); ok {
return res.String(), nil
}
case "dnskey":
if res, ok := a.(*dns.DNSKEY); ok {
return res.String(), nil
}
case "ds":
if res, ok := a.(*dns.DS); ok {
return res.String(), nil
}
case "eui48":
if res, ok := a.(*dns.EUI48); ok {
return res.String(), nil
}
case "eui64":
if res, ok := a.(*dns.EUI64); ok {
return res.String(), nil
}
case "hinfo":
if res, ok := a.(*dns.HINFO); ok {
return res.String(), nil
}
case "hip":
if res, ok := a.(*dns.HIP); ok {
return res.String(), nil
}
case "https":
if res, ok := a.(*dns.HTTPS); ok {
return res.String(), nil
}
case "ipseckey":
if res, ok := a.(*dns.IPSECKEY); ok {
return res.String(), nil
}
case "key":
if res, ok := a.(*dns.KEY); ok {
return res.String(), nil
}
case "kx":
if res, ok := a.(*dns.KX); ok {
return res.String(), nil
}
case "loc":
if res, ok := a.(*dns.LOC); ok {
return res.String(), nil
}
case "mx":
if res, ok := a.(*dns.MX); ok {
return res.String(), nil
}
case "naptr":
if res, ok := a.(*dns.NAPTR); ok {
return res.String(), nil
}
case "ns":
if res, ok := a.(*dns.NS); ok {
return res.String(), nil
}
case "nsec":
if res, ok := a.(*dns.NSEC); ok {
return res.String(), nil
}
case "nsec3":
if res, ok := a.(*dns.NSEC3); ok {
return res.String(), nil
}
case "nsec3param":
if res, ok := a.(*dns.NSEC3PARAM); ok {
return res.String(), nil
}
case "openpgpkey":
if res, ok := a.(*dns.OPENPGPKEY); ok {
return res.String(), nil
}
case "ptr":
if res, ok := a.(*dns.PTR); ok {
return res.String(), nil
}
case "rrsig":
if res, ok := a.(*dns.RRSIG); ok {
return res.String(), nil
}
case "rp":
if res, ok := a.(*dns.RP); ok {
return res.String(), nil
}
case "sig":
if res, ok := a.(*dns.SIG); ok {
return res.String(), nil
}
case "smimea":
if res, ok := a.(*dns.SMIMEA); ok {
return res.String(), nil
}
case "soa":
if res, ok := a.(*dns.SOA); ok {
return res.String(), nil
}
case "srv":
if res, ok := a.(*dns.SRV); ok {
return res.String(), nil
}
case "sshfp":
if res, ok := a.(*dns.SSHFP); ok {
return res.String(), nil
}
case "svcb":
if res, ok := a.(*dns.SVCB); ok {
return res.String(), nil
}
case "ta":
if res, ok := a.(*dns.TA); ok {
return res.String(), nil
}
case "tkey":
if res, ok := a.(*dns.TKEY); ok {
return res.String(), nil
}
case "tlsa":
if res, ok := a.(*dns.TLSA); ok {
return res.String(), nil
}
case "tsig":
if res, ok := a.(*dns.TSIG); ok {
return res.String(), nil
}
case "txt":
if res, ok := a.(*dns.TXT); ok {
return res.String(), nil
}
case "uri":
if res, ok := a.(*dns.URI); ok {
return res.String(), nil
}
case "zonemd":
if res, ok := a.(*dns.ZONEMD); ok {
return res.String(), nil
}
}
return "", fmt.Errorf("invalid record type")
}
func getRecordType(queryType string) (uint16, error) {
var recordType uint16
switch strings.ToLower(queryType) {
case "a":
recordType = dns.TypeA
case "aaaa":
recordType = dns.TypeAAAA
case "afsdb":
recordType = dns.TypeAFSDB
case "apl":
recordType = dns.TypeAPL
case "caa":
recordType = dns.TypeCAA
case "cdnskey":
recordType = dns.TypeCDNSKEY
case "cds":
recordType = dns.TypeCDS
case "cert":
recordType = dns.TypeCERT
case "cname":
recordType = dns.TypeCNAME
case "csync":
recordType = dns.TypeCSYNC
case "dhcid":
recordType = dns.TypeDHCID
case "dlv":
recordType = dns.TypeDLV
case "dname":
recordType = dns.TypeDNAME
case "dnskey":
recordType = dns.TypeDNSKEY
case "ds":
recordType = dns.TypeDS
case "eui48":
recordType = dns.TypeEUI48
case "eui64":
recordType = dns.TypeEUI64
case "hinfo":
recordType = dns.TypeHINFO
case "hip":
recordType = dns.TypeHIP
case "https":
recordType = dns.TypeHTTPS
case "ipseckey":
recordType = dns.TypeIPSECKEY
case "key":
recordType = dns.TypeKEY
case "kx":
recordType = dns.TypeKX
case "loc":
recordType = dns.TypeLOC
case "mx":
recordType = dns.TypeMX
case "naptr":
recordType = dns.TypeNAPTR
case "ns":
recordType = dns.TypeNS
case "nsec":
recordType = dns.TypeNSEC
case "nsec3":
recordType = dns.TypeNSEC3
case "nsec3param":
recordType = dns.TypeNSEC3PARAM
case "openpgpkey":
recordType = dns.TypeOPENPGPKEY
case "ptr":
recordType = dns.TypePTR
case "rrsig":
recordType = dns.TypeRRSIG
case "rp":
recordType = dns.TypeRP
case "sig":
recordType = dns.TypeSIG
case "smimea":
recordType = dns.TypeSMIMEA
case "soa":
recordType = dns.TypeSOA
case "srv":
recordType = dns.TypeSRV
case "sshfp":
recordType = dns.TypeSSHFP
case "svcb":
recordType = dns.TypeSVCB
case "ta":
recordType = dns.TypeTA
case "tkey":
recordType = dns.TypeTKEY
case "tlsa":
recordType = dns.TypeTLSA
case "tsig":
recordType = dns.TypeTSIG
case "txt":
recordType = dns.TypeTXT
case "uri":
recordType = dns.TypeURI
case "zonemd":
recordType = dns.TypeZONEMD
default:
return uint16(0), fmt.Errorf("invalid record type")
}
return recordType, nil
}
/*
CVE-2023-6549 - NetScaler ADC and NetScaler Gateway - Citrix NetScaler ADC and NetScaler Gateway contain a buffer overflow vulnerability that allows for a denial-of-service when configured as a Gateway (VPN virtual server, ICA Proxy, CVPN, RDP Proxy) or \" \"AAA virtual server.%nCVE-2023-6548 - NetScaler ADC and NetScaler Gateway - Citrix NetScaler ADC and NetScaler Gateway contain a code injection vulnerability that allows for authenticated remote code execution on the management interface with access to NS\" \"IP, CLIP, or SNIP.%nCVE-2023-35082 - Endpoint Manager Mobile (EPMM) and MobileIron Core - Ivanti Endpoint Manager Mobile (EPMM) and MobileIron Core contain an authentication bypass vulnerability that allows unauthorized users to access restricted functio\" \"nality or resources of the application.%n
CVE-2023-6549 - NetScaler ADC and NetScaler Gateway - Citrix NetScaler ADC and NetScaler Gateway contain a buffer overflow vulnerability that allows for a denial-of-service when configured as a Gateway (VPN virtual server, ICA Proxy, CVPN, RDP Proxy) or \" \"AAA virtual server.%nCVE-2023-6548 - NetScaler ADC and NetScaler Gateway - Citrix NetScaler ADC and NetScaler Gateway contain a code injection vulnerability that allows for authenticated remote code execution on the management interface with access to NSI\" \"P, CLIP, or SNIP.%nCVE-2023-35082 - Endpoint Manager Mobile (EPMM) and MobileIron Core - Ivanti Endpoint Manager Mobile (EPMM) and MobileIron Core contain an authentication bypass vulnerability that allows unauthorized users to access restricted functiona\" \"lity or resources of the application.%n
*/

View File

@ -56,7 +56,7 @@ func main() {
}
}
if len(cves) == 0 {
if err := dns.Update("istheinternetonfire.app", "TXT", "Safe for now!"); err != nil {
if err := dns.UpdateTXT("istheinternetonfire.app", "TXT", "Safe for now!"); err != nil {
config.Cfg.Log.Error("unable to update dns record", "error", err)
time.Sleep(time.Second * time.Duration(config.Cfg.RefreshSeconds))
continue
@ -69,7 +69,7 @@ func main() {
for _, v := range cves[len(cves)-num:] {
txtData += fmt.Sprintf("%s - %s - %s\n", v.CveID, v.Product, v.ShortDescription)
}
if err := dns.Update("istheinternetonfire.app", "TXT", txtData); err != nil {
if err := dns.UpdateTXT("istheinternetonfire.app", "TXT", txtData); err != nil {
config.Cfg.Log.Error("unable to update dns record", "error", err)
time.Sleep(time.Second * time.Duration(config.Cfg.RefreshSeconds))
continue