Pwnable.kr-mistake 这一关HINT已经给了,但是光看C真的很难分析出来

题目分析

根据所给信息

We all make mistakes, let’s move on.
(don’t take this too seriously, no fancy hacking skill is required at all)

This task is based on real event
Thanks to dhmonkey

hint : operator priority

ssh mistake@pwnable.kr -p2222 (pw:guest)

连接远程环境,下载 C 文件和二进制文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <stdio.h>
#include <fcntl.h>

#define PW_LEN 10
#define XORKEY 1

void xor(char* s, int len){
int i;
for(i=0; i<len; i++){
s[i] ^= XORKEY;
}
}

int main(int argc, char* argv[]){

int fd;
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){
printf("can't open password %d\n", fd);
return 0;
}

printf("do not bruteforce...\n");
sleep(time(0)%20);

char pw_buf[PW_LEN+1];
int len;
if(!(len=read(fd,pw_buf,PW_LEN) > 0)){
printf("read error\n");
close(fd);
return 0;
}

char pw_buf2[PW_LEN+1];
printf("input password : ");
scanf("%10s", pw_buf2);

// xor your input
xor(pw_buf2, 10);

if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
printf("Password OK\n");
system("/bin/cat flag\n");
}
else{
printf("Wrong Password\n");
}

close(fd);
return 0;
}

可以看出来逻辑还是比较清楚的,就是会读取 password 文件的十个字节,异或 1 之后和你的输入比较,如果相等给 flag,在外面,它权限设置是没有问题的,二进制文件给了 s 权限位,password 对于普通用户也是不可读的。

但是问题是在这个运算

1
fd=open("/home/mistake/password",O_RDONLY,0400) < 0

因为 = 的优先级比较低,因此它先一步算出来 fd<0 为假,值为 0,因此我们的 fd=0 就会在打开文件成功的时候恒成立。fd=0 使用 read 读取将读取标准输入的字符,也就是我们的输入。

因此我们随便给两串异或起来结果为 1 的即可。

题解

连接远程环境,输入 00000000001111111111 即可获得 flag。

flag:Mommy, the operator priority always confuses me :(