Last active
November 20, 2016 19:33
-
-
Save davidmz/66fb4caba208fec243b224eac96e331d to your computer and use it in GitHub Desktop.
Скрипт для обфуцирования юзернеймов, UUID-ов и токенов в логах Фидика
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Использование:
cat access_log | log-crypt -secret SOMESECRETSTRING > crypted_access_log
Секрет (
-secret
) обеспечивает преобразование одинаковых юзернеймов в одинаковые обфуцированные юзернеймы. Если обрабатываются несколько файлов, то следует задавать одинаковый секрет.