main.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package main
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "os"
  7. "path/filepath"
  8. "github.com/cloudflare/mitmengine"
  9. "github.com/cloudflare/mitmengine/db"
  10. )
  11. var outDir = filepath.Join("mergedb")
  12. var mitmConfig = mitmengine.Config{
  13. BrowserFileName: filepath.Join("reference_fingerprints", "mitmengine", "browser.txt"),
  14. MitmFileName: filepath.Join("reference_fingerprints", "mitmengine", "mitm.txt"),
  15. BadHeaderFileName: filepath.Join("reference_fingerprints", "mitmengine", "badheader.txt"),
  16. }
  17. func askUser(scanner *bufio.Scanner, message string) bool {
  18. fmt.Println(message)
  19. if !scanner.Scan() {
  20. log.Fatal("Aborting...")
  21. }
  22. switch scanner.Text() {
  23. case "y", "Y", "Yes", "yes":
  24. return true
  25. }
  26. return false
  27. }
  28. func main() {
  29. var err error
  30. var file *os.File
  31. mitmProcessor, err := mitmengine.NewProcessor(&mitmConfig)
  32. if err != nil {
  33. log.Fatal(err)
  34. }
  35. os.MkdirAll(outDir, 0777)
  36. scanner := bufio.NewScanner(os.Stdin)
  37. var before, after int
  38. if askUser(scanner, "Automatically merge browser database?") {
  39. size := len(mitmProcessor.BrowserDatabase.Records)
  40. total := size * size
  41. count := 0
  42. before, after = mitmProcessor.BrowserDatabase.MergeBy(func(r1, r2 db.Record) bool {
  43. count++
  44. if count%size == 0 {
  45. fmt.Printf("(%.2f)\r", (float32(count*100))/float32(total))
  46. }
  47. // Don't automatically merge across these values
  48. if !(r1.UASignature.BrowserName == r2.UASignature.BrowserName &&
  49. r1.UASignature.OSName == r2.UASignature.OSName &&
  50. r1.UASignature.OSVersion == r2.UASignature.OSVersion &&
  51. r1.UASignature.DeviceType == r2.UASignature.DeviceType &&
  52. r1.UASignature.Quirk.String() == r2.UASignature.Quirk.String() &&
  53. r1.RequestSignature.Version.String() == r2.RequestSignature.Version.String() &&
  54. r1.RequestSignature.Curve.String() == r2.RequestSignature.Curve.String() &&
  55. r1.RequestSignature.EcPointFmt.String() == r2.RequestSignature.EcPointFmt.String() &&
  56. r1.RequestSignature.Quirk.String() == r2.RequestSignature.Quirk.String()) {
  57. return false
  58. }
  59. merged := r1.RequestSignature.Merge(r2.RequestSignature)
  60. // Merge if one of the request signatures already contains the other.
  61. if r1.RequestSignature.String() == merged.String() || r2.RequestSignature.String() == merged.String() {
  62. return true
  63. }
  64. // Do not merge if the merged signature is too lenient
  65. if merged.Cipher.OrderedList == nil && merged.Cipher.OptionalSet.Len() > 10 {
  66. return false
  67. }
  68. if merged.Extension.OrderedList == nil && merged.Extension.OptionalSet.Len() > 10 {
  69. return false
  70. }
  71. return true
  72. })
  73. fmt.Printf("Before: %d, After: %d\n", before, after)
  74. }
  75. if askUser(scanner, "Manually merge browser database?") {
  76. before, after = mitmProcessor.BrowserDatabase.MergeBy(func(r1, r2 db.Record) bool {
  77. return askUser(scanner, fmt.Sprintf("in1: %s\nin2: %s\nout: %s\nMerge? ", r1, r2, r1.Merge(r2)))
  78. })
  79. fmt.Printf("Before: %d, After: %d\n", before, after)
  80. }
  81. fmt.Println("Dumping browser database")
  82. // dump browser database
  83. file, err = os.Create(filepath.Join(outDir, "browser.txt"))
  84. if err != nil {
  85. log.Fatal(err)
  86. }
  87. mitmProcessor.BrowserDatabase.Dump(file)
  88. if askUser(scanner, "Automatically merge mitm database?") {
  89. mitmProcessor.MitmDatabase.MergeBy(func(r1, r2 db.Record) bool { return r1.RequestSignature.String() == r2.RequestSignature.String() })
  90. mitmProcessor.MitmDatabase.MergeBy(func(r1, r2 db.Record) bool {
  91. return r1.RequestSignature.String() == r2.RequestSignature.String()
  92. })
  93. }
  94. if askUser(scanner, "Manually merge mitm database?") {
  95. mitmProcessor.MitmDatabase.MergeBy(func(r1, r2 db.Record) bool { return r1.RequestSignature.String() == r2.RequestSignature.String() })
  96. mitmProcessor.MitmDatabase.MergeBy(func(r1, r2 db.Record) bool {
  97. return askUser(scanner, fmt.Sprintf("in1: %s\nin2: %s\nout: %s\nMerge? ", r1, r2, r1.Merge(r2)))
  98. })
  99. }
  100. fmt.Println("Dumping mitm database")
  101. // dump mitm database
  102. file, err = os.Create(filepath.Join(outDir, "mitm.txt"))
  103. if err != nil {
  104. log.Fatal(err)
  105. }
  106. mitmProcessor.MitmDatabase.Dump(file)
  107. fmt.Println("Finished")
  108. }