Skip to content

Instantly share code, notes, and snippets.

@davidmz
Last active November 20, 2016 19:33
Show Gist options
  • Save davidmz/66fb4caba208fec243b224eac96e331d to your computer and use it in GitHub Desktop.
Save davidmz/66fb4caba208fec243b224eac96e331d to your computer and use it in GitHub Desktop.
Скрипт для обфуцирования юзернеймов, UUID-ов и токенов в логах Фидика
package main
import (
"bufio"
"crypto/hmac"
"crypto/sha1"
"encoding/hex"
"flag"
"fmt"
"os"
"regexp"
"strings"
)
var pathTemplates = makeRegexps([]string{
`^/v1/users/whoami`,
`^/v1/users/(?:accept|reject)Request/([^/]+)`,
`^/v1/users/([^/]+)`,
`^/v1/timelines/(?:home|filter/)`,
`^/v1/timelines/([^/]+)`,
`^/v1/groups/([^/]+)/subscribers/([^/]+)`,
`^/v1/groups/([^/]+)`,
`^/v2/requests/([^/]+)`,
})
var pathTokenTemplates = makeRegexps([]string{
`token=([^&]+)`,
})
var refererTemplates = makeRegexps([]string{
`^https://(?:(?:gamma\.|m\.|)freefeed\.net|myfeed\.rocks)/(?:about|dev|signin|signup|restore|reset|settings|filter|search|groups|friends)`,
`^https://(?:m\.freefeed\.net|myfeed\.rocks)/as/(?:FreeFeed|Mokum)/([^/]+)`,
`^https://(?:(?:gamma\.|m\.|)freefeed\.net|myfeed\.rocks)/([^/]+)`,
})
var uuidTemplates = makeRegexps([]string{
`([a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[8|9|a|b][a-f0-9]{3}-[a-f0-9]{12})`,
})
var logFormatRe = regexp.MustCompile(`^` +
`(?P<proxy_protocol_addr>[^ ]+) - ` +
`(?P<remote_user>[^ ]+) ` +
`\[(?P<time_local>[^\]]+)\] ` +
`"(?P<request>[^"]+)" ` +
`(?P<status>[^ ]+) ` +
`(?P<body_bytes_sent>[^ ]+) ` +
`"(?P<http_referer>[^"]+)" ` +
`"(?P<http_user_agent>[^"]+)" ` +
`(?P<request_time>[^ ]+) ` +
`(?P<upstream_response_time>[^ ]+) ` +
`(?P<pipe>[^ ]+)` +
`$`)
var logVarNames = logFormatRe.SubexpNames()
var secret string
func main() {
flag.StringVar(&secret, "secret", "", "a secret string for username encoding")
flag.Parse()
if secret == "" {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
flag.PrintDefaults()
os.Exit(1)
}
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
matches := logFormatRe.FindStringSubmatch(scanner.Text())
if matches == nil {
continue
}
matches[4] = encryptRequest(matches[4]) // request
matches[7] = encryptReferer(matches[7]) // referer
fmt.Printf("%s - %s [%s] \"%s\" %s %s \"%s\" \"%s\" %s %s %s\n", untypeArray(matches[1:])...)
}
}
func encryptRequest(text string) string {
parts := strings.Split(text, " ")
parts[1] = encryptText(parts[1], pathTemplates, encryptUsername)
parts[1] = encryptText(parts[1], pathTokenTemplates, encryptToken)
parts[1] = encryptText(parts[1], uuidTemplates, encryptUUID)
return strings.Join(parts, " ")
}
func encryptReferer(text string) string {
text = encryptText(text, refererTemplates, encryptUsername)
text = encryptText(text, uuidTemplates, encryptUUID)
return text
}
func encryptText(text string, regexps []*regexp.Regexp, crypter func(string) string) (newText string) {
newText = text
for _, re := range regexps {
m := re.FindStringSubmatchIndex(text)
if m != nil {
lastIndex := 0
newText = ""
for i := 0; i < len(m)/2-1; i++ {
uname := crypter(text[m[2*i+2]:m[2*i+3]])
newText += text[lastIndex:m[2*i+2]] + uname
lastIndex = m[2*i+3]
}
newText += text[lastIndex:]
break
}
}
return
}
func encryptUsername(username string) string {
const chars = "abcdefghijklmnopqrstuvwxyz"
mac := hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(username))
umac := mac.Sum(nil)
length := 5 + int(umac[0]%5)
result := ""
for i := 0; i < length; i++ {
p := int(umac[i+1]) % len(chars)
result += chars[p : p+1]
}
return result
}
func encryptToken(token string) string {
mac := hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(token))
return fmt.Sprintf("%X", mac.Sum(nil))
}
func encryptUUID(token string) string {
mac := hmac.New(sha1.New, []byte(secret))
mac.Write([]byte(token))
umac := mac.Sum(nil)[:16]
umac[6] = (umac[6] & 0x0f) | (4 << 4) // UUID v4
umac[8] = (umac[8] | 0x40) & 0x7F
return uuidString(umac)
}
func makeRegexps(patterns []string) (result []*regexp.Regexp) {
for _, p := range patterns {
result = append(result, regexp.MustCompile(p))
}
return
}
func untypeArray(a []string) (b []interface{}) {
for _, x := range a {
b = append(b, interface{}(x))
}
return
}
func uuidString(u []byte) string {
const dash byte = '-'
buf := make([]byte, 36)
hex.Encode(buf[0:8], u[0:4])
buf[8] = dash
hex.Encode(buf[9:13], u[4:6])
buf[13] = dash
hex.Encode(buf[14:18], u[6:8])
buf[18] = dash
hex.Encode(buf[19:23], u[8:10])
buf[23] = dash
hex.Encode(buf[24:], u[10:])
return string(buf)
}
@davidmz
Copy link
Author

davidmz commented Nov 4, 2016

Использование: cat access_log | log-crypt -secret SOMESECRETSTRING > crypted_access_log

Секрет (-secret) обеспечивает преобразование одинаковых юзернеймов в одинаковые обфуцированные юзернеймы. Если обрабатываются несколько файлов, то следует задавать одинаковый секрет.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment