本篇内容介绍了“怎么使用radare2逆向iOS Swift应用程序”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
0x01 前言
使用 radare2 逆向 iOS Swift 应用程序,我们将使用iGoat应用程序。我们的目标是反编译iOS Swift应用程序的外观。这是以前iGoat Objective C项目的Swift版本。使用OWASP iGoat,您可以学习iOS Swift应用程序中的漏洞。
KeychainExerciseVC.swift
class KeychainExerciseVC: UIViewController { @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! override func viewDidLoad() { super.viewDidLoad() secureStore(userName: "iGoat", password: "taoGi") } func secureStore(userName: String, password: String) { do { // This is a new account, create a new keychain item with the account name. let passwordItem = KeychainPasswordItem(service: "SaveUser", account: userName, accessGroup: nil) // Save the password for the new item. try passwordItem.savePassword(password) } catch { fatalError("Error updating keychain - /(error)") } }
一旦viewDidLoad()
被调用,它会调用secureStore与userName: "iGoat"
和password: "taoGi"
。我们研究的目的就是了解这些方法在反汇编中是什么样子的。
准备开始
在我们开始之前,我们必须减少二进制文件体积。这可以使用radare2的rabin2完成:
$ cd Payload/iGoat-Swift.app $ rabin2 -x iGoat-Swift
这将创建一个包含两个二进制文件(32/64位)的文件夹iGoat-Swift.fat/
,打开32位二进制,进行分析,并启用字符串模拟:
$ r2 -e bin.demanglecmd=true -e emu.str=true iGoat-Swift.fat/iGoat-Swift.arm_32.0 [0x000bfe60]> aaaa
让我们看看我们可以找到关于二进制各部分中的swift的内容:
iS~swift 09 0x0022f400 10501 0x00233400 10501 -r-x 9.__TEXT.__swift3_typeref 10 0x00231d08 456 0x00235d08 456 -r-x 10.__TEXT.__swift3_assocty 11 0x00231ed0 656 0x00235ed0 656 -r-x 11.__TEXT.__swift2_proto 12 0x00232160 3284 0x00236160 3284 -r-x 12.__TEXT.__swift3_fieldmd 13 0x00232e34 60 0x00236e34 60 -r-x 13.__TEXT.__swift3_builtin 14 0x00232e70 2772 0x00236e70 2772 -r-x 14.__TEXT.__swift3_reflstr 16 0x002339ec 1552 0x002379ec 1552 -r-x 16.__TEXT.__swift3_capture
我们当前的方法不是很好(仅使用r2检查二进制,仅静态方法),我们不能指望在反汇编中找到很多东西。 我们将在以后的学习中了解如何获取更多信息(小小剧透:也涉及r2)。我们假装我们没有看到源代码,因为我们现在就是在做“Keychain Exercise”。输入ic?
$ r2 -- -- Radare2, what else? [0x00000000]> ic? | ic List classes, methods and fields | icc List classes, methods and fields in Header Format
检查classes
首先我们来看看这些类:
ic~+class | grep iGoat ... 0x00281678 [0x000efe48 - 0x000f0378] (sz 1328) class 0 iGoat_Swift.HTMLViewController 0x002816b0 [0x000f4b48 - 0x000f4d60] (sz 536) class 0 iGoat_Swift.CenterContainmentSegue 0x002816c8 [0x000f4f68 - 0x000f5578] (sz 1552) class 0 iGoat_Swift.KeychainExerciseVC 0x002816ec [0x000f86bc - 0x000f8a6c] (sz 944) class 0 iGoat_Swift.CutAndPasteExerciseVC 0x00281704 [0x000f8bf0 - 0x000f92c4] (sz 1748) class 0 iGoat_Swift.BinaryPatchingVC 0x00281720 [0x000f94e4 - 0x000f9fa8] (sz 2756) class 0 iGoat_Swift.URLSchemeAttackExerciseVC ...
我们可以iGoat_Swift.KeychainExerciseVC
在地址中找到0x002816c8
。
检查flags
另一种选择是查看flags(f
)和grep(~
)case insensitive(+
)Keychain
:
[0x00044798]> f~+Keychain 0x001f2330 38 str.TtC11iGoat_Swift18KeychainExerciseVC ... 0x001f2450 26 str.Error_updating_keychain 0x001f4ccf 52 str.Unexpected_error__d_deleting_identity_from_keychain 0x001f801a 49 str.CBLOpenIDConnectAuthorizer_keychainAttributes 0x001f80fd 34 str.:_No_ID_token_found_in_Keychain 0x001f8170 32 str.:_Read_ID_token_from_Keychain ... 0x002816c8 1 class.iGoat_Swift.KeychainExerciseVC 0x000f4f68 1 method.iGoat_Swift.KeychainExerciseVC.usernameTextField 0x000f4f8c 1 method.iGoat_Swift.KeychainExerciseVC.setUsernameTextField: 0x000f4fa4 1 method.iGoat_Swift.KeychainExerciseVC.passwordTextField 0x000f4fc8 1 method.iGoat_Swift.KeychainExerciseVC.setPasswordTextField: 0x000f4fe0 1 method.iGoat_Swift.KeychainExerciseVC.viewDidLoad 0x000f5094 1 method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender: 0x000f5290 368 method.iGoat_Swift.KeychainExerciseVC.initWithNibName:bundle: 0x000f5578 1 method.iGoat_Swift.KeychainExerciseVC.initWithCoder:
我们再次看到iGoat_Swift.KeychainExerciseVC
地址中的类0x002816c8
。
class信息
我们还可以获得有关此class的完整信息:
[0x00044f44]> ic iGoat_Swift.KeychainExerciseVC class iGoat_Swift.KeychainExerciseVC 0x000f4f68 method iGoat_Swift.KeychainExerciseVC usernameTextField 0x000f4f8c method iGoat_Swift.KeychainExerciseVC setUsernameTextField: 0x000f4fa4 method iGoat_Swift.KeychainExerciseVC passwordTextField 0x000f4fc8 method iGoat_Swift.KeychainExerciseVC setPasswordTextField: 0x000f4fe0 method iGoat_Swift.KeychainExerciseVC viewDidLoad 0x000f5094 method iGoat_Swift.KeychainExerciseVC loginActionWithSender: 0x000f5290 method iGoat_Swift.KeychainExerciseVC initWithNibName:bundle: 0x000f5578 method iGoat_Swift.KeychainExerciseVC initWithCoder: 0x000f5140 method iGoat_Swift.KeychainExerciseVC .cxx_destruct
注意viewDidLoad
位于的方法0x000f4fe0
。提示:icc
用于一个很好的类似c-header
的输出:
@interface iGoat_Swift.KeychainExerciseVC : { iGoat_Swift.KeychainExerciseVC::(ivar)usernameTextField iGoat_Swift.KeychainExerciseVC::(ivar)passwordTextField } - (void) setUsernameTextField: - (void) setPasswordTextField: - (void) viewDidLoad - (void) loginActionWithSender: @end
如果您需要,可以将其保存到文件中,icc > iGoat-Swift.arm_32.0.h
或者只显示内部较少的文件:icc~..
func viewDidLoad()
:在视图控制器将其视图层次结构加载到内存后调用此方法。无论视图层次结构是从nib文件加载还是在loadView()方法中以编程方式创建,都会调用此方法。我们通常会覆盖此方法以对从nib文件加载的视图执行其他初始化。在这里,我们将找到练习的主要代码。如果我们要找0x000f4fe0
,我们会看到它被标记为method.iGoat_Swift.KeychainExerciseVC.viewDidLoad(我们之前在旗帜中看到过)。
反编译
我们找到了“切入点”,让我们仔细检查一下。
viewDidLoad
r2显示以下反汇编:
[0x000f4ff4]> pdf ;-- method.iGoat_Swift.KeychainExerciseVC.viewDidLoad: ╭ (fcn) sub.objc_retain_fe0 180 │ sub.objc_retain_fe0 (); │ ; var int local_0h @ sp+0x0 │ ; var int local_4h @ sp+0x4 │ ; var int local_8h @ sp+0x8 │ ; var int local_ch @ sp+0xc │ ; UNKNOWN XREF from str. (+0x14) │ 0x000f4fe0 b0402de9 push {r4, r5, r7, lr} │ 0x000f4fe4 08708de2 add r7, sp, 8 │ 0x000f4fe8 10d04de2 sub sp, sp, 0x10 ; "T" │ 0x000f4fec e4560ce3 movw r5, 0xc6e4 │ 0x000f4ff0 0040a0e1 mov r4, r0 │ 0x000f4ff4 185040e3 movt r5, 0x18 │ 0x000f4ff8 05509fe7 ldr r5, [0x000f5000] ; [0xf5000:4]=0xe3550000 │ 0x000f4ffc 0aae03eb bl sym.imp.objc_retain │ ; DATA XREF from sub.objc_retain_fe0 (0xf4ff8) │ 0x000f5000 000055e3 cmp r5, 0 │ ╭─< 0x000f5004 0a00001a bne 0xf5034 ; likely │ │ 0x000f5008 2c0009e3 movw r0, 0x902c │ │ 0x000f500c 180040e3 movt r0, 0x18 │ │ 0x000f5010 00008fe0 add r0, pc, r0 │ │ 0x000f5014 080080e2 add r0, r0, 8 ; 0x27e04c ; aav.0x0027e04c │ │ 0x000f5018 6076ffeb bl sym.func.000d29a0; sym.func.000d29a0(0x27e04c) │ │ 0x000f501c 0050a0e1 mov r5, r0 ; aav.0x0027e04c │ │ 0x000f5020 b0060ce3 movw r0, 0xc6b0 │ │ 0x000f5024 180040e3 movt r0, 0x18 │ │ 0x000f5028 5bf07ff5 dmb ish │ │ 0x000f502c 00008fe0 add r0, pc, r0 │ │ 0x000f5030 005080e5 str r5, [r0] │ │ ; CODE XREF from sub.objc_retain_fe0 (0xf5004) │ ╰─> 0x000f5034 08408de5 str r4, [sp + local_8h] │ 0x000f5038 08008de2 add r0, sp, 8 │ 0x000f503c 0c508de5 str r5, [sp + local_ch] │ 0x000f5040 641203e3 movw r1, 0x3264 ; 'd2' │ 0x000f5044 181040e3 movt r1, 0x18 │ 0x000f5048 01109fe7 ldr r1, [0x000f5050] ; [0xf5050:4]=0xe30a085c │ 0x000f504c e6ad03eb bl sym.imp.objc_msgSendSuper2 │ ; DATA XREF from sub.objc_retain_fe0 (0xf5048) │ 0x000f5050 5c080ae3 movw r0, 0xa85c │ 0x000f5054 0010a0e3 mov r1, 0 │ 0x000f5058 0f0040e3 movt r0, 0xf │ 0x000f505c 30330de3 movw r3, 0xd330 │ 0x000f5060 0f3040e3 movt r3, 0xf │ 0x000f5064 04108de5 str r1, [sp + local_4h] │ 0x000f5068 0510a0e3 mov r1, 5 │ 0x000f506c 00008fe0 add r0, pc, r0 ; 0x1ef8d0 ; "iGoat" ; str.iGoat │ 0x000f5070 03308fe0 add r3, pc, r3 ; 0x1f23a8 ; "taoGi" ; str.taoGi │ 0x000f5074 00108de5 str r1, [sp] │ 0x000f5078 0510a0e3 mov r1, 5 │ 0x000f507c 0020a0e3 mov r2, 0 │ 0x000f5080 c50100eb bl sub.SaveUser_79c │ 0x000f5084 0400a0e1 mov r0, r4 │ 0x000f5088 e3ad03eb bl sym.imp.objc_release │ 0x000f508c 08d047e2 sub sp, r7, 8 ╰ 0x000f5090 b080bde8 pop {r4, r5, r7, pc} ; r13
方法摘要:
[0x000f4ff4]> pds 0x000f4ffc bl sym.imp.objc_retain 0x000f5018 bl sym.func.000d29a0 0x000f504c bl sym.imp.objc_msgSendSuper2 0x000f506c str.iGoat 0x000f5070 str.taoGi 0x000f5080 bl sub.SaveUser_79c 0x000f5088 bl sym.imp.objc_release ;-- method.iGoat_Swift.KeychainExerciseVC.loginActionWithSender:: 0x000f50a8 bl sym.imp.objc_retain 0x000f50b0 bl sym.imp.objc_retain 0x000f50b8 bl sub.swift_unknownWeakLoadStrong_d5c 0x000f50c0 bl sym.imp.objc_release 0x000f50d0 b sym.imp.objc_release
需要注意的事项:1.func viewDidLoad()
变成objc_retain: sub.objc_retain_fe0
2.我们可以看到,即使在摘要中我们也可以找到字符串iGoat
和taoGi
。3.它sub.SaveUser_79c
使用这些字符串调用子例程。
sub.SaveUser_79c
子程序sub.SaveUser_79c位于0x000f579c:
[0x000f4ff4]> s sub.SaveUser_79c [0x000f579c]> pdf ╭ (fcn) sub.SaveUser_79c 516 │ sub.SaveUser_79c (); │ ; var int local_0h @ sp+0x0 │ ; var int local_4h @ sp+0x4 │ ; var int local_8h @ sp+0x8 │ ; var int local_ch @ sp+0xc │ ; var int local_10h @ sp+0x10 │ ; var int local_14h @ sp+0x14 │ ; var int local_18h @ sp+0x18 │ ; var int local_1ch @ sp+0x1c │ ; var int local_20h @ sp+0x20 │ ; var int local_24h @ sp+0x24 │ ; var int local_28h @ sp+0x28 │ ; var int local_2ch @ sp+0x2c │ ; var int local_30h @ sp+0x30 │ ; var int local_34h @ sp+0x34 │ ; var int local_48h @ sp+0x48 │ ; var int local_4ch @ sp+0x4c │ ; CALL XREF from sub.objc_retain_fe0 (0xf5080) │ 0x000f579c f0402de9 push {r4, r5, r6, r7, lr} │ 0x000f57a0 0c708de2 add r7, sp, 0xc │ 0x000f57a4 00052de9 push {r8, sl} │ 0x000f57a8 028b2ded vpush {d8} │ 0x000f57ac 58d04de2 sub sp, sp, 0x58 ; 'X' │ 0x000f57b0 0340a0e1 mov r4, r3 │ 0x000f57b4 a53b0ce3 movw r3, 0xcba5 │ 0x000f57b8 0f3040e3 movt r3, 0xf │ 0x000f57bc 0c5097e5 ldr r5, [r7, 0xc] │ 0x000f57c0 03308fe0 add r3, pc, r3 ; 0x1f236d ; "SaveUser" ; str.SaveUser │ 0x000f57c4 2c308de5 str r3, [sp + local_2ch] │ 0x000f57c8 0830a0e3 mov r3, 8 │ 0x000f57cc 0060a0e3 mov r6, 0 │ 0x000f57d0 30308de5 str r3, [sp + local_30h] │ 0x000f57d4 38308de2 add r3, sp, 0x38 │ 0x000f57d8 34608de5 str r6, [sp + local_34h] │ 0x000f57dc 470083e8 stm r3, {r0, r1, r2, r6} │ 0x000f57e0 0100a0e3 mov r0, 1 │ 0x000f57e4 48608de5 str r6, [sp + local_48h] │ 0x000f57e8 4c608de5 str r6, [sp + local_4ch] │ 0x000f57ec 5000cde5 strb r0, [sp, 0x50] │ 0x000f57f0 0500a0e1 mov r0, r5 │ 0x000f57f4 30ae03eb bl sym.imp.swift_unknownRetain │ 0x000f57f8 081097e5 ldr r1, [r7, 8] │ 0x000f57fc 2c308de2 add r3, sp, 0x2c │ 0x000f5800 0400a0e1 mov r0, r4 │ 0x000f5804 0520a0e1 mov r2, r5 │ 0x000f5808 0080a0e3 mov r8, 0 │ 0x000f580c dea400eb bl sub._b8c; sub._b8c(0x0, 0x4042f04f) │ 0x000f5810 000058e3 cmp r8, 0 │ 0x000f5814 1cd04702 subeq sp, r7, 0x1c │ 0x000f5818 028bbd0c vpopeq {d8} │ 0x000f581c 0005bd08 popeq {r8, sl} │ 0x000f5820 f080bd08 popeq {r4, r5, r6, r7, pc} ; aav.0x000cf2c0 │ 0x000f5824 2fe1ffeb bl sym.func.000edce8 │ 0x000f5828 3810a0e3 mov r1, 0x38 ; '8' │ 0x000f582c 0320a0e3 mov r2, 3 │ 0x000f5830 0350a0e3 mov r5, 3 │ 0x000f5834 99c2ffeb bl sym.func.000e62a0; sym.func.000e62a0(0x0) │ 0x000f5838 0040a0e1 mov r4, r0 │ 0x000f583c 000c0ce3 movw r0, 0xcc00 ; "xD" │ 0x000f5840 0f0040e3 movt r0, 0xf │ 0x000f5844 0610a0e3 mov r1, 6 │ 0x000f5848 00008fe0 add r0, pc, r0 ; 0x1f2450 ; "Error updating keychain - " ; str.Error_updating_keychain ...
方法摘要:
[0x000f579c]> pds 0x000f57c0 str.SaveUser 0x000f57f4 bl sym.imp.swift_unknownRetain 0x000f580c bl sub._b8c 0x000f5824 bl sym.func.000edce8 0x000f5834 bl sym.func.000e62a0 0x000f5848 str.Error_updating_keychain 0x000f5868 bl sym.func.000f0e34
需要注意的事项:1.XREF来自viewDidLoad
:; CALL XREF from sub.objc_retain_fe0 (0xf5080)
。2.字符串 SaveUser
。3.函数调用:sym.func.000edce8
和sym.func.000e62a0
和sym.func.000f0e34>
。4.字符串 Error updating keychain -
所以我们猜测它试图在这里更新Keychain。现在我们看到了这个字符串Error updating keychain -
……想象一下,我们还没有通过查看classes(ic)而是通过查看strings(iz)来开始,这也是一种非常常见的方法。
iz~+keychain 1530 0x001ee330 0x001f2330 37 38 (4.__TEXT.__cstring) ascii _TtC11iGoat_Swift18KeychainExerciseVC 1533 0x001ee380 0x001f2380 39 40 (4.__TEXT.__cstring) ascii Error reading password from keychain - 1535 0x001ee3b0 0x001f23b0 154 155 (4.__TEXT.__cstring) ascii /Users/swaroop.yermalkar/AWS/iGoat-Swift-master/iGoat-Swift/iGoat-Swift/Source/Exercises/InsecureLocalDataStorage/KeychainAnalyze/KeychainExerciseVC.swift 1536 0x001ee450 0x001f2450 26 27 (4.__TEXT.__cstring) ascii Error updating keychain - ... axt @ 0x001f2450 sub.SaveUser_79c 0xf5848 [DATA] add r0, pc, r0
“怎么使用radare2逆向iOS Swift应用程序”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
原创文章,作者:1402239773,如若转载,请注明出处:https://blog.ytso.com/221637.html