码迷,mamicode.com
首页 > 其他好文 > 详细

实验吧 RE reversemeplz

时间:2018-01-30 21:11:16      阅读:420      评论:0      收藏:0      [点我收藏+]

标签:数字   art   ==   end   地址   权限   source   down   address   

刚做这道题的时候就是刚学完 gdb 调试,还没有实例练一下,刚好这道题可以学习一下 gdb

装 peda gdb

我就是按照网上查的办法装的,唯一注意的地方就是,我第一装的时候用的 root 权限装的(比较蠢),所以 user 权限打不开,后来又 user 权限下装,就可以显示红色的 gdb-peda$

git clone https://github.com/longld/peda.git ~/peda
echo "source ~/peda/peda.py" >> ~/.gdbinit

reversemeplz 题目分析

现在回到题目,先用 linux 看一下是什么类型文件,linux 环境下运行一下,然后 IDA32 打开。找到关键函数

技术分享图片

我把函数名字改为 key,只有返回 v1=1 才能得到答案 再看 key 函数
技术分享图片

func 我感觉也是关键函数,所以把它也标记了一下,然后打开 func 的时候,发现复杂,所以先不准备处理它,我进行对于 key 函数的整理

for i = 0; i < 15; i++:
    if a1[i] <= 96:
        a1[i] = func(a1[1] & 1)     #这里我特意去查,并且试了一下是 *优先级 > &
    if a1[i] > 122:
        a1[i] = func(a1[1] & 2)
    if 97 <= a1[i] <= 122:          #97 - 122 是 a - z
        a1[i] = a1[i]               # 这里很重要
    v3 = func(a1[i])
    v9[i] = v3
    if v3 > 0xCCu && v3 != 0XCFu    #这里我也被坑了一下,由于 v3 是char型,所以 -49 只是因为上溢产        
                v1 = 1                    生的负数,这里也是一个关键位置

# 输入长度必须为 15
v4 = 0

# v1 必不为 1
for i = 1; i <= 14; i++ 
    v9[i] - v9[i-1] = diff[i]       #看 IDA 就可以发现 v8 的起始刚好在 v9 上面一位
    # 因为若 a1[15] == 1 则必 return 0
    # 因为若 func(0) == 1 则必 return 0
    # 所以 a1[15] != 1 && func(0) != 1  但是这好像没什么卵用(嘿嘿嘿)
    return func(a1[0]) == 98
    # 为了能 return 一个非零数, 则 func(a1[0]) == 98, 这里是突破口

# 接下来就是练调试的部分,需要调试出 diff [1 - 14],通过 v9[0] = func(a1[0]) = 98, 可以求出 fun(a1[0 - 15]),但是总觉得差点什么,我们并没有搞清楚 func 的函数怎么运行,或者存在什么运算规律

调试

大致流程:

  1. 先输 gdb
  2. 再 file ./[ file ]
  3. 开始 start
  4. 设断点 b *[ 地址 ]
  5. run
  6. p $参数
  7. n 或者 c

调试出 diff 数组

技术分享图片

技术分享图片

技术分享图片

可以看到你想要的那个地址和地址上的数据,之后我会写一点关于今天学会用的 x 的知识,就是别忘了p 时 ‘$‘

技术分享图片

根据上面的汇编可以知道是每隔四个是 diff 数组内容,且 eax 从 0x1 开始取

技术分享图片

调试尝试 a-z 输入时 func 的规律

为什么选 a-z 呢 因为 a-z 输入时 a[ i ] = a[ i ] 更好控,若是 func 有规律,就更容易找到 func 的规律

然后我就开始了一波新的调试,这里可以 之前有调试的内容

  1. 可以直接 q 退出,再开新的 gdb (这样显得比较蠢)
  2. 就用我查的新技巧
  3. info b 查询 break 情况
  4. delete 数字 ,是删除第几个断点 (还有其他的办法使断点不可用)
  5. 新设断点,再次 start, run

这里新设断点,我设到了 if ( (unsigned __int8)v3 > 0xCCu && v3 != 0xCFu ) 这里,因为这里汇编比较清楚

技术分享图片

第一个箭头指向的是:处理的字符串即 func( char ) 是什么

第二个箭头指向的是:汇编中调试当前位置

第三个箭头指向我打印出来的 func( ‘a‘ )

然后在不断 c 和 print 的过程中发现

func( a-m ) == n-z func( n-z ) = a-m

这里规律出来之后就比较清晰了,我们如果能找到 只由 a-z 组成的15位字符串,就可以满足条件,从而得到满足输入的字符串,如果不能就还要研究 func() (我也不想啊)

然后写了一发脚本,跑出来可以,而且语义比较符合,交一发就出来了

附上脚本

# /usr/bin/env python
# -*-coding:utf-8-*-

__Author__= ‘Vangelis‘

diff = [-1, 17, -11,  3, -8, 5, 14, -3, 1, 6, -11, 6, -8, -10]

#a:0x6e b:0x6f c:0x70 d:0x71 e:0x72 f:0x73 g:0x74 h:0x75 i:0x76 j:0x77 k:0x78 l:0x79 m:0x7a
#n:0x61 o:0x62 p:0x63 q:0x64 ...
#according to gdb, find the rule of ‘func‘ -- send ‘a-z‘  out ‘n-za-m‘ ‘m‘ is break 
#so the first could ‘o‘

map = {‘n‘:‘a‘, ‘o‘:‘b‘, ‘p‘:‘c‘, ‘q‘:‘d‘, ‘r‘:‘e‘, ‘s‘:‘f‘, ‘t‘:‘g‘, ‘u‘:‘h‘, ‘v‘:‘i‘, ‘w‘:‘j‘, ‘x‘:‘k‘, ‘y‘:‘l‘, ‘z‘:‘m‘, ‘a‘:‘n‘, ‘b‘:‘o‘, ‘c‘:‘p‘, ‘d‘:‘q‘, ‘e‘:‘r‘, ‘f‘:‘s‘, ‘g‘:‘t‘, ‘h‘:‘u‘, ‘i‘:‘v‘, ‘j‘:‘w‘, ‘k‘:‘x‘, ‘l‘:‘y‘, ‘m‘:‘z‘}

key = ord(‘b‘)
flag = ‘o‘
for i in range(14):
    key += diff[i]
    flag += map[chr(key)]

print(‘flag{‘ + flag + ‘}‘)

关于 x 的使用问题

x/<n f u> < addr >

正如我使用的一样 n 代表个数:当前地址向后显示几个内存单元的值

f 代表按照什么格式:就像 C 中的 数据类型一样 ,注意一下 t 和 a

? x d u o t(binary) a(address) c f

u 代表按照几个字节来分开:b表示单字节,h表示双字节,w表示四字 节,g表示八字节

我需要一个字节一个字节的 所以用的 b 需要10进制,所以用的 d

有人问了为什么你 db 写反了,还可以出来(这么尴尬的问题,你也问???喵喵喵???)

实话实说,我也是写到这里才发现,我之前截屏的那一次操作写反了(=.=)

去试了一波,发现对于 db 正反都可以用,可能是当 f u 没产生冲突的时候可以用吧,就像 f 中无 b 所以认为是属于u 中的吧

技术分享图片

关于 x 的用法的参考资料:

https://www.cnblogs.com/jlmgary/p/6170435.html

实验吧 RE reversemeplz

标签:数字   art   ==   end   地址   权限   source   down   address   

原文地址:https://www.cnblogs.com/Vangelis/p/8387017.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!