Skip to content

Commit

Permalink
init commit
Browse files Browse the repository at this point in the history
  • Loading branch information
kumavis committed Aug 3, 2017
0 parents commit b67bcf2
Show file tree
Hide file tree
Showing 6 changed files with 468 additions and 0 deletions.
92 changes: 92 additions & 0 deletions .gitignore
@@ -0,0 +1,92 @@

# Created by https://www.gitignore.io/api/osx,node

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env


### OSX ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# End of https://www.gitignore.io/api/osx,node
17 changes: 17 additions & 0 deletions package.json
@@ -0,0 +1,17 @@
{
"name": "eth-phishing-detect",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "node test"
},
"author": "",
"license": "ISC",
"dependencies": {
"fast-levenshtein": "^2.0.6"
},
"devDependencies": {
"tape": "^4.8.0"
}
}
89 changes: 89 additions & 0 deletions src/config.json
@@ -0,0 +1,89 @@
{
"whitelist": [
"metamask.io",
"myetherwallet.com",
"myetheroll.com",
"myetherapi.com",
"ledgerwallet.com"
],
"blacklist": [
"wallet-ethereum.net",
"myelherwallel.com",
"etherswap.org",
"eos.ac",
"uasfwallet.com",
"ziber.io",
"mvetherwallet.com",
"etherswap.org",
"myethewallet.net",
"multiply-ethereum.info",
"bittrex.comze.com",
"karbon.vacau.com",
"xn--myetherwallt-7db.com",
"xn--myetherwallt-leb.com",
"etherdelta.gitlhub.io",
"etherdelta.glthub.io",
"myethewallet.net",
"myetherwillet.com",
"digitaldevelopersfund.vacau.com",
"myetherwallel.com",
"myeltherwallet.com",
"myelherwallet.com",
"wwwmyetherwallet.com",
"myethermwallet.com",
"district-0x.io",
"coin-dash.com",
"coindash.ru",
"myethervallet.com",
"myetherwallet.com.gl",
"myetherwallet.com.ua",
"myÄ—therwallet.com",
"myetherwallet.com.gl",
"xn--mytherwallet-fvb.com",
"district0x.net",
"aragonproject.io",
"coin-wallet.info",
"coinswallet.info",
"contribute-status.im",
"secure-myetherwallet.com",
"update-myetherwallet.com",
"ether-api.com",
"ether-wall.com",
"mycoinwallet.net",
"etherclassicwallet.com",
"ethereumchamber.com",
"ethereumchamber.net",
"ethereumchest.com",
"myethervvallet.com",
"metherwallet.com",
"mtetherwallet.com",
"my-etherwallet.com",
"my-etherwallet.in",
"myeherwallet.com",
"myetcwallet.com",
"myetehrwallet.com",
"myeterwallet.com",
"myethe.rwallet.com",
"myethereallet.com",
"myetherieumwallet.com",
"myetherswallet.com",
"myetherw.allet.com",
"myetherwal.let.com",
"myetherwalet.com",
"myetherwaliet.com",
"myetherwall.et.com",
"myetherwaller.com",
"myetherwallett.com",
"myetherwaillet.com",
"myetherwalllet.com",
"myetherweb.com.de",
"myethetwallet.com",
"myethewallet.com",
"omg-omise.co",
"omise-go.com",
"tenx-tech.com",
"tokensale-tenx.tech",
"ubiqcoin.org",
"metamask.com"
]
}
73 changes: 73 additions & 0 deletions src/detector.js
@@ -0,0 +1,73 @@
const levenshtein = require('fast-levenshtein')
const DEFAULT_TOLERANCE = 4

class PhishingDetector {

constructor (opts) {
this.blacklist = processDomainList(opts.blacklist || [])
this.whitelist = processDomainList(opts.whitelist || [])
this.tolerance = ('tolerance' in opts) ? opts.tolerance : DEFAULT_TOLERANCE
}

check (domain) {
const source = domainToParts(domain)

// if source matches whitelist domain (or subdomain thereof), PASS
const whitelistMatch = matchPartsAgainstList(source, this.whitelist)
if (whitelistMatch) return { type: 'whitelist', result: false }

// if source matches blacklist domain (or subdomain thereof), FAIL
const blacklistMatch = matchPartsAgainstList(source, this.blacklist)
if (blacklistMatch) return { type: 'blacklist', result: true }

// check if near-match of whitelist domain, FAIL
const fuzzyForm = domainPartsToFuzzyForm(source)
const levenshteinMatched = this.whitelist.find((targetParts) => {
const fuzzyTarget = domainPartsToFuzzyForm(targetParts)
const distance = levenshtein.get(fuzzyForm, fuzzyTarget)
return distance <= this.tolerance
})
if (levenshteinMatched) {
const match = domainPartsToDomain(levenshteinMatched)
return { type: 'fuzzy', result: true, match }
}

// matched nothing, PASS
return { type: 'all', result: false }
}

}

module.exports = PhishingDetector

// util

function processDomainList (list) {
return list.map(domainToParts)
}

function domainToParts (domain) {
return domain.split('.').reverse()
}

function domainPartsToDomain(domainParts) {
return domainParts.slice().reverse().join('.')
}

// for fuzzy search, drop TLD and re-stringify
function domainPartsToFuzzyForm(domainParts) {
return domainParts.slice(1).reverse().join('.')
}

// match the target parts, ignoring extra subdomains on source
// source: [io, metamask, xyz]
// target: [io, metamask]
// result: PASS
function matchPartsAgainstList(source, list) {
return list.some((target) => {
// target domain has more parts than source, fail
if (target.length > source.length) return false
// source matches target or (is deeper subdomain)
return target.every((part, index) => source[index] === part)
})
}
11 changes: 11 additions & 0 deletions src/index.js
@@ -0,0 +1,11 @@
const PhishingDetector = require('./detector')
const config = require('./config.json')

const detector = new PhishingDetector(config)

module.exports = checkDomain


function checkDomain(domain) {
return detector.check(domain).result
}

0 comments on commit b67bcf2

Please sign in to comment.