Fork me on GitHub

pwnable.kr_mistake

题面:

1
2
3
4
5
6
7
8
9
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)

提示这道题的要点是运算符的优先级

连上服务器后发现题目文件夹下有四个文件

1
2
3
4
5
6
mistake@ubuntu:~$ ls -l
total 24
-r-------- 1 mistake_pwn root 51 Jul 29 2014 flag
-r-sr-x--- 1 mistake_pwn mistake 8934 Aug 1 2014 mistake
-rw-r--r-- 1 root root 792 Aug 1 2014 mistake.c
-r-------- 1 mistake_pwn root 10 Jul 29 2014 password

查看一下mistake.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;
}

根据题目的提示运算符我找一些代码中的关键点

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

在这里由于open()的返回值不会小于0,且<的优先级比=高,所以这句语句的结果是open()的返回值!<0,所以open("/home/mistake/password",O_RDONLY,0400) < 0的值为false,因此赋值给fd的时候fd为0,此平台的第一题就是考察的File descriptor,当值为0时执行标准输入,因此实际上代码并不会读password文件,而是等待用户的输入,这就可以让我们来伪造password

1
2
3
4
5
6
xor(pw_buf2, 10);                                        
//对用户的输入xor
if(!strncmp(pw_buf, pw_buf2, PW_LEN)){ //比较xor后的密码与“原”密码
printf("Password OK\n");
system("/bin/cat flag\n");
}

因此我们只需要再fd赋值之后输入自己的10位密码,然后再输入xor后的密码,即可比对成功拿到flag

1
2
3
4
5
6
mistake@ubuntu:~$ ./mistake
do not bruteforce...
1111111111
input password : 0000000000
Password OK
Mommy, the operator priority always confuses me :(
您的支持是我最大的动力🍉