美文网首页
XCTF-reverse-新手练习 writeup

XCTF-reverse-新手练习 writeup

作者: Pig_deng饲养员 | 来源:发表于2019-06-27 09:02 被阅读0次

insanity

  • 自己解题思路:
  1. 拿到代码先使用file工具查看代码类型,显示为ELF32位程序
  2. 使用ida打开程序,反汇编,结果如下,看出程序是输出一个字符串,然后等待,随机化输出结果:


    ida结果.png
  3. 在Linux下给程序赋予权限,运行程序,程序输出结果为随机输出,多运行几次可以程序输出结果不同,其中某次会输出flag。
  • 官方write up :

使用strings insanity | grep flag,即可直接得到答案,使用strings命令和管道过滤可以快速得到flag。

logmein

  1. 使用ida打开程序,结果如下:


    logmein
  2. 由分析可以看出是一个异或程序,字符串长度由v8变量可知为17位。(刚开始时将反斜杠误认为一个字符,后来发现反斜杠是为了转义,因此长度为17位。),写一个c程序即可得出答案,程序为(好久不写c程序都不会写了。。):
#include<stdio.h>

int main()
{
    long long int v7 =28537194573619560;
    int v6 = 7;
    char v8[18] = ":\"AL_RT^L*.?+6/46";
    char s;
    for(int i=0; i<17; i++)
    {
        s =(char) (*((char*)&v7 + i % v6) ^ v8[i]);
        printf("s:%c\n ", s);
    }

    return 0;
}
  1. 总结:刚开始时将&v7以为是取地址符,看了官方write up 才发现v7是16进制字符串harambe,这个字符串在通过strings命令可以找到,自己试着拿这个字符串异或了对应的v8变量得到了前7位数字,没想到是循环异或,因此通过这种暴力破解只得出了一半,其实只要循环异或就可以得到正确答案。。。。 重点:v7字符串!!!!

no-strings-attached

  • 个人思路
  1. file命令查看文件类型为 ELF32位程序。

  2. ida打开程序,找到main函数,可以看到main函数主要为4个函数,Linux下运行程序,程序提示输入验证信息,程序输出和main函数的4个函数对比,可以看出authenticate为主要的函数,进入该函数,伪码如下,分析authenticate函数代码,可以看出程序从用户处得到一个输入ws,然后将wss2比较,如果相同显示成功,否则显示失败,因此可以得知flag即为s2的内容,而s2的内容由decrypt函数返回:

    main.png
    authenticate.png
  3. 分析decrypt程序伪代码,伪代码如图所示:

    decrypt函数.png

程序大致逻辑为:
看while循环中的内容,v7为a2字符串的长度,dest为字符串s的复制,
for循环逻辑为 s的当前内容减去a2的内容,
由authenticate函数调用可知,a2为0x0102030405,
s为0x3a36373b807a717863667367626573606b71786a737064786e70706470646e7b76786a737b80
长度明显不对等,因此猜测这里是循环相减.

  1. 写一个python脚本印证猜测:
s  = '0102030405010203040501020304050102030405010203040501020304050102030405010203'
s1 = '3a36373b807a717863667367626573606b71786a737064786e70706470646e7b76786a737b80'

result = ''
for c in range(0, len(s1), 2):
    a = int(s1[c:c+2], 16) - int(s[c:c+2], 16)
    result += chr(a)

print(result)

最后结果明显是flag的格式,因此猜测成立~
核心逻辑就是s字符串减去a2字符串的值,长度不够时a2循环往复。

  • 官方wp
  1. 通过ida分析可以看到函数逻辑在decrypt,即该函数返回结果即为flag。因此考虑使用Gdb工具的查看内存功能。
  2. gdb调试打开程序,在decrypt处下断点。
  3. r运行程序,进行单步调试n选项,不进入函数内部,由刚刚的逻辑可知此处运行结果应该已经得到flag,因此查看程序内存。
  4. info reg命令可以查看当前函数内部寄存器状态和内存,函数的返回结果存放在eax寄存器中,因此将eax寄存器内容打印就是flag。
  5. x/286x $eax命令将eax寄存器内容打印出来,转换为字符串即为flag。 (x/40cw $eax命令更直观)
    具体过程如下图所示:
    gab调试1.png
    gdb调试2.png

python-trade

该题是一个pyc文件,本质就在于反编译pyc文件,使用工具为uncompylepyc反编译工具使用)。

  1. 通过反编译pyc文件,得到的py源码如下:


    pyc反编译结果.png
  2. 分析源代码可知,程序将flag通过encode函数加密后和字符串correct比较,因此flag即为对字符串correct进行解密。
  3. 写出如下解密函数:
def decode(s):
    flag = ''
    for i in s:
        x = ord(i) - 16
        x ^= 32
        flag += chr(x)

    return flag

correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
result = decode(base64.b64decode(correct))
  1. result即为最终flag。

查看了官方wp后,发现有一个在线反编译网站https://tool.lu/pyc/

csaw2013reversing2

  • 个人wp
    (菜鸡每次都靠蒙。虽然结果是对的,但是不是很明白原理23333)
  1. 拿到程序先运行,可以看到正如题目中描述的一样,弹出一个flag标识的框,但是框中文字却是乱码。
  2. ida进行分析,查看伪码,main函数伪码如图所示,由伪码可以分析出memcpy_s处的unk_409B10处就应该为程序flag,查看了以后仍然是伪码,继续往下查看逻辑发现有一处if语句,语句大概可以判断出这里会有一个退出进程,因此考虑使用动态调试。
    main.png
  3. 使用ollydbg工具进行动态调试(原因是ida的动态调试不是很熟悉,没有Ollydbg用起来顺手),调试到如下位置处,可以发现程序会直接跳转到刚刚的进程退出函数,程序退出,如图:


    原来的代码.png
  4. 将009B10A3处的JMP指令修改为NOP指令,不让程序跳转,让程序顺序执行,接下来会有一个弹窗函数,修改后查看堆栈内容,此时text为空,弹窗显示的也是空信息。
  5. 可以看到接下来还有一个MessageBoxA函数,因此将第一个弹窗函数也NOP掉,运行程序,运行到009B10C4处即可看到flag,修改的程序代码如下所示:
    修改后的代码.png
  6. 完成题目后又对ida的图形结构分析,可以看出第一个弹窗函数是烟雾信息,迷惑用的,没有任何信息含量。如图:


    ida图结构分析.png
  • 官方wp
    通过Ida分析可知,sub_4010EF处为解密函数,因此程序需要通过该函数才能顺利显示出flag。
    修改相关指令,
    修改int 3NOP.
    修改 jmp short loc_4010EFjmp short loc_4010B9.
    修改jz short loc_4010B9jmp short loc_401096.
    修改指令的步骤为edit->Patch programs->Assemble然后保存,保存的步骤为edit->Patch programs->Apply Patches to Input file,然后运行程序,即可得到flag,修改后的程序图如下:
    修改后的ida图结构.png

相关文章

网友评论

      本文标题:XCTF-reverse-新手练习 writeup

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