逆向密码(七)

比如签名的CertificateSigningRequest.certSigningRequest文件就是base64对二进制编码

ValueCharValueCharValueCharValueChar
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/
source ASCII (if <128)Man
source octets77 (0x4d)97 (0x61)110 (0x6e)
Bit pattern010011010110000101101110
Index1922546
Base64-encodedTWFu
encoded octets84 (0x54)87 (0x57)70 (0x46)117 (0x75)
Text contentM
ASCII77 (0x4d)0 (0x00)0 (0x00)
Bit pattern010011010000000000000000
Index191600
Base64-encodedTQ==
Text contentMa
ASCII77 (0x4d)97 (0x61)0 (0x00)
Bit pattern010011010110000100000000
Index192240
Base64-encodedTWE=

把要编码的字母到对应assci二进制码 每6个二进制取一个值那对应的符号(其他的=补全)

base64大多是对加密后的数据进行编码

base64编码:

base64解码:

密码:

  • 非对称 (RSA,公私钥..)(由于简单的数据运算,效率比较低,主要用于加密核心的小数据)
  • 对称
  • HASH 哈希(散列)函数(不可逆,不能用加密解密)

对称密码:

  • 分组密码 (Feistel,DES,AES)
  • 序列密码 (线性反馈寄存器,内容扰乱系统,A5/1算法,RC5算法)
  • 密码模式 (电子密码本ECB,密码块链接CBC,填充密码块链接PCBC,密文反馈CFB,计数器模式CTR)

哈希密码:

  • 用途:文件校验,数字签名
  • 算法:MD4,MD5,SHA1

Openssl(公开加密算法库):

生成私钥:

从上面private.pem私钥中生成公钥 (公钥是根据私钥算出)

查看明文的private内容


MD5

一个二进制只有一个Hash值(可用于判断一个数据有没有被修改过)

 

 

–未完.待更新

静态语言、动态语言区别?

静态语言:

比如c语言,值声明了方法不实现是报错的,如果现实了比如下面简单代码,在编译时期就已经确定了run代码段的内存地址。比如int age=27;至于在要age名字有必要吗?

动态语言:

OC只声明不现实不报错,它是根据运行时macho上查找 IMP在Symbok Table 符号表查找(sel > IMP(地址)‘对应查看)

逆向ASLR(六)

程序是先装载的macho文件然后在装载依赖库

macho装载内存后,是一个虚拟内存(相对macho来说)

内存中不存在header ,load commands

__DATA段的VM Address是__PAGEZERO的VM Address+__TEXT段的VM Size(真实大小)(每次编译都会改变)


ASLR(Address space layout randomization)地址空间配置随机加载 

是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。据研究表明ASLR可以有效的降低缓冲区溢出攻击的成功率,如今Linux、FreeBSD、Windows等主流操作系统都已采用了该技术。

作用: 降低缓冲区溢出攻击的成功率

问题:0x1000063B8 是否[Began:withEvent:]地址?

比如要手动下方法断点,这时找不到真正的地址是无光动态调试,0x1000063B8其实并不是内存条上的真实地址,

通过image list 拿到macho文件在内存条的地址(比如0x0000000102598000 应该拿0x2598000)+0x1000063B8就是真实的地址了

问题:怎么拿到全局的变量?

比如定义了int age=27; 在macho中怎么找到(其中age这个变量名是个地址在编译时就已经有地址位置,要age名字没必要的) (静态语言就是根据把代码生成地址空间在编译时期就知道 比如c语言只声明不实现会报错。OC只声明不现实不报错,它是根据运行时macho上查找 IMP在Symbok Table查找)

  1. 获取&age地址 (0x00000001022fcfd8)
  2. &age-image list的macho的地址(0x00000001022f4000) =  0x8FD8
  3. 在2中相减得到的地址在macho(__DATA,__data)中查看


静态语言和动态语言区别?

静态语言就是根据把代码生成地址空间在编译时期就知道 比如c语言只声明不实现会报错。

OC只声明不现实不报错,它是根据运行时macho上查找 IMP在Symbok Table查找

逆向方法反汇编(五)

局部变量属于强引用。汇编代码:

#mark-1: 看汇编objc_msgSend 这里结构是

oc中调用: [Animal alloc]

objc_msgSend(Animal.class,@selector(alloc));

根据汇编也就是x0寄存器也类,x1寄存器是sel

#mark-3:

  • x0:animal对象
  • x1:nil  (也就是首页指针指向nil,释放原来的对象)

注意:objc_storeStrong

所有OC中使用Strong修饰的对象 实际调用的函数是objc_storeStrong,代码实现如下


上面的一些是动态分析,如果是在真实的项目中决定是非常的复杂,所有动态分析很麻烦,可以直接用ida工具来分析

查看ida分析和上面动态分析是一样结果,只是它的更加详细 函数名也一起展示了。

问题:看上图 地址都是text:000000010000….    中间都是一个1 (后面8个0),为什么?

0x100000000 是4个G的虚拟size  (也就是text是从0x100000000开始)

问题:ida是怎么知道 这个地址的函数名 类名等?

主要是通过mach0文件分析对应查找, 如图

逆向block(四)

  • globalblock (编译时期)
  • stackblock    (编译时期)
  • mallocblock    (运行时期)

汇编:

#mark-a:

x8是通过adrp add 算出地址是0x104b7c080,读内存地址 得到__NSGlobalBlock__,__NSGlobalBlock__是block的isa指针也就是在这附近有一个block的定义.


比如一些稍复杂的block定义:

汇编:

这时直接用动态调试非常麻烦(算地址再去macho查看),可以直接借助 ida工具来

逆向LLDB(三)

LLDB (Low Lever Debug)

常用指令

  • help breakpoint 产看breakpoint指令
  • breakpoint set -n funcRun   (-n是-name,  funcRun是方法名字) (简写 b funcRun)
  • breakpoint set -n “-[ViewController run]” -n “-[ViewController eat:]”   设置多个断点
  • breakpoint set –selector touchesBegan:withEvent:  断点所以得方法和类无光
  • breakpoint set –file ViewController.m  –selector touchesBegan:withEvent:   在指定文件中设置断点
  • breakpoint set -r Run:  遍历满足整个项目中符合Run:这个字符的所以方法
  • breakpoint list 断点的list
  • breakpoint disable 2.1  禁用2.1处断点(也就是funcRun处断点)
  • breakpoint enable 2.1  启用2.1处断点
  • breakpoint delete 2  删除一组断点 (删除一个是禁用,只有删除一组才可以删除)
  • breakpoint delete  全部删除
  • p 就是expression简写
  • poexpression -O
  • expression 断点修改…  (p (Animal *)self.cat    得到$2 然后再去设置$2.run 才能执行) (control+return 多行)
  • memory read 0x32…..  读内存地址 也可以用 x 0x32…
  • x/数量格式字节数 内存地址  格式:x是16进制,f是浮点,d是10进制。字节大小:b:byte 1字节,h:half word 2字节 w:word 4字节,g:giant word 8字节)
  • memory write 0x102a821 8  (0x102a820:  22 07 00 00 00 00,其中0x102a821是07,2位一个字节)
  • register read x1  读寄存器

  • up 查看堆栈上一个调用的函数
  • thread return  回滚堆栈上一个调用的函数 (再c执行就结束了 不会再往下走, 因为return)
  • frame select 5 查看bt后的#序号的函数,也就是直接断点到#序号的函数中
  • frame variable 查看整个方法中的参数

 

  • continue  简写c 继续执行
  • next 简写n  单步运行,一行一行代码走
  • step 简写s  单步运行,遇到子函数会进去


内存断点:(和断点的一些设置一样 delete 、list等)

  • watchpoint set variable cat->name  对cat的name设置内存断点(也就是name改变就断点)
  • watchpoint set expression 0x00000003d…    给内存地址设置断点

断点添加指令:

  • break command add 1              添加指令
  • breakpoint command list 1     查看1处指令
  • breakpoint command delte 1   删除指令


stop-hook

pass和debugView 不会触发,只对breadpoint,watchpoint

  • target stop-hook add -o “p self.cat.name”
  • target stop-hook delete  删除
  • undisplay 1           删除一组
  • target stop-hook list    查看所有

image

  • image lookup -a 0x32323f2    通过地址查看指令
  • image lookup -t Animal  查看类的信息 (包含了头文件)
  • image list

例子:真机上崩溃信息

可以用image lookup -a 0x18564ed8c 这样方式来看崩溃的堆栈信息


总结:

lldb在断点启动的时候会走 $HOME/.lldbinit 文件 (如果没有自己新建),里面可以配置一些指令,一般是用作导入配置文件

逆向Mach-o(二)

Mach-o(Mach Ojbect缩写)文件有11种格式(并不是所有的可执行文件都有Mach-o),是Mac/iOS上用于存储程序,库的标准格式

Mach-o常见格式:

  • 可执行文件
  • object   (a. 其中包括.o 文件   b. .a静态库文件 其实就是N个.o文件集合)
  •   DYLIB:动态库 (a. dylib  b.framwork)
  • 动态连接器
  • DSYM

例子1:

把上面的代码文件.c编程.o执行命令

  • clang -c main.c   (会生成一个main.o) (也可以直接生成多个 clang -c main.c test.c)
  • file main.o  (main.o: Mach-O 64-bit object x86_64)(属于Mach-o 是一个object 不是可执行文件
  • clang main.o (或者生成cusmain clang -o cusmain main.0)(生成a.out 在file a.out (a.out: Mach-O 64-bit executable x86_64) (可执行文件))
  • ./a.out 直接执行 (Hello, World!)

上面那几步也可以直接生成可执行文件 :

例子2:多文件文件合并成一个可执行文件

这个文件类交Test.c  (不需要引入#include..),另一个文件还是上面的main.c (和.c顺序没关系)

执行下面命令合并(会有警告 没关系)

它会生成一个sks可执行文件,./sks 直接执行就行

*find找文件 find /cust/dsk -name “*.a”


动态库共享缓存:

为了提高性能,系统的动态库文件都存在动态库共享缓存里面(其中动态库只有一份)

比如上面的dyld_shared….x86_64h 多个app动态库都放在这,起到公用库的作用(类似单利) (通过动态连接器加载动态库)

动态加载器(动态连接器)(dyld) (用来加载动态库) (是dynamic linker可执行文件)

  • dynamic linker
  • dynamic loadel


二进制文件

其中xcode中默认是Executable可执行文件

  • Executable (默认)
  • Dynamic Library
  • Bundle
  • Static Library
  • Relocatable Object File

xcode,debug下生成app可执行文件是arm64, 在release中是多个架构,这个debug中YES是当前真机的架构

Architectures和有效架构是取交集,所有上面只生成arm64 armv7,在Architectures加一种就可以生成armv7s架构

在分析汇编代码的时候,大多时候值分析一个架构就可以(经常用于静态库):

拆分二进制文件:

合并:


MachO

MachO主要分为3大块:

  • MachO Header (包含整个架构的信息,load Commands数量等)
  • Load Commands (区域位置)
  • Data (代码 全局变量等)

MachO工具


附加: shell转成二进制可执行文件

http://www.datsi.fi.upm.es/~frosal/ 下载解压进入 然后执行make test

  • test.sh.x是加密后的可执行的二进制文件;用./test.sh.x即可运行,
  • test.sh.x.c是生成 test.sh.x的原文件(c语言)

-e:指定过期时间为2018年05月24日
-m:过期后打印出的信息;
-v: verbose
-r: 可在相同操作系统的不同主机上执行
-f: 指定源shell

另外的一种方式 gzexe test.sh

逆向class-dump(一)

逆向原理:

  • 动态调试:通过界面调试Cycript/LLDB
  • 静态分析:通过汇编代码分析app源码
  • 代码注入:就是动态库,注入进去,动态库默认加载,通过HOOK代码来改变程序执行流程
  • 重签名: 安装非越狱手机 (企业/个人证书)

class-dump

class-dump可以导出程序里的所有的头文件(方法所以得定义,和成员变量(包含.m中的))

安装:

注意:

  • /usr/bin 系统预装,系统升级会更新和覆盖
  • /local/bin 本地 放自己的可执行文件

如果这2个都存在一样的,执行哪个? 主要看 PATH里面的配置顺序, (PATH=$PATH:$HOME/bin:/sbin:/usr/bin:/usr/sbin)

  • 如果你使用的是bash,cat ~/.bash_profile (bash默认加载bash_profile)
  • 如果是zsh, cat ~/.zshrc (zsh默认架子啊zshrc)

安装方式几种:

  1. 把class-dump可执行文件直接放进;local/bin 目录
  2. 在当前用户下新建个文件夹(如 mkdir ~/bin),然后chmod +x  ~/bin/class-dump 给他执行权限,然后在bash_profile/zshrc找到export PATH=$HOME/bin/:$PATH   然后source ~/.bash_profile 或source ~/.zshrc

配置好,要退出终端在打开。验证有没有成功,直接在终端执行 class-dump,看到版本就成功了

使用:

这是微信的ipa包 链接:https://pan.baidu.com/s/1C9hLt6oOv6jgdrSaMH6f-Q 密码:j7ad

  1. 可以使用自己的ipa包,解压找到可执行文件
  2. 执行class-dump -H yourexecFile (这样是把所有的头文件(包含第三方的)输出到当前文件夹下,也可以指定路径class-dump -H yourexecFile -o /customDir )

努力改变

  1.  尽最大可能 早起早睡
  2.  一周至少2次去健身
  3.  2周至少给家人打一个电话
  4.  努力做到让家人身心健康 家庭和谐
  5.  少发脾气,对于不喜欢的人要忍 忍 忍, 看不惯的事深虑后决定
  6.  尽量不要做一些后悔 内疚的事
  7.  认识和解释自己的不足
  8.  再交2-3个真正的铁哥们
  9.  制作一份简单计划 尽量要按时完成,不然就尽快花别的时间来补上
  10.  禁止制作复杂、很难完成的计划(偶尔是可以的)
  11.  学习技术要专注一点, 要快速的过完一遍.. 然后通过实用来复习巩固
  12.  说话尽量不要太伤人,深虑后再说
  13.  不要计较太多 尽量做到少说 少比
  14.  对于“叛徒/小人”要尽可能容忍,不可能做成朋友的人也不要扯破关系,把他当普通人、陌生人
  15.  找到2个真正的“偶像” 向他学习,生成动力
  16.  尽量让自己每天快乐点

Clang

clang转不同平台,代码是不一样的,可以直接指定平台(特别是汇编是不一样的)