day3

2018-08-12  本文已影响13人  zs0zrc

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传回返回值。

题目自己实现指令集


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

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

find binary parser:

find Disassembler:

find tracer and debugger:

然后开始常规的逆向


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

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

漏洞挖掘的分析策略:

控制流分析:

代码识别:

上一篇下一篇

猜你喜欢

热点阅读