Az alábbi cikket Ys. írta a 0x90 blogon, és mivel a cikksorozata kapcsolódik az iPhone-hoz, mi érdekesnek gondoljuk a számotokra is, így ezeket engedelmével egymás után át is emelnénk ide, a Szifonra.
***
Amikor iOS-es alkalmazások biztonságáról beszélünk, a szexi titkosítási-authentikációs-kriptós témák mellett gyakran elsikkad az, hogy milyen módon védjük a felhasználó az adott alkalmazáshoz tartozó érzékeny adatait. Ugye itt mobil eszközökről beszélünk, ebben a világban abszolút elképzelhető, hogy az eszközt ellopják vagy a felhasználó elveszíti. Igen érdekes kérdés, hogy ilyenkor mi van.
A titkosításról szóló résznél beszéltünk arról, hogy bár a fájlrendszer elviekben minden eleme titkosított valamilyen kulccsal, valódi védelmet csak azok a fájlok kapnak, amiket a fejlesztők bevédenek. Sajnos van egy csomó dolog, ami ellen még ez sem véd – de ne vágjunk a dolgok elébe.
Milyen felhasználói adatokat érdemes védeni? Hát, az attól függ leginkább, hogy mire használják az adott alkalmazást, de mindenképp ide tartoznak a felhasználó authentikációjához szükséges adatok, és némileg tágabb értelmezésben minden olyan információ, ami a felhasználó tevékenységének kifürkészésére lehet alkalmas – szélsőséges esetben támadóként ellopjuk a lezárt, jelszóval védett alkalmazással felszerelt iPadet, varázsolunk kettőt és megszemélyesítjük a júzert, ellopva minden adatát, ami az eszközben van. Na, ilyenkor nem szoktak minket szeretni a fejlesztők. (Kis kitérő: szerintem az a jó betörési tesztelő, akit utálnak a fejlesztők és az üzemeltetők, mint a szart, mert folyton extra munkát generál nekik.)
Szóval, mik azok a vektorok, ahol nyoma marad a felhasználói tevékenységnek? Lássunk párat.
Automatikus screenshotok
Amikor megnyomod A Gombot az eszköz előlapján és visszamész a home screenre, akkor az iOS csinál automatikusan egy screenshotot, amit kitesz arra a háromtized másodpercre, amíg visszatölti az appot, ha előveszed megint. Ez tök jó, viszont ugye az így elkészült kép megtaláható plain-textben az alkalmazás könyvtárában még úgy is, hogy le van zárva a screen lock az iOS felületéhez. Ez nem jó. Sőt a HFS journal végigtúrásával további screenshotokat is ki lehet szitálni.
white-iPhone: ~# pwd
/var/mobile/Applications/6941BAF6-6968-457A-A227-6EC24D1A70AB/Library/Caches/Snapshots/com.rememberthemilk.mobilertm
white-iPhone: ~# ls
UIApplicationAutomaticSnapshotDefault-Portrait@2x.jpg
Ez így fícsör, nem bug, de legalább kezelni lehet a hatását – az Apple ugyanis az AppDelegate események közé bevette azt, hogy “achtung! Az appodat háttérbe fogják tenni!” – ezt az eseményt ki lehet használni arra, hogy letakarítsuk a képernyőt, mielőtt a screenshot elkészül. Figyelni érdemes azonban arra, hogy két ilyen jellegű esemény is van: az egyik az applicationWillResignActive:, a másik az applicationDidEnterBackground:.
SQLite rekordok
Az SQLite-ot szeretjük, mert önleíró, platformfüggetlen és maceramentes tárolási mód akár közepes mennyiségű adatra is. Arról viszont kevés iFejlesztő tud, hogy nem olyan egyszerű ám törölni belőle, mert mivel az egész adatbázis egy fájl, egy kulccsal van titkosítva és a NAND flash tulajdonságai miatt meglepően kevésszer lehet újraírni. Az asztali gépekre kitalált sqlite3 kliens lecsatlakozáskor kipucolja maga után a törölt rekordokat, viszont az iPhone-os nem (és az sqlite API sem). Csináljunk pl. egy sqlite adatbázist:
white-iPhone:~ root# sqlite3 bela.sqlite
SQLite version 3.7.2
Enter “.help” for instructions
sqlite> create table adat(
…> ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
…> rekord TEXT
…> );
sqlite> insert into adat(rekord) values(‘hello’);
sqlite> insert into adat(rekord) values(‘hellobello’);
sqlite> insert into adat(rekord) values(‘hellobello’);
sqlite> insert into adat(rekord) values(‘hellobello’);
sqlite> insert into adat(rekord) values(‘helloka’);
sqlite> .quit
Nézzük meg a bela.sqlite-ban lévő stringeket:
white-iPhone:~ root# strings bela.sqlite
SQLite format 3
Ytablesqlite_sequencesqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)^
tableadatadat
CREATE TABLE adat(
ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
rekord TEXT
helloka
!hellobello
!hellobello
!hellobello
hello
adat
Remek, nem is vártunk mást. Töröljünk most egy merészet.
white-iPhone:~ root# sqlite3 bela.sqlite
SQLite version 3.7.2
Enter “.help” for instructions
sqlite> delete from adat where rekord = ‘hellobello’;
sqlite> .dump
BEGIN TRANSACTION;
CREATE TABLE adat(
ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
rekord TEXT
);
INSERT INTO “adat” VALUES(1,’hello’);
INSERT INTO “adat” VALUES(5,’helloka’);
DELETE FROM sqlite_sequence;
INSERT INTO “sqlite_sequence” VALUES(‘adat’,5);
COMMIT;
Viszont…
white-iPhone:~ root# strings bela.sqlite
SQLite format 3
Ytablesqlite_sequencesqlite_sequence
CREATE TABLE sqlite_sequence(name,seq)^
tableadatadat
CREATE TABLE adat(
ROWID INTEGER PRIMARY KEY AUTOINCREMENT,
rekord TEXT
helloka
-!hellobello
!hellobello
!hellobello
hello
adat
Ez ellen többféleképp is lehet védekezni. Több helyen láttam már, hogy bekapcsolják az auto_vacuum=FULL módot, viszont ezzel az a probléma, hogy nem defragmentálja az adatbázist, így a törölt részek még mindig visszanyerhetőek. Az egyik működő megoldás az, hogy nem használunk sqlite-ot, csak ahol feltétlenül szükséges és nem írjuk ki az érzékeny adatokat a tárolóra. Jó, igaz, ez nem megoldja a problémát, hanem elkerüli – egy lehetséges megoldás, hogy törlés előtt egy UPDATE paranccsal átütjük a vonatkozó stringeket (legalább olyan hosszan, mint az eredeti stringek voltak). Lehetséges manuálisan is kiadni a VACUUM parancsot, viszont ez az egész adatbázist újjáépíti, emiatt eléggé erőforrásintenzív művelet és ez nem tesz jót a felhasználói élménynek.
No comment yet, add your voice below!