Skip to content

Instantly share code, notes, and snippets.

@jackhftang
Last active August 28, 2017 00:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackhftang/a013ae066b0deaee49c8faa58652ea1b to your computer and use it in GitHub Desktop.
Save jackhftang/a013ae066b0deaee49c8faa58652ea1b to your computer and use it in GitHub Desktop.
A simple knocking server
from bottle import route, run, template, error
import bottle
import subprocess
from random import random
from time import sleep
sequence = ['key1', 'key2', 'key3']
exclude = ['favicon.ico']
table = {}
def bingo(addr):
print('accept', addr)
# sudo iptables -I INPUT -p tcp --dport 33060 -s <addr> -j ACCEPT
subprocess.run(['sudo', 'iptables', '-I', 'INPUT', '-p', 'tcp', '--dport', '33060', '-s', addr, '-j', 'ACCEPT'])
def delay():
sleep(0.2 + 0.5 * random())
@error(404)
def notFound(error):
return ''
@route('/<path>')
def knock(path):
if path in exclude:
return ''
addr = bottle.request.remote_addr
cnt = 0
if addr in table:
cnt = table[addr]
## increase count by 1 or reset
if path == sequence[cnt]:
table[addr] = cnt + 1
## pass whole sequence
if table[addr] == len(sequence):
bingo(addr)
table.pop(addr, None)
delay()
return addr
else:
table.pop(addr, None)
## add noise against timing attack and make attack longer
delay()
return path
run(host='0.0.0.0', port=54321, reloader=False)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment