day3

作者: zs0zrc | 来源:发表于2018-08-12 11:57 被阅读13次

    re新手的做题体验:蒙蔽蒙蔽,一脸蒙蔽

    题目hide:
    这是一道加了upx壳的程序,但是但用upx脱壳工具脱不下来,所以只能手动脱壳

    因为程序在运行时,会自身进行脱壳,在linux下可以通过dd命令,将它的text段和data段dump下来,然后拼起来,拖进ida中看,但是这给dump下来的二进制文件不可以执行,因为它的不符合elf文件格式
    程序dump的话要,要先跳过ptrace这个系统调用,因为这个程序会调用ptrace来反调试,只要在gdb中用catch syscall ptrace这条命令,然后执行到ptrace,将eax设置为0就可以跳过ptrace了 然后通过 cat /proc/(pidof hide)/maps 来打印hide的内存信息
    最后通过 dd命令,将hide的text段和data段dump下来
    脱壳命令:

    sudo dd if=/proc/$(pidof hide) /mem of=hide_dump1 skip=4194304  bs=1c count=827392
    sudo dd if=/proc/$(pidof hide)/mem of=hide_dump2 skip=7110656  bs=1c count=20480
    cat hide_dump1 hide_dump2 >hide_dump
    

    程序dump下来后就可以脱到ida中去看了
    程序的关键代码可以通过string xref 找到。通过查找字符串 快捷键shift + f12 ,找到一些关键的字符串,然后查找有什么函数引用它,然后就可以找到main函数,但是ida静态分析的结果是不正确的,它有些关键代码被隐藏起来了,所以要通过string xref 来找到调用"Enter "字符串的地方,可以发现有两个地方引用了这个字符串,查看另一个调用的地方

    image.png

    跳转到那个地方,发现没有函数,create一个函数后因为syscall所以后面的代码反编译后显示不出来,所以通过查看汇编代码的关键函数的地址,在那create一个function,在反编译就可以查看了

    image.png

    可以发现,输入字符串长度为21,以及关键字符,以及加密后的密文v2
    加密函数实现了一个Tea加密算法的变种

    image.png image.png

    将flag_encdump出来,写个解密脚本跑一下,flag的内容就出来了
    解密脚本:
    脚本来源 : 大佬github

    from struct import pack,unpack
    
    arr=[0x52,0xb8,0x13,0x7f,0x35,0x8c,0xf2,0x1b,0xf4,0x63,0x86,0xd2,0x73,0x4f,0x1e,0x31]
    ct=map(chr,arr)
    
    def rec8e50(ct):
        res=''
        for i in range(16):
            res+=chr(i^ord(ct[i]))
        return res
    
    key=[1883844979,1165112144,2035430262,861484132]
    DELTA=0x676E696C
    rounds=8
        
    def ul(v):
      return v & 0xFFFFFFFF
    
    def rec8cc0(ct):
        res=''
        for j in range(2):
            v0=unpack('I',ct[8*j:8*j+4])[0]
            v1=unpack('I',ct[8*j+4:8*j+8])[0]
            sum = ul(DELTA * rounds)
            for i in range(rounds):
                v1 = ul(v1 - ((v0 << 4 ^ v0 >> 5) + v0 ^ sum + key[sum>>11 & 3]))
                sum = ul(sum - DELTA)
                v0 = ul(v0 - ((v1 << 4 ^ v1 >> 5) + v1 ^ sum + key[sum & 3]))
            res += pack('I',v0) + pack('I',v1)
        return res
    
    def c8cc0(pt):
        res=''
        for j in range(2):
            v0=unpack('I',pt[8*j:8*j+4])[0]
            v1=unpack('I',pt[8*j+4:8*j+8])[0]
            sum = 0
            for i in range(rounds):
                v0 = ul(v0 + ((v1 << 4 ^ v1 >> 5) + v1 ^ sum + key[sum & 3]))
                sum = ul(sum + DELTA)
                v1 = ul(v1 + ((v0 << 4 ^ v0 >> 5) + v0 ^ sum + key[sum>>11 & 3]))
            res += pack('I',v0) + pack('I',v1)
        return res
    
    
    for i in range(3):
        ct = rec8e50(ct)
        ct = rec8cc0(ct)
    
    print ct
    # qwb{f1Nd_TH3HldeC0dE}
    

    这题逆向的一个小技巧:
    可以看到这题包含很多很多的函数,所以这是个静态链接的程序,因为有很多库函数,我们不可能一个个点进去看,这里冠成大佬讲了一个技巧就是,通过查看main函数逻辑,写一个功能差不多的程序,然后利用ida的rizzo插件,进行模糊匹配,将符号导入dump下来的文件的database,然后大部分函数都会有正确的函数名了

    gdb调试小技巧:
    catch syscall 捕获程序的系统调用
    catch syscall ptrace 捕获ptrace系统调用
    set eax=0 设置eax 的值为0
    通过设置 eax的值为0可以跳过ptrace系统调用
    recall 回溯,只用在静态链接时有用
    reverse continue 返回上一个断点


    simplecheck:
    这是一道android逆向,这是我第一次做android逆向题,虽然很简单,但是做出来就很开心
    做android逆向需要了解一些前置知识
    推荐看这一篇blog

    了解完前置知识后就开始做题,我先将apk文件解压获得classes.dex文件
    然后通过dex2jar工具将dex文件反编译得到jar包
    这个要使用命令行
    通过命令 ./d2j-dex2jar.bat classes.dex --force to overwrite 获得反编译的jar文件包
    然后用 jd-gui-window查看反编译的java代码

    定位到关键代码,a类的一个函数,查看这个a函数做了什么

    image.png

    只有当输入的字符串满足判断语句时,才返回true
    对判断条件进行解密:
    解密脚本:

    #!/usr/bin/env python
    # -*- coding:UTF-8 -*-
    
    a = [0, 146527998, 205327308, 94243885, 138810487, 408218567, 77866117, 71548549, 563255818, 559010506, 449018203, 576200653, 307283021, 467607947, 314806739, 341420795, 341420795, 469998524, 417733494, 342206934, 392460324, 382290309, 185532945, 364788505, 210058699, 198137551, 360748557, 440064477, 319861317, 676258995, 389214123, 829768461, 534844356, 427514172, 864054312 ];
    b = [13710, 46393, 49151, 36900, 59564, 35883, 3517, 52957, 1509, 61207, 63274, 27694, 20932, 37997, 22069, 8438, 33995, 53298, 16908, 30902, 64602, 64028, 29629, 26537, 12026, 31610, 48639, 19968, 45654, 51972, 64956, 45293, 64752, 37108 ];
    c = [38129, 57355, 22538, 47767, 8940, 4975, 27050, 56102, 21796, 41174, 63445, 53454, 28762, 59215, 16407, 64340, 37644, 59896, 41276, 25896, 27501, 38944, 37039, 38213, 61842, 43497, 9221, 9879, 14436, 60468, 19926, 47198, 8406, 64666 ];
    d = [0, -341994984, -370404060, -257581614, -494024809, -135267265, 54930974, -155841406, 540422378, -107286502, -128056922, 265261633, 275964257, 119059597, 202392013, 283676377, 126284124, -68971076, 261217574, 197555158, -12893337, -10293675, 93868075, 121661845, 167461231, 123220255, 221507, 258914772, 180963987, 107841171, 41609001, 276531381, 169983906, 276158562 ];
    
    
    flag = [0]
    flag_s=""
    for i in range(len(c)):
        for j in range(0x20,0xff):
            if(a[i+1] == b[i]*j*j + c[i]*j + d[i]):
                print "find one char %s"%chr(j)
                flag.append(j)
                flag_s+=chr(j)
            else:
                continue    
    print flag_s
    

    最后跑出来flag是:flag{MAth_i&_GOOd_DON7_90V_7hInK?}


    regular -- magic

    函数调用约定出错 -> IDA -> option -> compiler -> Visual C
    要从 scanf 开始分析,跟踪输入流
    RC4加密
    setjmp longjmp 的概念
    在setjmp()函数中,将setjmp()函数的返回地址以及其他一些寄存器存到jmp_buf中;而在longjmp函数中,将jmp_buf中保存的"setjmp()函数的返回地址"作为longjmp()函数自己的返回地址。于是执行ret指令之后,longjmp()函数返回到“调用setjmp()函数”处(准确来说是“调用setjmp()函数”的下一条指令的地址),并通过eax传回返回值。

    题目自己实现指令集


    非常规逆向:
    特点:指令格式,架构不限定
    可能包含的种类:

    • lua/python/java/lua-jit/haskell/applescript/js/solidity 以太网智能合约
    • firmware/raw bin etc
    • chip8 、 avr、demency、risc-v etc....

    做非常规题要搜索的工具:
    find tools:

    • binary parser 二进制分析程序
    • disassembler 反汇编器
    • tracer
    • debugger 一般情况不会有
    • decompiler 一般都不回有 看天意

    find binary parser:

    • google 大法
    • 分析未知的二进制文件格式
    • firmware:
      先找基地址,然后找符号表
    • 其他未知的二进制文件格式:
      使用strings或者binwalk查看文件是否包含什么特征字符串或者是有没包含其他东东
      寻找任何有用的线索
      使用 IDA/radare2/binary ninja interface 或者使用ida loader

    find Disassembler:

    • google "xxxx disassembler/xxx IDA etc"
    • 人肉反编译器
    • IDA Pro/radare2/bianry.ninja interface

    find tracer and debugger:

    • google
    • tracer
      尝试搜索官方 tracer
    • debugger
      gdb-multian/qemu/emulator/trace replay

    然后开始常规的逆向


    pwn题的逆向分析策略:
    首先必须熟悉常见的的漏洞

    • 缓存区溢出
    • 整数溢出
    • 竞态条件
    • etc

    熟悉完常见的漏洞后,要了解一些漏洞挖掘的逆向技巧

    • 关键数据结构的分析,还原结构体,接口,类等
    • 控制流分析:理清程序的执行逻辑,基本要做到从反汇编代码到源码的还原
    • 数据流分析,搞清数据的流向

    漏洞挖掘的分析策略:

    • 目标文件较小时,争取做到整个程序从返汇编代码到接近源码级别的还原
    • 目标文件较大时,跟着数据流走,理清数据流经过的控制流

    控制流分析:

    • 目的是为了理清程序的逻辑,对于规模较小的目标文件,选择逆向整个文件
    • 常用方法: 代码走查、字符串交叉引用、API引用

    代码识别:

    • 熟悉产常见的数据结构、算法在目标文件长什么样
    • 链表、树、图、堆、各种加密算法
    • 逆向是门经验活,多逆就会有体会
    • 善用标记,标记结构体、变量名、变量类型
    • F5不是万能的,当感到代码诡异时,要从汇编代码的层次分析
    • 熟悉各类漏洞

    相关文章

      网友评论

          本文标题:day3

          本文链接:https://www.haomeiwen.com/subject/vnaevftx.html