XCTF-Reverse-ExerciseArea-010-writeup

0x00 介绍

本题是xctf攻防世界中Reverse的新手第十题。题目来源:SharifCTF 2016

给了一个二进制文件getit,需要对该二进制文件进行逆向分析,找到flag

实验环境:IDA Pro 7.0,gdb

0x01 解题过程

1.1 文件分析

Linux下的二进制文件,64位系统,符号表未被去掉


root@kali:~/hzy/ctf-learning# file getit 
getit: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=e389cd7a4b9272ba80f85d7eb604176f6106c61e, not stripped
root@kali:~/hzy/ctf-learning# chmod +x getit 
root@kali:~/hzy/ctf-learning# ./getit 
root@kali:~/hzy/ctf-learning# 


1.2 逆向分析

  1. 用IDA打开,发现该二进制文件未被加壳,因此不需要进行脱壳操作

  2. 基本块0x400775–0x400788是循环的条件判断,地址rbp+var_40中存储的是循环变量的值,先赋值给eax寄存器,再赋值给ebx,然后调用strlen函数,得到字符串s=c61b68366edeb7bdce3c6820314b7498的长度,保存在eax寄存器中;接下来如果ebx的值,也就是循环变量的值比长度小,就进入循环体,否则退出

  3. 基本块0x40078a–0x4007a6是关键的部分。从字符串s=c61b68366edeb7bdce3c6820314b7498中取s[eax],并赋值给寄存器eax,然后赋值给寄存器ecx;如果循环变量的值(存在eax中)为偶数,则eax赋值为0xffffffff,否则赋值为0x1;

  4. 基本块0x4007b4–0x4007c5是主要的部分。寄存器ecx的值加上eax的值,保存在ecx中;这里有个edx寄存器的值给了eax,然后将寄存器ecx的值,也就是当前字符串s的字符赋值给字符串t[rax]。往上溯源看下edx就可以发现,在基本块0x40078a–0x4007a6中,lea edx, [rax+0Ah],edx每次都通过eax来自增1,因此edx是用来偏移字符串t的。

打印一下发现字符串t其实就是flag字符串,格式为ShariCTF{'?'repet 32 times}也就是说,每次循环都经过3和4的操作,通过字符串s的字符与eax寄存器相加以后的字符,对flag字符串中的?进行填充:

XCTF-Reverse-ExerciseArea-010-writeup_第1张图片

用代码解出flag填充的内容:


s = "c61b68366edeb7bdce3c6820314b7498"

res = ""

for i, each in enumerate(s):
    each_ascii = ord(each)

    if i % 2 == 0:
        eax = 0xffffffff
        tmp = eax + each_ascii
        tmp = int("0x" + hex(tmp)[3:], 16)
    else:
        eax = 1
        tmp = eax + each_ascii
    

    tmp = chr(tmp)
    res = res + tmp


print(res)

那么flag为:SharifCTF{b70c59275fcfa8aebf2d5911223c6589}

你可能感兴趣的:(ctf)