บทนำ (Overview)
ในบทความนี้เราจะวิเคราะห์ถึงข้อมูลในหน่วยความจำ (Memory) ของโปรแกรมที่เขียนบน “iOS” กัน ซึ่งบางที่แล้วข้อมูลเช่น “username” “password” “OTP” “pincode” หรือ “session” เมื่อใช้งานเสร็จสิ้นก็ควรลบออกจากหน่วยความจำให้เรียบร้อย
ขั้นตอน (Step)
- เครื่อง “iOS” ต้องผ่านการ Jailbreak เสียก่อน (How to jailbreak iOS – “PP Jailbreak”)
- ติดตั้งโปรแกรม “DVIA” จากนั้นไปที่รายการ “Sensitive information in memory”
- สำหรับโปแกรมทั่วไปที่ดาวน์โหลดมาจาก “App Store” ให้ทำการ “Decrypt” เสียก่อน (http://blog.itselectlab.com/?p=565) แล้วติดตั้งโปรแปรมที่ “Decrypt” ใหม่อีกครั้ง
- เมื่อทำการ “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
- “Remote Access” ผ่าน “SSH”
- เมื่อได้ชื่อ “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
- และมีตัวแปรที่น่าสนใจคือ “NSString* _username;” และ “NSString* _password;” และ “@property”ที่น่าจะเกี่ยวข้องกับตัวแปรดังกล่าวดังข้างล่าง
@property(retain, nonatomic) NSString* password; @property(retain, nonatomic) NSString* username;
- จากนั้นเราลองใช้โปรแกรม “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
- เข้าถึง “Address” ของหน้า “UIViewController” ของการ “Login” (ซึ่งตอนนี้อยู่ตามรูปในขั้นตอนที่ 2)
cy# UIApp.keyWindow.rootViewController.topViewController.visibleViewController #"<SensitiveInformationDetailsVC: 0x160dd3f0>" cy# test = #0x160dd3f0 #"<SensitiveInformationDetailsVC: 0x160dd3f0>" cy# test #"<SensitiveInformationDetailsVC: 0x160dd3f0>"
- จากนั้นลองตรวจสอบค่าที่บรรจุอยู่ในตัวแปร
- วิธีที่ 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"
- วิธีที่ 1: ผ่าน Property