PWNABLE_02_hash

PWNABLE_02_hash

linux_hash 缺陷代码如下:

#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}

int main(int argc, char* argv[]){
        if(argc<2){
                printf("usage : %s [passcode]\n", argv[0]);
                return 0;
        }
        if(strlen(argv[1]) != 20){
                printf("passcode length should be 20 bytes\n");
                return 0;
        }

        if(hashcode == check_password( argv[1] )){
                system("/bin/cat flag");
                return 0;
        }
        else
                printf("wrong passcode.\n");
        return 0;
}

  1. hint: hash collision
  2. guest用户无flag文件执行权限,代码中如果hashcode == check_password( argv[1] )执行成功会输出flag结果。
  3. 需要令res的值为0x21DD09EC(十进制568134124)
  4. check_password将输入的argv1分为五份,并且相加起来
  5. 应该是四个113626825加上一个113626824
  6. 也就是四个06c5cec9加上一个06c5cec8
  7. 所以argv1应设置为\x06\xc5\xce\xc9\x06\xc5\xce\xc9\x06\xc5\xce\xc9\x06\xc5\xce\xc9\x06\xc5\xce\xc8
  8. 但C语言的编译器默认为小端存储,所以我们需要倒置输入的排序
  9. 最终应输入的16进制字符串如下: \xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc9\xce\xc5\x06\xc8\xce\xc5\x06
  10. 最终执行,结果如下:
col@pwnable:~$ ./col `python -c "print 4*'\xc9\xce\xc5\x06'+'\xc8\xce\xc5\x06'"`
daddy! I just managed to create a hash collision :)

check_password()不太明白的点

unsigned long check_password(const char* p){
        int* ip = (int*)p;
        int i;
        int res=0;
        for(i=0; i<5; i++){
                res += ip[i];
        }
        return res;
}
  • const char* p
    const表示不可修改,char是字符型,*是个指针
    这里还有三种情况:
    const char *p// 声明一个指向字符或字符串常量的指针(p所指向的内容不可修改)
    char const *p// 同上
    char * const p//声明一个指向字符或字符串的指针常量,即不可以修改p的值,也就是地址无法修改。
  • (int*) p是啥意思
    将p强制类型转换为int型指针,之前是字符型指针
  • res += ip[i]循环了五次,也就是说res的结果是ip指向地址第一到五位的和,但输入长度是20,程序是如何确定一次读4的长度的
    输入20字节=5×int=20×char
    当通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。 我是int型指针,我指的是int,他在内存里占4个字节。

    这里是由于指针类型被强制转换了,所以循环5次,如果是16位编译器,int长2,那就还得循环10次。
    这里并不是均分,+1后除5好计算,其他计算方法只要五次相加后和是0x21DD09EC均可。
    最后一句,程序确定了一次读4个字节的长度,因为从指向一个字节的字符指针,变成了指向四个字节的int指针。读的最小单位一直是“一个”,但种类有所不同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Python中,`__hash__()`是一个特殊方法(也称为魔术方法),用于定义对象的哈希值。哈希值是一个唯一的整数,用于在集合(如字典、集合)中快速查找和比较对象。 当我们在自定义类中没有定义`__hash__()`方法时,默认情况下,对象的哈希值是根据对象的内存地址计算的,即`id(obj)`。这意味着相同的对象可能具有不同的哈希值,因为它们在内存中具有不同的地址。 如果我们想要自定义一个类的哈希值,可以在类中实现`__hash__()`方法。这个方法应该返回一个整数,用于表示对象的哈希值。 下面是一个简单的示例,展示了自定义类中`__hash__()`方法的使用: ```python class Student: def __init__(self, name, age): self.name = name self.age = age def __hash__(self): # 自定义哈希值为年龄的平方 return self.age ** 2 student1 = Student("Alice", 20) student2 = Student("Bob", 25) print(hash(student1)) # 输出:400 print(hash(student2)) # 输出:625 ``` 在上述示例中,我们定义了一个`Student`类,并在其中实现了`__hash__()`方法,计算哈希值为年龄的平方。通过调用`hash()`函数,我们可以获取对象的哈希值并进行打印。 需要注意的是,如果一个类定义了`__hash__()`方法,那么它也必须定义`__eq__()`方法,用于对象的相等性比较。这是因为哈希值只能用于快速查找,而对象的相等性比较需要通过`__eq__()`方法来确定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值