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:
1 | [oracle@rokoko ~]$ cat .bash_profile | grep go |
3 | PATH=$PATH:/usr/ local /go/bin:$GOPATH/bin |
After installing GoLang you can do the following to compile my tool:
1 | [oracle@rokoko ~]$ mkdir -p ~/go/src/github.com/ghetzel |
2 | [oracle@rokoko ~]$ mkdir -p ~/go/src/github.com/ora600pl |
3 | [oracle@rokoko ~]$ cd ~/go/src/github.com/ghetzel |
4 | [oracle@rokoko ghetzel]$ git clone https://github.com/ghetzel/shmtool |
5 | Cloning into 'shmtool' ... |
6 | remote: Counting objects: 92, done . |
7 | remote: Total 92 (delta 0), reused 0 (delta 0), pack-reused 92 |
8 | Unpacking objects: 100% (92/92), done . |
9 | [oracle@rokoko ghetzel]$ cd ~/go/src/github.com/ora600pl |
10 | [oracle@rokoko ora600pl]$ git clone https://github.com/ora600pl/sgadump |
11 | Cloning into 'sgadump' ... |
12 | remote: Counting objects: 9, done . |
13 | remote: Compressing objects: 100% (7/7), done . |
14 | remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0 |
15 | Unpacking objects: 100% (9/9), done . |
16 | [oracle@rokoko ora600pl]$ cd sgadump/ |
17 | [oracle@rokoko sgadump]$ ls |
19 | [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:
1 | [oracle@rokoko sgadump]$ sgadump |
2 | sgadump by Kamil Stawiarski (@ora600pl) - dumps database blocks from SGA. |
3 | 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:
1 | SQL> sho parameters memory_target |
4 | ------------------------------------ ----------- ------------------------------ |
5 | memory_target big integer 0 |
6 | SQL> sho parameters sga_target |
9 | ------------------------------------ ----------- ------------------------------ |
10 | 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? 🙂
1 | SQL> alter system flush buffer_cache; |
5 | SQL> select data_object_id |
7 | 3 where object_name= 'EMPLOYEES' |
14 | SQL> select dbms_rowid.rowid_block_number(rowid) as bno, count (1) |
16 | 3 group by dbms_rowid.rowid_block_number(rowid); |
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.
1 | [oracle@rokoko sgadump]$ ipcs -m |
3 | ------ Segmenty pamięci dzielonej ---- |
4 | klucz id_shm właściciel uprawn. bajtów podłączeń stan |
5 | 0x00000000 262144 oracle 600 8622080 116 |
6 | 0x00000000 294913 oracle 600 1157627904 58 |
7 | 0x00000000 327682 oracle 600 8155136 58 |
8 | 0x91a6a268 360451 oracle 600 8192 58 |
9 | [oracle@rokoko sgadump]$ sgadump -b 8192 -d 73865 -s 294913 -o emps |
10 | shmid = 294913 size is 1157627904, blocks = 141312 |
11 | 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.
1 | [oracle@rokoko ~]$ cat listfile.rico2 |
2 | 1 /home/oracle/go/src/github.com/ora600pl/sgadump/emps |
3 | 2 /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf |
4 | [oracle@rokoko ~]$ python rico2.py listfile.rico2 |
5 | RICO v2 by Kamil Stawiarski (@ora600pl | www.ora-600.pl) |
6 | This is open source project to map BBED functionality. |
7 | If you know how to use BBED, you will know how to use this one. |
8 | Not everything is documented but in most cases the code is trivial to interpret it. |
9 | So if you don't know how to use this tool - then maybe you shouldn't ;) |
11 | Usage: python2.7 rico2.py listfile.txt |
12 | The listfile.txt should contain the list of the DBF files you want to read |
16 | This tool should be used only to learn or in critical situations! |
17 | The usage is not supported! |
18 | If found on production system, this software should be considered as malware and deleted immediately! |
20 | 1 /home/oracle/go/src/github.com/ora600pl/sgadump/emps |
21 | 2 /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf |
23 | DBA 0x800083 (8388739 2,131) |
25 | File: /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf(2) |
26 | Block: 131 Dba: 0x800083 |
27 | ------------------------------------------------------------ |
28 | Wrong kind of block. Currently supported: 6.1 |
31 | File: /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf(2) |
32 | Block: 131 Offsets: 0 to 512 Dba: 0x800083 |
33 | --------------------------------------------------------------- |
34 | 06a20000 83004001 1f6d1900 00000114 | ......@..m...... |
35 | c2d40000 b64bd34f 98dcff3f 23d0c822 | .....K.O...?#.." |
36 | ba1b1249 8e0d572f 740b8db7 f7fd6a15 | ...I..W/t.....j. |
37 | 679856ef a61c8130 896c0066 cd6b7a45 | g.V....0.l.f.kzE |
38 | b3751eb2 b40cdeb6 8f16bbdf f9b4f53d | .u.............= |
39 | 50199851 dbe0dde9 5688576b 9e9df4a0 | P..Q....V.Wk.... |
40 | 0f481d54 b36b746f b98f6a21 0d13fb51 | .H.T.kto..j!...Q |
41 | 489b7825 4e94fd05 d2bbe1ce 7b117069 | H.x%N.......{.pi |
42 | 38c5ab56 e4ae4a77 2ff41926 5bb135d7 | 8..V..Jw/..&[.5. |
43 | b4432e7a 630ca876 a52f5905 31ddcc10 | .C.zc..v./Y.1... |
44 | dfcb778a 4573f718 44c1bb9d f89ab735 | ..w.Es..D......5 |
45 | 3518bf50 be236042 c49efe31 c72865dc | 5..P.#`B...1.(e. |
46 | 88827881 6c6ce355 2b14f312 bf9119af | ..x.ll.U+....... |
47 | 5f53c4c5 7fd4c1a7 ac29c784 1c124019 | _S......)....@. |
48 | 46098a1e 42dd8b48 640b777b 49f20b58 | F...B..Hd.w{I..X |
49 | 0cfd6491 cff43be9 a48013bc d336796b | ..d...;......6yk |
50 | 7b3a2a3b 513dee44 8f7a5d6d 948c9d54 | {:*;Q=.D.z]m...T |
51 | 7decaea7 37f35331 4b1a36a2 0fcd0c70 | }...7.S1K.6....p |
52 | 4e83beae 72e03920 c7a218ba f4cb17e4 | N...r.9 ........ |
53 | d10d09f8 bb3e5aa4 be827849 b4b9522e | .....>Z...xI..R. |
54 | 0c171483 fce82a0c 64b184da 7da1ef73 | ......*.d...}..s |
55 | 8cd53b7b 66e46885 8855018a babb6669 | ..;{f.h..U....fi |
56 | e1a79636 b66210d7 c27b6f43 43929a58 | ...6.b...{oCC..X |
57 | 915d44bf e6efe9d0 845c4c97 3c25d5fa | .]D......\L.<%.. |
58 | 29d90c7d 11fe47f7 73213529 8c75a98b | )..}..G.s!5).u.. |
59 | cd30d13f a76adf74 c2bfe501 ec853a74 | .0.?.j.t......:t |
60 | 605f6641 b57c9a85 614d28f8 75c2253f | `_fA.|..aM(.u.%? |
61 | 7dfcb3d8 7bcc1386 ab40d7e1 7a37b999 | }...{....@..z7.. |
62 | f9837dc3 c5073575 9181feaf 038ae706 | ..}...5u........ |
63 | c344ff1d 075b3b6b 7c07b118 3a88a3fd | .D...[;k|...:... |
64 | 23bb4a29 7170a48a 975818b7 21ce08a9 | #.J)qp...X..!... |
As you can see I can’t read the encrypted block in a datafile. But let’s check the dump from SGA:
2 | DBA 0x400000 (4194304 1,0) |
4 | File: /home/oracle/go/src/github.com/ora600pl/sgadump/emps(1) |
6 | ------------------------------------------------------------ |
9 | struct kcbh, 20 bytes @0 |
11 | struct ktbbh, 96 bytes @20 |
13 | struct kdbh, 14 bytes @124 |
15 | struct kdbt[1], 4 bytes @138 |
19 | ub1 freespace[7406] @160 |
21 | ub1 rowdata[622] @7566 |
27 | rowdata[549] @8115 0x2c |
35 | col 1[6] @8122: 446f6e616c64 |
36 | col 2[8] @8129: 4f436f6e6e656c6c |
37 | col 3[8] @8138: 444f434f4e4e454c |
38 | col 4[12] @8147: 3635302e3530372e39383333 |
39 | col 5[7] @8160: 786b0615010101 |
40 | col 6[8] @8168: 53485f434c45524b |
47 | rico2 > x /rncccctcnnnn |
48 | rowdata[549] @8115 0x2c |
55 | col 0[3] @8118: c20263 198 |
56 | col 1[6] @8122: 446f6e616c64 Donald |
57 | col 2[8] @8129: 4f436f6e6e656c6c OConnell |
58 | col 3[8] @8138: 444f434f4e4e454c DOCONNEL |
59 | col 4[12] @8147: 3635302e3530372e39383333 650.507.9833 |
60 | col 5[7] @8160: 786b0615010101 2007-06-21:00:00:00 |
61 | col 6[8] @8168: 53485f434c45524b SH_CLERK |
62 | col 7[2] @8177: c21b 2600 |
64 | col 9[3] @8181: c20219 124 |
65 | 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.