Contents
Overview
During march 2008 the Sampo bank introduced a new java applet based internet bank interface. There are various questionable things about this applet, especially the JNI DLLs shipped with it. The things below are based for the most part on the version available during the evening (Finnish time) of March 25, 2008. No rigorous review of the applet was performed; rather, the findings below are the result of a more casual look at the applet contents.
The link to this page started going around uncontrollably. Visualization of the spreading (based on the access logs) can be seen here: https://www.clarifiednetworks.com/Blog/2009-04-28%2023%3A09
FAQ
Why can I edit this page?
This is a wiki. Feel free to add relevant content. And yes. We monitor this for spam and will be sad if we have to add some access control. We certainly know how it can be done.
General Musings
The approach of moving business logic to the client side is interesting. It was brought to the market with promises of increased security for users. However, the java applet employed in the www-bank makes use of native interfaces, often in seemingly naive ways. These are outlined further below.
The native dll's are provided for 32-bit platforms only. Why native dll's are needed at all seems a good question - one can imagine that Java should suffice for a client applet.
Besides the clueless attempt to "enhance security" by making payment verification happen in a Java applet window, the access to the PC's internals appears to be a badly implemented approach to generate a hardware signature; perhaps to monitor use of multiple accounts? A fraud-management company with name of Iovation does a similar thing using Active-X components for gaming industry uses. It's unclear what benefit this brings to a bank which already requires strong identification, let alone its customers.
Archive Contents
The applet is quite large.
JNI use
1 class dk.danskebank.ec.ec.esafekey.businesslogic.IDFactory {
2 s = getID(Utility.getComponentHome(), new String(abyte0, "ISO-8859-1"), System.getProperty("os.arch"), System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("user.name"), System.getProperty("java.vm.vendor"));
3 private native String getID(String s, String s1, String s2, String s3, String s4, String s5, String s6);
4 private native void isLoaded();
5 }
At http://www.iki.fi/sintonen/src/sampo/sampopcid.c there is a C tool to call the functions in the native dlls. A backup is available at the link below.
Linux DLL
General notes
$ file pcid.dll pcid.dll: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), not stripped
The dll is supplied for 32-bit intel platforms only. It is not stripped.
strings output
Things of note include the following.
Character Strings
/proc/asound/cards /proc/cpuinfo /proc/ide0/hda /proc/ide1/hdc /proc/ide2/hdb /proc/ide3/hdd /proc/ide/hda /proc/ide/hdb /proc/ide/hdc /proc/ide/hdd /proc/meminfo /proc/partitions /proc/pci /proc/sys/kernel/hostname /proc/version
Apparently the applet needs to know about your hostname, hard drives, partitions, kernel version, audio hardware, memory layout, and sound cards. It also looks at the system's pci device list.
model name stepping flags
These seem related to parsing /proc/cpuinfo. It is very precisely figuring out your cpu make.
eth0 eth1 wlanf
Network interface examination.
uname -a > %s whoami > %s hostname > %s
More machine examination. The output is piped somewhere (look below).
%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X
Mac address parsing.
%s/geometry %s/model %s.%s uname -a > %s whoami > %s hostname > %s %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X %2.2s ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
These strings seem to be related to C string handling using sprintf and similar funtions. The string ABCDE... is most likely related to base64 encoding (and maybe decoding).
Symbols
The following symbols seem interesting.
- getALSAId
- getPARTId
- getHDId
- getMAC
- getMEMId
- getCPUId
- getKRNLId
- getUSERId
- getHOST
- SHA256Init
- SHA256Finalize
- SHA256Data
- sha256
- base64Encode
- bLookup
Additionally it seems there is a need to run system commands using the system function, which is generally frowned upon.
attachNeedle
The attachNeedle function especially sounds very interesting. SampoApplet/LinuxDLL/attachNeedleDisassembly.
Traces
The applet does interesting things. Possible usernames have been anonymized below. During an strace of the java vm:
execve("/bin/sh", ["sh"..., "-c"..., "whoami > /home/user/e-Safekey/.120"...], [/* 75 vars */])Notes:
A directory e-Safekey is created in the users home directory without consulting the user
- Calling binaries through the shell is not safe
- Piping the output to files that are later examined opens a window for possible attacks, enabling injection of random (possibly malicious) data.
Mac DLL
General notes
Apparently the MacDLL contains some features that the Linux one does not. It checks for Bluetooth devices, motherboard information such as boot ROM and serial, the graphic chipset information and CPU information.
$ file pcid.dll pcid.dll: Mach-O fat file with 2 architectures
strings output
Character strings
%s/log.txt
A log file for something.
whoami > %s
Same whoami as in Linux version.
system_profiler SPBluetoothDataType > %s Address Firmware Manufacturer
Bluetooth information.
system_profiler SPHardwareDataType > %s Boot ROM Serial
Apparently info about the hardware.
system_profiler SPDisplaysDataType > %s Chipset
Graphic chipset.
system_profiler SPNetworkDataType > %s FireWire
Networking.
machdep.cpu.brand_string machdep.cpu.model machdep.cpu.stepping machdep.cpu.signature machdep.cpu.features machdep.cpu.extfeatures hw.cpufrequency_max hw.cputype hw.cpusubtype hw.model hw.machine hw.memsize hw.l2cachesize
CPU Info.
Symbols
This is a list of the most interesting calls from the strings listing.
- _fetchID
- _getHDID
- _CFUUIDGetConstantUUIDWithBytes
- _CFUUIDGetUUIDBytes
- _getBluetooth
- _getDisplay
- _getFileName
- _getFirewire
- _getJavaSuppliedElement
- _getROMnSerial
- _getUSER
- _logString
- _path
- _getCPU
- _getHOST
- _getKRNL
- _getMAC
- _getMEM
Java Code
Implementation Peculiarities
A decompile of the applet source yields a few interesting discoveries.
File Copying
File copying is achieved by streaming content from one file to another. The effect is quite similar to calling cat file1 > file2 on Unix systems. Why the applet needs to deal with files at all is a good question. Note that file copying is performed one character at a time (instead of copying, for example, 1024 characters on each step) using FileReader and FileWriter. The process is very inefficient and possibly alters the content if the copied file is not a text file represented in the system default character encoding.
1 public static void copyFile(final String source, final String destination)
2 throws Exception
3 {
4 AccessController.doPrivileged(new PrivilegedExceptionAction() {
5
6 public final Object run() throws IOException
7 {
8 File file = new File(source);
9 File file1 = new File(destination);
10 FileReader filereader = new FileReader(file);
11 FileWriter filewriter = new FileWriter(file1);
12 int i;
13 while((i = filereader.read()) != -1)
14 filewriter.write(i);
15 filereader.close();
16 filewriter.close();
17 return null;
18 }
19 });
20 }
Embedded Data
There are some base64 encoded data objects inside the source code. For example several gif images have been located.
getTimeStamp
The binaries include an extremely naive timestamp implementation.
1 public static String getTimeStamp()
2 {
3 Calendar calendar = Calendar.getInstance();
4 String s = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(1)))).toString()).toString(), 4);
5 String s1 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(2) + 1))).toString()).toString(), 2);
6 String s2 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(5)))).toString()).toString(), 2);
7 String s3 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(11)))).toString()).toString(), 2);
8 String s4 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(12)))).toString()).toString(), 2);
9 String s5 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(13)))).toString()).toString(), 2);
10 String s6 = ensureStrLen(Integer.valueOf((new StringBuffer(String.valueOf(calendar.get(14)))).toString()).toString(), 4);
11 return s + "-" + s1 + "-" + s2 + " " + s3 + ":" + s4 + ":" + s5 + ":" + s6;
12 }
Other Interesting Findings
Will not even comment on these.
1 private static String ensureStrLen(String s, int i)
2 {
3 String s1 = s;
4 while (s1.length() < i) s1 = "0" + s1;
5 return s1;
6 }
1 public static final int RandomErrorNotEnoughRandom = 1;
Code Obfuscator
There is a Java code obfuscator included with the applet. The developers apparently forgot to run it.
Apparently obfuscated Classes
In many instances class and file names seem obfuscated. For example:
$ cd iaik/cms $ ls ?.class a.class c.class e.class g.class n.class q.class b.class d.class f.class i.class p.class r.class
1 class iaik.cms.a extends java.lang.Object implements iaik.cms.CertificateIdentifier
2 class iaik.cms.b extends java.util.Vector
3 class iaik.cms.c extends java.lang.Object
4 class iaik.cms.d extends java.lang.Object implements iaik.asn1.ASN1Type
5 class iaik.cms.e extends java.lang.Object implements iaik.cms.KeyIdentifier
6 class iaik.cms.f extends java.lang.Object implements iaik.cms.CertificateIdentifier
7 interface iaik.cms.g
8 class iaik.cms.i extends java.lang.Object implements iaik.cms.InputStreamHashEngine
9 final class iaik.cms.n extends iaik.utils.Factory
10 class iaik.cms.p extends iaik.asn1.structures.Attributes
11 class iaik.cms.q extends java.io.FilterInputStream
12 class iaik.cms.r extends java.lang.Object implements iaik.cms.InputStreamCompressEngine
These classes seem to implement interfaces and extend classes from the IAIK Provider for the Java™ Cryptography Extension (IAIK-JCE) http://jce.iaik.tugraz.at/.
Data Files
props/applet.props
rootCert=<data> domains=.danskebank.lu,.danskebank.dk,.danskebank.se,.danskebank.com,.danskebank .co.uk,.fokus.no,.nationalirishbank.ie,.northernbank.co.uk,.sampopankki.fi,.dani ca.no,.danica.se,.danicapension.dk version=410060 signerName=DBGSIGN textsDA/SE/NO/FI=lots of strings
Double base64-encoded (inner base64 with dos newlines) root certificate
Seems to be invalid ASN.1:
0:d=0 hl=4 l=1093 cons: SEQUENCE
4:d=1 hl=4 l= 813 cons: SEQUENCE
8:d=2 hl=2 l= 3 cons: cont [ 0 ]
10:d=3 hl=2 l= 1 prim: INTEGER :02
13:d=2 hl=2 l= 10 prim: INTEGER :31313131313030303031
25:d=2 hl=2 l= 13 cons: SEQUENCE
27:d=3 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
38:d=3 hl=2 l= 0 prim: NULL
40:d=2 hl=3 l= 196 cons: SEQUENCE
43:d=3 hl=2 l= 16 cons: SET
45:d=4 hl=2 l= 14 cons: SEQUENCE
47:d=5 hl=2 l= 3 prim: OBJECT :commonName
52:d=5 hl=2 l= 7 prim: PRINTABLESTRING :DBGROOT
61:d=3 hl=2 l= 11 cons: SET
63:d=4 hl=2 l= 9 cons: SEQUENCE
65:d=5 hl=2 l= 3 prim: OBJECT :countryName
70:d=5 hl=2 l= 2 prim: PRINTABLESTRING :DK
74:d=3 hl=2 l= 19 cons: SET
76:d=4 hl=2 l= 17 cons: SEQUENCE
78:d=5 hl=2 l= 3 prim: OBJECT :localityName
83:d=5 hl=2 l= 10 prim: PRINTABLESTRING :Copenhagen
95:d=3 hl=2 l= 16 cons: SET
97:d=4 hl=2 l= 14 cons: SEQUENCE
99:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
104:d=5 hl=2 l= 7 prim: PRINTABLESTRING :Denmark
113:d=3 hl=2 l= 26 cons: SET
115:d=4 hl=2 l= 24 cons: SEQUENCE
117:d=5 hl=2 l= 3 prim: OBJECT :organizationName
122:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Danske Bank Group
141:d=3 hl=2 l= 26 cons: SET
143:d=4 hl=2 l= 24 cons: SEQUENCE
145:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
150:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Danske Bank Group
169:d=3 hl=2 l= 24 cons: SET
171:d=4 hl=2 l= 22 cons: SEQUENCE
173:d=5 hl=2 l= 3 prim: OBJECT :serialNumber
178:d=5 hl=2 l= 15 prim: PRINTABLESTRING :611262281100001
195:d=3 hl=2 l= 9 cons: SET
197:d=4 hl=2 l= 7 cons: SEQUENCE
199:d=5 hl=2 l= 3 prim: OBJECT :surname
204:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
206:d=3 hl=2 l= 9 cons: SET
208:d=4 hl=2 l= 7 cons: SEQUENCE
210:d=5 hl=2 l= 3 prim: OBJECT :givenName
215:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
217:d=3 hl=2 l= 9 cons: SET
219:d=4 hl=2 l= 7 cons: SEQUENCE
221:d=5 hl=2 l= 3 prim: OBJECT :title
226:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
228:d=3 hl=2 l= 9 cons: SET
230:d=4 hl=2 l= 7 cons: SEQUENCE
232:d=5 hl=2 l= 3 prim: OBJECT :postalCode
237:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
239:d=2 hl=2 l= 30 cons: SEQUENCE
241:d=3 hl=2 l= 13 prim: UTCTIME :080109120000Z
256:d=3 hl=2 l= 13 prim: UTCTIME :180109120000Z
271:d=2 hl=3 l= 196 cons: SEQUENCE
274:d=3 hl=2 l= 16 cons: SET
276:d=4 hl=2 l= 14 cons: SEQUENCE
278:d=5 hl=2 l= 3 prim: OBJECT :commonName
283:d=5 hl=2 l= 7 prim: PRINTABLESTRING :DBGROOT
292:d=3 hl=2 l= 11 cons: SET
294:d=4 hl=2 l= 9 cons: SEQUENCE
296:d=5 hl=2 l= 3 prim: OBJECT :countryName
301:d=5 hl=2 l= 2 prim: PRINTABLESTRING :DK
305:d=3 hl=2 l= 19 cons: SET
307:d=4 hl=2 l= 17 cons: SEQUENCE
309:d=5 hl=2 l= 3 prim: OBJECT :localityName
314:d=5 hl=2 l= 10 prim: PRINTABLESTRING :Copenhagen
326:d=3 hl=2 l= 16 cons: SET
328:d=4 hl=2 l= 14 cons: SEQUENCE
330:d=5 hl=2 l= 3 prim: OBJECT :stateOrProvinceName
335:d=5 hl=2 l= 7 prim: PRINTABLESTRING :Denmark
344:d=3 hl=2 l= 26 cons: SET
346:d=4 hl=2 l= 24 cons: SEQUENCE
348:d=5 hl=2 l= 3 prim: OBJECT :organizationName
353:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Danske Bank Group
372:d=3 hl=2 l= 26 cons: SET
374:d=4 hl=2 l= 24 cons: SEQUENCE
376:d=5 hl=2 l= 3 prim: OBJECT :organizationalUnitName
381:d=5 hl=2 l= 17 prim: PRINTABLESTRING :Danske Bank Group
400:d=3 hl=2 l= 24 cons: SET
402:d=4 hl=2 l= 22 cons: SEQUENCE
404:d=5 hl=2 l= 3 prim: OBJECT :serialNumber
409:d=5 hl=2 l= 15 prim: PRINTABLESTRING :611262281100001
426:d=3 hl=2 l= 9 cons: SET
428:d=4 hl=2 l= 7 cons: SEQUENCE
430:d=5 hl=2 l= 3 prim: OBJECT :surname
435:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
437:d=3 hl=2 l= 9 cons: SET
439:d=4 hl=2 l= 7 cons: SEQUENCE
441:d=5 hl=2 l= 3 prim: OBJECT :givenName
446:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
448:d=3 hl=2 l= 9 cons: SET
450:d=4 hl=2 l= 7 cons: SEQUENCE
452:d=5 hl=2 l= 3 prim: OBJECT :title
457:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
459:d=3 hl=2 l= 9 cons: SET
461:d=4 hl=2 l= 7 cons: SEQUENCE
463:d=5 hl=2 l= 3 prim: OBJECT :postalCode
468:d=5 hl=2 l= 0 prim: PRINTABLESTRING :
470:d=2 hl=4 l= 288 cons: SEQUENCE
474:d=3 hl=2 l= 13 cons: SEQUENCE
476:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
487:d=4 hl=2 l= 0 prim: NULL
489:d=3 hl=4 l= 269 prim: BIT STRING
762:d=2 hl=2 l= 57 cons: cont [ 3 ]
764:d=3 hl=2 l= 55 cons: SEQUENCE
766:d=4 hl=2 l= 14 cons: SEQUENCE
768:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Key Usage
773:d=5 hl=2 l= 1 prim: BOOLEAN :255
776:d=5 hl=2 l= 4 prim: OCTET STRING [HEX DUMP]:03020106
782:d=4 hl=2 l= 18 cons: SEQUENCE
784:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Basic Constraints
789:d=5 hl=2 l= 1 prim: BOOLEAN :255
792:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:30060101FF020100
802:d=4 hl=2 l= 17 cons: SEQUENCE
804:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Subject Key Identifier
809:d=5 hl=2 l= 10 prim: OCTET STRING [HEX DUMP]:040844424742524F4F54
821:d=1 hl=2 l= 13 cons: SEQUENCE
823:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
834:d=2 hl=2 l= 0 prim: NULL
836:d=1 hl=4 l= 257 prim: BIT STRING
Error in encoding
31849:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:asn1_lib.c:150: