吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7433|回复: 19
收起左侧

[CTF] 攻防世界 reverse 的logmein writeup

[复制链接]
上山砍大树 发表于 2019-11-14 16:09
图显示不出来吗。
分析如上图:
[C] 纯文本查看 复制代码
  if ( v3 < strlen(v8) ) 
    quit();

这里可以判定输入字符串长度>=strlen(v8);
[C] 纯文本查看 复制代码
if ( i >= strlen(v8) )
      quit();

这样的话就可以最终确定:strlen(input_string)==strlen(v8),确定了input_string的长度为17。

既然
[C] 纯文本查看 复制代码
input_string[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i])

就判断是错误,说明每一个输入的字符都需要跟后面算出来的结果相比对,对比成功才能得到
[C] 纯文本查看 复制代码
printf("You entered the correct password!\nGreat job!\n");


所以想要得到正确的输入,通过对比的内容(像面镜子)就可以得到了。
那我们就看看这个对比度内容是什么:
[C] 纯文本查看 复制代码
(char)(*((_BYTE *)&v7 + i % v6) ^ v8[i])

咱们先看看里面的参数:
  • v6=7;
  • v8=“:\"AL_RT^L*.?+6/46”;
  • v7
咱们一起来看看v7:类型是_int64,v7保存的数据是28537194573619560LL,证明这是一个long long int类型的数据。
int64的64可能是因为一个long long int数据占8byte=64bit的长度。(测算方法:
[C] 纯文本查看 复制代码
 printf("\n\n%d",sizeof(long long int));
//输出结果为8,即8byte

但是上面需要的是char类型的(&v7+偏移量)来确定字符,并不需要int类型的数据,那么这是怎么回事呢?看下面的分析:
(*byte)==>(char *)类似于强制类型转换,&v7也就是将保存v7数据的地址提出,然后(_BYTE *)&v7可以用另一种更简单的方式理解:
[C] 纯文本查看 复制代码
   char *target=(char *)&v7;
就是定义一个指针指向v7的首地址。
这样(指针+数字)的组合就是数组的索引方式,所以&v7+i==&v7(这部分是指针方面的知识)。
那么v7由int64转化到char类型后,(&v7+数字偏移量)索引到的应该是什么呢?这就不得不提到了数据在内存中存储的方式了:
long long int v7=28537194573619560,但是v7在内存中是以字节为单位存储的,把v7转化为16进制为:0x65626D61726168;
在内存中存储的方式是小端存储(little-endian),如图:

好像又没图了,不过我还能讲。接下来就是强制转化为字符形式,然后访问内部成员,数组需要从(首地址(即低地址)+偏移)来索引数据,所以索引出的(char *)v7="harambe";
明白了上面的指针和强制类型转化,小端序存储后,
[C] 纯文本查看 复制代码
input_string[i] = (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i])
就很容易掌握了算法了,然后我们直接用c写两个程序把input_string字符串整理出来:
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char v8[]=":\"AL_RT^L*.?+6/46";//strlen(v8)==strlen(input_string)
    long long int v7=0x65626D61726168;

    int i;
    /*将long long int转化为字符类型
注意理解小端序存储方式和指针索引数据*/
    char *target=(char *)&v7;

    char final_string[20];
    for(i=0;i<strlen(v8);i++)
    {
        final_string[i]=target[i%7]^v8[i];
        printf("%c",final_string[i]);
    }
    return 0;

}


这样就可以得到flag为
[C] 纯文本查看 复制代码
RC3-2016-XORISGUD


当然也可以这样做:
[C] 纯文本查看 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
    long long int v7=0x65626D61726168;
    char a[]=":\"AL_RT^L*.?+6/46";
    char input_string[20];

    for(int i=0;i<strlen(a);i++)
    {
        input_string[i]=(char)(*((char *)&v7 + i%7)^a[i]);
        printf("%c",input_string[i]);
    }
    printf("\n\n%d",sizeof(long long int));
    return 0;
}


可以对比一下,哪些是可以相互替代的,更容易加深对指针和数组关系的理解。

main反汇编.jpg

main反汇编.jpg

v7在内存中的存储方式

v7在内存中的存储方式

免费评分

参与人数 7吾爱币 +12 热心值 +6 收起 理由
Kv1n + 1 用心讨论,共获提升!
Hmily + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
chumen77 + 1 + 1 用心讨论,共获提升!
笙若 + 1 + 1 用心讨论,共获提升!
oxsho + 1 用心讨论,共获提升!
loser. + 1 + 1 用心讨论,共获提升!
bei133 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2019-11-14 16:56
 楼主| 上山砍大树 发表于 2019-11-14 17:20
Hmily 发表于 2019-11-14 16:56
https://www.52pojie.cn/misc.php?mod=faq&action=faq&id=29&messageid=36 看这个学习下贴图。

ok我看看修改一下
哲别冰 发表于 2019-11-14 19:59
kao2288 发表于 2019-11-14 23:14
下载一个看看
Shiroi14 发表于 2019-11-15 00:50

不明觉厉
aj2002214 发表于 2019-11-15 11:21
下载一个看看
ctf513 发表于 2019-11-15 14:00
前来学习!!!!!!
2Burhero 发表于 2019-11-15 15:20
暖贴小能手
避世狗熊 发表于 2019-11-15 15:30
不明觉厉,修改试试
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 21:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表