oracle注入大全(三)
Packet sniffing
The main issue with packet sniffing for connections to the Oracle database is that the Oracle network protocol is proprietary and not published. Does that matter for trying to ascertain if SQL injection attempts have taken place? Probably yes, as access to the protocol would allow a better design and efficient tool for this task. Without access to the protocol and no wish to reverse engineer it, the task is limited to grabbing ASCII text strings from the wire. There are both advantages and disadvantages with this method:
Advantages:
A system could be implemented on a separate server allowing real time analysis without impacting the source database.
Disadvantages:
This method can be resource intensive.
The packets need to be sniffed close to the source and on the same subnet to ensure all packets pass in front of the sniffer.
If the Oracle advanced security options for encrypting of network packets or any other third party solution is used to encrypt, sniffing packets will not work.
If, as in our example, the SQL injection attempt is passed as a call to a package procedure then the true internal dynamic SQL will not be visible. Instead you will simply see the typed in command.
Packet sniffing every packet will generate a huge amount of data. Piping the packets through a filter program is a solution to mitigate this issue.
To demonstrate, we will use snoop on Solaris to see what is visible within network packets. Start up snoop and fire the SQL from a SQL*Plus session:
root:jupiter> snoop -t a -x 0 jupiter and port 1521 | strings
Using device /dev/hme (promiscuous mode)
15:06:34.31348 172.16.240.3 -> jupiter TCP D=1521 S=1404 Ack=299902194 Seq=26460609 Len=174 Win=8413
0: 0800 2092 9d88 00a0 ccd3 a550 0800 4500 .. ........P..E.
16: 00d6 6884 4000 8006 596d ac10 f003 ac10 ..h.@...Ym......
32: f00b 057c 05f1 0193 c1c1 11e0 24f2 5018 ...|........$.P.
48: 20dd 0f36 0000 00ae 0000 0600 0000 0000 ..6............
64: 1169 36a4 61de 0001 0101 0303 5e37 0304 .i6.a.......^7..
80: 0021 0078 71de 0001 52bc 39de 0001 0a00 .!.xq...R.9.....
96: 0000 00e0 39de 0000 0101 0000 0000 0000 ....9...........
112: 0000 0000 0000 0000 0000 0000 0000 0000 ................
128: e239 de00 4245 4749 4e20 6765 745f 6375 .9..BEGIN get_cu
144: 7374 2827 7827 2720 756e 696f 6e20 7365 st('x'' union se
160: 6c65 6374 2075 7365 726e 616d 6520 6672 lect username fr
176: 6f6d 2061 6c6c 5f75 7365 7273 2077 6865 om all_users whe
192: 7265 2027 2778 2727 3d27 2778 2729 3b20 re ''x''=''x');
208: 454e 443b 0a00 0101 0101 0000 0000 0001 END;............
224: 0800 0105 ....
15:06:34.33281 jupiter -> 172.16.240.3 TCP D=1404 S=1521 Ack=26460783
Seq=299902194 Len=54 Win=24820
0: 00a0 ccd3 a550 0800 2092 9d88 0800 4500 .....P.. .....E.
16: 005e 094a 4000 4006 f91f ac10 f00b ac10 .^.J@.@.........
32: f003 05f1 057c 11e0 24f2 0193 c26f 5018 .....|..$....oP.
An immediate success with this method is apparent, because the SQL is captured with the SQL injection attempt in it. As with other methods in this article, to take this further a few things would need to be done:
A filter program would need to be implemented that could parse out the SQL statements and determine if any potential SQL injection attempt has taken place.
To be of any real use the filter program would also need to extract the timestamp from the packet header as well as the source IP address.
Extracting the database user would be extremely difficult as previous packets would need to be inspected to extract login information. This would also suggest the need to store previous packets or information about them and their sequence to do this.
As a simple solution, packet sniffing would appear to be an option provided a reasonably simple filter/parser program can be written in Perl or C. The goal would be to output the possible wrongdoing by extracting the SQL, timestamp and src and dest IP from the packet stream.
Sniffing packets within oracle (sqlnet trace)
Extracting network information closer to Oracle is possible by using the trace facility of SQL*Net, Net*8 or Oracle networking (whichever name is relevant to your database release).
Trace facilities are available for most of the Oracle networking tools such as the listener, Oracle names, connection manager, names control utility and of course the Oracle networking client and server. In this example we can concentrate on the server trace. It is possible to trace from the client end but it would be necessary to do so for all clients and thus harder to manage.
There are some disadvantages to using Oracle networking trace files as a tool to look for SQL injection:
The trace files can grow very quickly and use an enormous amount of disk space. If not managed correctly there is a danger of filling a disk and a possible denial of service taking place.
There is an overhead involved in writing the trace files.
Even though it is possible to define a unique trace file name and location, Oracle appends a process ID (PID) to the trace file name. This is the operating system PID of the shadow process. The pid can be seen with the following SQL:
SQL> select p.spid,s.username
2 from v$session s,v$process p
3 where s.paddr=p.addr;
SPID USERNAME
--------- ------------------------------
<records snipped>
616 DBSNMP
556 SYSTEM
9 rows selected.
SQL>
To enable trace simply add the following lines to the $ORACLE_HOME/network/admin/sqlnet.ora file:
TRACE_FILE_SERVER=pf_trace.trc
TRACE_DIRECTORY_SERVER=/tmp
TRACE_LEVEL_SERVER=SUPPORT
The parameters define where the trace is to be written, what it is called and also the level. There are four levels that can be used: OFF, USER, ADMIN and SUPPORT. They rise in detail from OFF to SUPPORT; the SUPPORT level includes the contents of the network packets.
Let's run our example again from SQL*Plus on a Windows client and see what is generated in the trace file. The trace file is as expected, pf_trace_616.trc. Wow, this file is 4005 lines in length just from connecting and executing the following:
SQL> exec get_cust('x'' union select username from all_users where ''x''=''x');
PL/SQL procedure successfully completed.
Searching in the trace for the packet dump we can find the SQL injection attempt sent to the database:
nsprecv: 165 bytes from transport
nsprecv: tlen=165, plen=165, type=6
nsprecv: packet dump
nsprecv: 00 A5 00 00 06 00 00 00 |........|
nsprecv: 00 00 03 5E 35 03 04 00 |...^5...|
nsprecv: 21 00 78 71 DE 00 01 52 |!.xq...R|
nsprecv: BC 39 DE 00 01 0A 00 00 |.9......|
nsprecv: 00 00 E0 39 DE 00 00 01 |...9....|
nsprecv: 01 00 00 00 00 00 00 00 |........|
nsprecv: 00 00 00 00 00 00 00 00 |........|
nsprecv: 00 00 00 00 00 00 00 E2 |........|
nsprecv: 39 DE 00 42 45 47 49 4E |9..BEGIN|
nsprecv: 20 67 65 74 5F 63 75 73 | get_cus|
nsprecv: 74 28 27 78 27 27 20 75 |t('x'' u|
nsprecv: 6E 69 6F 6E 20 73 65 6C |nion sel|
nsprecv: 65 63 74 20 75 73 65 72 |ect user|
nsprecv: 6E 61 6D 65 20 66 72 6F |name fro|
nsprecv: 6D 20 61 6C 6C 5F 75 73 |m all_us|
nsprecv: 65 72 73 20 77 68 65 72 |ers wher|
nsprecv: 65 20 27 27 78 27 27 3D |e ''x''=|
nsprecv: 27 27 78 27 29 3B 20 45 |''x'); E|
nsprecv: 4E 44 3B 0A 00 01 01 01 |ND;.....|
Whilst using SQL*Net trace files are a possibility, there are a number of issues besides the items listed above:
Once again a parser would be needed to extract the SQL text from the packet dumps and to then identify from a set of rules whether the SQL might be a SQL injection attempt.
The PID used as part of the trace file name is not known until the user connects and the shadow process it started. If the filenames were not unique then like snoop the trace could be piped through a filter and the disk usage issue would go away.
The trace files could be monitored regularly with a simple shell script that checks for trace files where there is no longer a shadow process running. These can then be processed and removed. Long running sessions would generate huge trace files and not be ideally managed in this way.
It is easier to determine the OS user and database user involved with SQL*Net traces as this information can be found from the v$process and v$session views with knowledge of the OS PID.
This method is not practical for implementing a simple SQL injection utility in an organisation. The resource issues alone would make it difficult to manage and work with. It could be used sparingly when a suspected incident has occurred and where trace usage could be controlled to a narrow time band or number of clients.