How to find the sensitive information in memory

บทนำ (Overview)

ในบทความนี้เราจะวิเคราะห์ถึงข้อมูลในหน่วยความจำ (Memory)  ของโปรแกรมที่เขียนบน “iOS” กัน ซึ่งบางที่แล้วข้อมูลเช่น “username” “password” “OTP” “pincode” หรือ “session” เมื่อใช้งานเสร็จสิ้นก็ควรลบออกจากหน่วยความจำให้เรียบร้อย




ขั้นตอน (Step)

  1.  เครื่อง “iOS” ต้องผ่านการ Jailbreak เสียก่อน (How to jailbreak iOS – “PP Jailbreak”)
  2. ติดตั้งโปรแกรม “DVIA” จากนั้นไปที่รายการ “Sensitive information in memory” sensitiveinformation2
  3. สำหรับโปแกรมทั่วไปที่ดาวน์โหลดมาจาก “App Store” ให้ทำการ “Decrypt” เสียก่อน (http://blog.itselectlab.com/?p=565) แล้วติดตั้งโปรแปรมที่ “Decrypt” ใหม่อีกครั้ง
  4. เมื่อทำการ “Decrypt” โปรแกรมเรียบร้อยเราจึงสามารถ “Reverse Engineer” โปรแกรมได้ (อ่าน “Class” หรือ “Method” ออก ตามบทความ http://blog.itselectlab.com/?p=350) แต่สำหรับโปรแกรม “DVIA” ไม่ได้มาจาก “App Store” ดังนั้นจึงข้ามขั้นตอนที่ (3) ไปได้ดังนี้
    • “Remote Access” ผ่าน “SSH”
      login as: root
      root@192.168.0.15's password:
      iPad:~ root# ls -l
      total 112
      drwxr-xr-x 3 root wheel   102 Oct 23  2014 Documents/
      drwxr-xr-x 8 root wheel   272 Oct  9  2014 Library/
      drwxr-xr-x 3 root wheel   102 Oct 24  2014 Media/
      -rw-r--r-- 1 root wheel 82904 Oct 10  2014 dumpdecrypted.dylib
      -rwxrwxrwx 1 root wheel 25744 Oct 10  2014 keychain_dumper*
      
    • ค้นหา “Directory” สำหรับโปรแกรม “DVIA”
      iPad:~ root# cd /var/mobile/Applications/
      iPad:/var/mobile/Applications root# ps aux | grep Damn
      mobile     783   0.0 13.3   517264  68372   ??  Ss   10:10AM   0:31.21 /var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp
      iPad:/var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerabl        eIOSApp.app root# ls -l
      total 21128
      -rw-r--r-- 1 mobile mobile    11553 May 24 04:16 120x120.png
      -rw-r--r-- 1 mobile mobile    13907 May 24 04:16 152x152.png
      -rw-r--r-- 1 mobile mobile     6525 May 24 04:16 57x57.png
      -rw-r--r-- 1 mobile mobile   375699 May 24 04:16 640_960_SplashScn.png
      -rw-r--r-- 1 mobile mobile   464522 May 24 04:16 640x1136_SplashScn.png
      -rw-r--r-- 1 mobile mobile     7893 May 24 04:16 72x72.png
      -rw-r--r-- 1 mobile mobile     8464 May 24 04:16 76x76.png
      -rw-r--r-- 1 mobile mobile    11292 May 24 04:16 AppIcon40x40\@2x.png
      -rw-r--r-- 1 mobile mobile    11553 May 24 04:16 AppIcon60x60\@2x.png
      drwxr-xr-x 3 mobile mobile      102 May 24 04:16 Base.lproj/
      -rwxr-xr-x 1 mobile mobile 19509584 May 24 04:17 DamnVulnerableIOSApp*
      -rw-r--r-- 1 mobile mobile     1427 May 24 04:16 Info.plist
      -rwxr-xr-x 1 mobile mobile     1341 May 24 04:16 LICENSE.txt*
      -rw-r--r-- 1 mobile mobile   464522 May 24 04:16 LaunchImage-700-568h\@2x.png
      -rw-r--r-- 1 mobile mobile   375699 May 24 04:16 LaunchImage-700\@2x.png
      drwxr-xr-x 2 mobile mobile       68 May 24 04:16 META-INF/
      drwxr-xr-x 2 mobile mobile      136 May 24 04:16 Model.momd/
      -rw-r--r-- 1 mobile mobile        8 May 24 04:16 PkgInfo
      drwxr-xr-x 3 mobile mobile      102 May 24 04:16 PlugIns/
      -rwxr-xr-x 1 mobile mobile      324 May 24 04:16 README.txt*
      drwxr-xr-x 2 mobile mobile      102 May 24 04:16 _CodeSignature/
      -rw-r--r-- 1 mobile mobile     4030 May 24 04:16 card-bg.png
      -rw-r--r-- 1 mobile mobile     2006 May 24 04:16 card-bg\@2x.png
      -rw-r--r-- 1 mobile mobile     8081 May 24 04:16 embedded.mobileprovision
      drwxr-xr-x 2 mobile mobile      102 May 24 04:16 en.lproj/
      -rw-r--r-- 1 mobile mobile     1150 May 24 04:16 google.co.uk.cer
      -rw-r--r-- 1 mobile mobile     2927 May 24 04:16 header-bg.png
      -rw-r--r-- 1 mobile mobile     3155 May 24 04:16 header-bg\@2x.png
      -rw-r--r-- 1 mobile mobile     4840 May 24 04:16 main-bg.png
      -rw-r--r-- 1 mobile mobile     5424 May 24 04:16 main-bg\@2x.png
      -rw-r--r-- 1 mobile mobile     3789 May 24 04:16 menu-icon.png
      -rw-r--r-- 1 mobile mobile     5006 May 24 04:16 menu-icon\@2x.png
      -rw-r--r-- 1 mobile mobile     3922 May 24 04:16 menuIcon.png
      -rw-r--r-- 1 mobile mobile     5388 May 24 04:16 menuIcon\@2x.png
      -rw-r--r-- 1 mobile mobile     2941 May 24 04:16 slider-active.png
      -rw-r--r-- 1 mobile mobile     3133 May 24 04:16 slider-active\@2x.png
      -rw-r--r-- 1 mobile mobile    74035 May 24 04:16 slider-bg.png
      -rw-r--r-- 1 mobile mobile   176841 May 24 04:16 slider-bg\@2x.png
      
    • ใช้คำสั่ง “class-dump-z ชื่อโปรแกรม > ชื่อไฟล์ที่ต้องการบันทึก” เพื่อ “Reverse Engineering”
      iPad:/var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerableIOSApp.app root# class-dump-z  DamnVulnerableIOSApp > zTest.txt
      iPad:/var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerableIOSApp.app root# ls -l
      total 21764
      -rw-r--r-- 1 root   mobile   649319 Jun 29 14:12 zTest.txt
      
    • ทดสอบเปิดอ่าน “Class” “Method” และ “Properties”
      iPad:/var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerableIOSApp.app root# cat zTest.txt
      @interface RLMRealm : NSObject {
              BOOL _inWriteTransaction;
              unsigned _threadID;
      @private
              NSThread* _thread;
              NSMapTable* _notificationHandlers;
              unique_ptr<tightdb::Replication, std::__1::default_delete<tightdb::Replication> > _replication;
              unique_ptr<tightdb::SharedGroup, std::__1::default_delete<tightdb::SharedGroup> > _sharedGroup;
              unique_ptr<tightdb::Group, std::__1::default_delete<tightdb::Group> > _readGroup;
              Group* _group;
              BOOL _readOnly;
              BOOL _inMemory;
              BOOL _autorefresh;
              BOOL _dynamic;
              NSString* _path;
              RLMSchema* _schema;
      }
      @property(readonly, assign, nonatomic, getter=getOrCreateGroup) Group* group;
      @property(readonly, assign, nonatomic) BOOL dynamic;
      @property(readonly, assign, nonatomic) BOOL inWriteTransaction;
      @property(assign, nonatomic) BOOL autorefresh;
      @property(retain, nonatomic) RLMSchema* schema;
      @property(readonly, assign, nonatomic, getter=isReadOnly) BOOL readOnly;
      @property(readonly, assign, nonatomic) NSString* path;
      +(id)migrateRealmAtPath:(id)path key:(id)key;
      +(id)migrateRealmAtPath:(id)path encryptionKey:(id)key;
      +(id)migrateRealmAtPath:(id)path;
      +(unsigned)schemaVersionAtPath:(id)path encryptionKey:(id)key error:(id*)error;
      +(unsigned)schemaVersionAtPath:(id)path error:(id*)error;
      +(void)setSchemaVersion:(unsigned)version forRealmAtPath:(id)path withMigrationBlock:(id)migrationBlock;
      +(void)setDefaultRealmSchemaVersion:(unsigned)version withMigrationBlock:(id)migrationBlock;
      +(void)resetRealmState;
      +(void)setEncryptionKey:(id)key forRealmsAtPath:(id)path;
      +(id)realmWithPath:(id)path key:(id)key readOnly:(BOOL)only inMemory:(BOOL)memory dynamic:(BOOL)dynamic schema:(id)schema error:(id*)error;
      +(id)realmWithPath:(id)path encryptionKey:(id)key readOnly:(BOOL)only error:(id*)error;
      +(id)inMemoryRealmWithIdentifier:(id)identifier;
      +(id)realmWithPath:(id)path readOnly:(BOOL)only error:(id*)error;
      +(id)realmWithPath:(id)path;
      +(id)defaultRealm;
      +(id)writeablePathForFile:(id)file;
      +(void)setDefaultRealmPath:(id)path;
      +(id)defaultRealmPath;
      +(void)initialize;
      +(BOOL)isCoreDebug;
      -(id).cxx_construct;
      -(void).cxx_destruct;
      -(BOOL)writeCopyToPath:(id)path encryptionKey:(id)key error:(id*)error;
      -(BOOL)writeCopyToPath:(id)path error:(id*)error;
      -(BOOL)writeCopyToPath:(id)path key:(id)key error:(id*)error;
      -(id)createObject:(id)object withObject:(id)object2;
      -(id)objects:(id)objects withPredicate:(id)predicate;
      -(id)objects:(id)objects where:(id)where args:(void*)args;
      -(id)objects:(id)objects where:(id)where;
      -(id)allObjects:(id)objects;
      -(void)deleteAllObjects;
      -(void)deleteObjects:(id)objects;
      -(void)deleteObject:(id)object;
      -(void)addOrUpdateObjectsFromArray:(id)array;
      -(void)addOrUpdateObject:(id)object;
      -(void)addObjects:(id)objects;
      -(void)addObject:(id)object;
      -(BOOL)refresh;
      -(void)handleExternalCommit;
      -(void)dealloc;
      -(void)invalidate;
      -(void)cancelWriteTransaction;
      -(void)transactionWithBlock:(id)block;
      -(void)commitWriteTransaction;
      -(void)beginWriteTransaction;
      -(void)sendNotifications:(id)notifications;
      -(void)removeNotification:(id)notification;
      -(id)addNotificationBlock:(id)block;
      -(id)migrationBlock:(id)block;
      -(id)initWithPath:(id)path key:(id)key readOnly:(BOOL)only inMemory:(BOOL)memory dynamic:(BOOL)dynamic error:(id*)error;
      @end
      
  5. เมื่อได้ชื่อ “Class” เรียบร้อยแล้ว จากนั้นช่วงเวลานี้อาจจะต้องลองศึกษาจากชื่อ “Class” “Method” หรือ “Properties” ที่เกี่ยวข้องกับช่องโหว่ที่เป็นไปได้ว่าจะมี ในตอนนี้เรากำลังหาช่องโหว่เกี่ยวกับการ “Sensitive information” “username” และ “password” จึงลองค้นหาคำที่อาจที่เกี่ยวข้องดังกล่าว น่าจะเกี่ยวข้องกับ “Class” ข้างล่าง
    @interface SensitiveInformationDetailsVC : UIViewController {
    @private
    	NSString* _username;
    	NSString* _password;
    }
    @property(retain, nonatomic) NSString* password;
    @property(retain, nonatomic) NSString* username;
    -(void).cxx_destruct;
    -(void)didReceiveMemoryWarning;
    -(void)initializeLogin;
    -(void)viewDidLoad;
    @end
    
  6. และมีตัวแปรที่น่าสนใจคือ “NSString* _username;” และ “NSString* _password;” และ “@property”ที่น่าจะเกี่ยวข้องกับตัวแปรดังกล่าวดังข้างล่าง
    @property(retain, nonatomic) NSString* password;
    @property(retain, nonatomic) NSString* username;
    
  7. จากนั้นเราลองใช้โปรแกรม “Cycript” เชื่อมต่อ process ของโปรแกรม “DVIA” ที่กำลัง “Run” อยู่ดังนี้ (http://blog.itselectlab.com/?p=95)
    iPad:~ root# ps aux | grep Damn
    mobile 1274 0.0 16.3 532304 84068 ?? Ss 10:30PM 0:23.18 /var/mobile/Applications/BD0BBE00-2C62-4533-B7C4-D8B46D1EF4C5/DamnVulnerableIOSApp.app/DamnVulnerableIOSApp
    root 1364 0.0 0.1 339588 428 s001 R+ 8:32AM 0:00.01 grep Damn
    iPad:~ root# cycript -p 1274
    
  8. เข้าถึง “Address” ของหน้า “UIViewController” ของการ “Login” (ซึ่งตอนนี้อยู่ตามรูปในขั้นตอนที่ 2)
    cy# UIApp.keyWindow.rootViewController.topViewController.visibleViewController
    #"<SensitiveInformationDetailsVC: 0x160dd3f0>"
    cy# test = #0x160dd3f0
    #"<SensitiveInformationDetailsVC: 0x160dd3f0>"
    cy# test
    #"<SensitiveInformationDetailsVC: 0x160dd3f0>"
    
  9. จากนั้นลองตรวจสอบค่าที่บรรจุอยู่ในตัวแปร
    • วิธีที่ 1: ผ่าน Property
      cy# test.username
      @"Bobby"
      cy# test.password
      @"P2ssw0rd"
      
    • วิธีที่ 2: ผ่าน Property
      cy# [test username]
      @"Bobby"
      cy# [test password]
      @"P2ssw0rd"
      
    • วิธีที่ 3: ผ่านตัวแปร
      cy# test->_username
      @"Bobby"
      cy# test->_password
      @"P2ssw0rd"
      

ใส่ความเห็น