Monday, October 13, 2014

Every port is OPEN for security reasons.

Suppose you're a c00l hacker, and you need to scan for some system for open ports. What will you do? NMAP. Right?

You are scanning your victim and discovering some open ports:
80,135,445 etc. This will help you to choose your methodology of future enumeration, right?

With regular NMAP scan, like:
bt6# nmap
the target will be scanned, by default, for 1000 well known ports.

Stop for a second, and think if all of these ports will be open.

You, as a hacker, will stuck for some time, enumerating fake-open ports. Furthermore, it will be immediately logged in system.

My teacher gave this idea, and implementation with scapy.
The algorithm is simple:
Got SYN packet > Send back SYN-ACK with SEQ+1.
That was fine, but works in half of times. Not a production level.

Also, he told that he wasn't first that invented this method.
I've googled, and not found anything about that.

So, i've asked for help from kernel modules :)
IPTABLES - Port-forwarding.

What we'll need? 
1. Server that will respond to every incoming SYN packet.
2. IPTABLES or other firewall
3. IPSET (for use in iptables)
4. Real-time monitoring for adding/removing ports from SET.

You can open all ports, but i don't think it is necessary.
I will open only well-known ports of nmap. Everyone use nmap, don't think so?

First of all, DROP reset (RST) packet in OUTPUT table.
# iptables -A OUTPUT -p tcp -m tcp --tcp-flags RST RST -j DROP
Why? If some port is closed, your system will not respond with RST packet back, and other reasons, like got SYN-ACK, or RST, etc.

Secondly, DROP ICMP packet 'destination unreachable' in OUTPUT table.
# iptables -A OUTPUT -p icmp -m icmp --icmp-type 3 -j DROP
We don't want to allow somebody to know about any closed port in our system.

Create a set in IPSET:
# ipset create set_name bitmap:port range 0-65535

Add your well-known ports to this set:
# ipset add set_name port_number

If you want to test your specific port, if it in the set:
# ipset test set_name 8888
8888 is in set set_name.

Need a well-known port list? take it:
# nmap -dd |grep -E 'syn-ack|no-response'|cut -d'/' -f1 > ports.txt
This will work if you dropped a RESET packet in first step.

Assuming, you know BASH a little, you will know how to code a simple script that will add all ports to set in one click.

Ok. IPSET SET is created, let's make a main IPTABLES rule:
# iptables -t nat -A PREROUTING -p tcp -m set --match-set set_name dst -j REDIRECT --to-ports 8888

You may ask: "What is port 8888?"
That's the point. It is your server script that is listening only on one port, and answering everyone with a connection!

If you don't know how to make a server, you can use 'socat' for example:
# socat TCP-LISTEN:8888,reuseaddr,fork -

Otherwise, you can improve this script for you:
#!/usr/bin/env python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

port = 8888

s.bind((host, port))


 while True:
   c, addr = s.accept()
   data = c.recv(2048)
   response = ''
   c.send("Welcome %s. Logged.\n" % addr[0])
except KeyboardInterrupt:

It will listen on 8888 port (chose yours), and will send back "Welcome IP_ADDR. Logged."

The output:
# nc 8888

Welcome Logged.

Proof of concept: Nmap (fast) scanning
# nmap -F

Starting Nmap 6.46 ( ) at 2014-10-13 03:06 IDT
Nmap scan report for
Host is up (0.0026s latency).
7/tcp     open     echo
9/tcp     open     discard
13/tcp    open     daytime
21/tcp    open     ftp
22/tcp    open     ssh
23/tcp    open     telnet
25/tcp    open     smtp
26/tcp    open     rsftp
37/tcp    open     time
53/tcp    open     domain
79/tcp    open     finger
80/tcp    open     http
81/tcp    open     hosts2-ns
88/tcp    open     kerberos-sec
106/tcp   open     pop3pw
110/tcp   open     pop3
111/tcp   open     rpcbind
113/tcp   open     ident
119/tcp   open     nntp
135/tcp   open     msrpc
139/tcp   open     netbios-ssn
143/tcp   open     imap
144/tcp   open     news
179/tcp   open     bgp
199/tcp   open     smux
389/tcp   open     ldap
427/tcp   open     svrloc
443/tcp   open     https
444/tcp   open     snpp
445/tcp   open     microsoft-ds
465/tcp   open     smtps
513/tcp   open     login
514/tcp   open     shell
515/tcp   open     printer
543/tcp   open     klogin
544/tcp   open     kshell
548/tcp   open     afp
554/tcp   open     rtsp
587/tcp   open     submission
631/tcp   open     ipp
646/tcp   open     ldp
873/tcp   open     rsync
990/tcp   open     ftps
993/tcp   open     imaps
995/tcp   open     pop3s
1025/tcp  open     NFS-or-IIS
1026/tcp  open     LSA-or-nterm
1027/tcp  open     IIS
1028/tcp  open     unknown
1029/tcp  open     ms-lsa
1110/tcp  open     nfsd-status
1433/tcp  open     ms-sql-s
1720/tcp  open     H.323/Q.931
1723/tcp  open     pptp
1755/tcp  open     wms
1900/tcp  open     upnp
2000/tcp  open     cisco-sccp
2001/tcp  open     dc
2049/tcp  open     nfs
2121/tcp  open     ccproxy-ftp
2717/tcp  open     pn-requester
3000/tcp  open     ppp
3128/tcp  open     squid-http
3306/tcp  open     mysql
3389/tcp  open     ms-wbt-server
3986/tcp  open     mapper-ws_ethd
4899/tcp  open     radmin
5000/tcp  open     upnp
5009/tcp  open     airport-admin
5051/tcp  open     ida-agent
5060/tcp  open     sip
5101/tcp  open     admdog
5190/tcp  open     aol
5357/tcp  open     wsdapi
5432/tcp  open     postgresql
5631/tcp  open     pcanywheredata
5666/tcp  open     nrpe
5800/tcp  open     vnc-http
5900/tcp  open     vnc
6000/tcp  open     X11
6001/tcp  open     X11:1
6646/tcp  open     unknown
7070/tcp  open     realserver
8000/tcp  open     http-alt
8008/tcp  open     http
8009/tcp  open     ajp13
8080/tcp  open     http-proxy
8081/tcp  open     blackice-icecap
8443/tcp  open     https-alt
8888/tcp  open     sun-answerbook
9100/tcp  open     jetdirect
9999/tcp  open     abyss
10000/tcp open     snet-sensor-mgmt
32768/tcp open     filenet-tms
49152/tcp open     unknown
49153/tcp open     unknown
49154/tcp open     unknown
49155/tcp open     unknown
49156/tcp open     unknown
49157/tcp open     unknown
MAC Address: 00:0C:29:73:95:1C (VMware)

Nmap done: 1 IP address (1 host up) scanned in 1.43 seconds

Remains to solve only one problem. What if you want to open a port for some reason? like netcat...

We need a realtime monitoring for listening ports, and if the there appeared one or more new listen ports, we need to remove them from IPSET set. Otherwise if one or more listening ports disappeared, we have to add them to the SET.

A fast and dirty implementation of this:

from subprocess import check_output
import re
from time import sleep

set_name = 'rports'

def open_ports():
   netstat = check_output('netstat -tan',shell=True)
   lports = re.findall(r'(?<=\:)[0-9]{1,5}\w(?=.+listen)',netstat.lower())
   lports = list(set(lports))
   return lports

tmp_ports = []

while 1:
   openports = open_ports()
   new_open = list(set(openports) - set(tmp_ports))
   new_closed = list(set(tmp_ports) - set(openports))
   if len(new_open):
     for port in new_open:
       #print 'removing port %s from ipset' % port
       os.system('ipset del %s %s' % (set_name,port))
   if len(new_closed):
     for port in new_closed:
       #print 'adding port %d to ipset' % int(port)
       os.system('ipset add %s %s' % (set_name,port))
   tmp_ports = openports

This will run 'netstat -tan' and look for changes in LISTEN ports.

Code on github:

The idea - by Gil Rozenberg
Implementation with iptables/ipset - by Alexander Korznikov

nice to be a root#


  1. instead of adding a port to SET, now i prefer to delete it from SET..
    ~# ipset add set_name 0-65535

    and then delete the difference:

    ~# ipset del rports $port

    you may check if this worked for you with command:

    ~# ipset test rports PORT#

  2. Thanks for this solution. It is really great! I forked your github and changed a little bit to be compatible with python3 and to do some automation to be easier to anyone run.