Cryptoversing

发布日期:2019年02月10日 类别:reversing 题目来源:ctflearn.com 题目链接:https://ctflearn.com/problems/667 (需要注册登录)

将题目中的程序下载下来,运行后提示输入密码:

dontpanic@Win:~$ ./xor.bin
[*] Hello! Welcome to our Program!
Enter the password to contiune:  abcd
[-] Wrong Password
点击此处显示 Writeup
点击此处隐藏 Writeup

使用 Cutter 载入 xor.bin,照例先看一下字符串:

strings

看一下 Successful Login 的交叉引用,只在 main 函数里使用了。往上翻一翻,看起来所有的验证逻辑都在 main 函数中。首先看一下函数开始的部分:

这里其实是在向 local_a0h (即 $rbp-0xa0) 进行字符串赋值。将几个字符串拼起来之后就是 h_bO}EcDOR+G)uh(jl,vL。需要注意的是这里没有设置字符串终止的 \0

再往下就是计算的主要逻辑部分:

|           0x0000087b      mov  dword [local_b8h], 0x10
|           0x00000885      mov  dword [local_b4h], 0x18
|           0x0000088f      lea  rax, [s]
|           0x00000893      mov  rdi, rax ; const char *s
|           0x00000896      call sym.imp.strlen ; size_t strlen(const char *s)
|           0x0000089b      shr  rax, 1
|           0x0000089e      mov  dword [local_b0h], eax
|           0x000008a4      lea  rax, [s]
|           0x000008a8      mov  rdi, rax ; const char *s
|           0x000008ab      call sym.imp.strlen ; size_t strlen(const char *s)
|           0x000008b0      mov  dword [local_ach], eax
|           0x000008b6      mov  dword [local_a8h], 0
|           0x000008c0      lea  rax, [s]
|           0x000008c4      mov  rdi, rax ; const char *s
|           0x000008c7      call sym.imp.strlen ; size_t strlen(const char *s)
|           0x000008cc      shr  rax, 1
|           0x000008cf      mov  dword [local_a4h], eax
|           0x000008d5      mov  dword [local_cch], 0
|       ,=< 0x000008df      jmp  0x968
|       |   0x000008e4      mov  eax, dword [local_cch]
|       |   0x000008ea      cdqe
|       |   0x000008ec      mov  eax, dword [rbp + rax*4 - 0xa8]
|       |   0x000008f3      mov  dword [local_c8h], eax
|      ,==< 0x000008f9      jmp  0x94a
|      ||   0x000008fb      mov  eax, dword [local_c8h]
|      ||   0x00000901      cdqe
|      ||   0x00000903      movzx eax, byte [rbp + rax - 0x60]
|      ::   0x00000908      movsx eax, al
|      ::   0x0000090b      mov  dword [local_bch], eax
|      ::   0x00000911      mov  eax, dword [local_cch]
|      ::   0x00000917      cdqe
|      ::   0x00000919      mov  eax, dword [rbp + rax*4 - 0xb8]
|      ::   0x00000920      mov  edx, eax
|      ::   0x00000922      mov  eax, dword [local_bch]
|      ::   0x00000928      xor  eax, edx
|      ::   0x0000092a      mov  byte [local_cdh], al
|      ::   0x00000930      mov  eax, dword [local_c8h]
|      ::   0x00000936      cdqe
|      ::   0x00000938      movzx edx, byte [local_cdh]
|      ::   0x0000093f      mov  byte [rbp + rax - 0x80], dl
|      ::   0x00000943      add  dword [local_c8h], 1
|      ::   0x0000094a      mov  eax, dword [local_cch]
|      ::   0x00000950      cdqe
|      ::   0x00000952      mov  eax, dword [rbp + rax*4 - 0xb0]
|      ::   0x00000959      cmp  dword [local_c8h], eax
|      `==< 0x0000095f      jl   0x8fb
|       :   0x00000961      add  dword [local_cch], 1
|       :   0x00000968      cmp  dword [local_cch], 1
|       `=< 0x0000096f      jle  0x8e4

仔细读一下这段代码,可以看出这是一个两层的循环。写出对应的 C 语言代码如下:

可以看出,这段代码的基本操作就是把字符串的前半段与 0x10 异或、后半段与 0x18 异或,将结果存入 local_80 数组中。

再向下就是检查结果了:

写出对应的 C 语言代码如下:

只是很简单的比较。因此我们将h_bO}EcDOR+G)uh(jl,vL的前半段与 0x10 异或,后半段与 0x18 异或:

这样就能够得到 flag 了。

dontpan1c 的 CTF 笔记
南阳一出即相,淮阴一出即将。

知识共享许可协议

本站所有作品均采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本站不包含明令禁止公开解题过程的题目。

本站由 Jekyll 强力驱动。