Pwnablekr_Toddlers Bottle_mistake

ssh로 접속하면 소스파일과 실행파일이 있다.

이 C 코드의 원래 목적은 password라는 이름의 파일을 열고, 내용을 읽은 뒤 그것을 사용자가 입력한 입력값과 비교하는 것이다. 하지만 코드에 오류가 있어서 원하는 대로 작동하지 않는다.
C 코드 핵심 알고리즘은 다음과 같다.
- 파일을
open한다. read함수로 읽어들인다.scanf함수로 10글자의 비밀번호를 입력 받는다.- 입력받은 비밀번호를 1과 XOR하여 인코딩한다.
read함수로 읽은 비밀번호와 입력 받고 인코딩한 비밀번호를 비교한다. 맞으면 성공.
이 코드에서 잘못된 점은 다음과 같다.

이 코드가 정상적으로 작동하도록 하기 위해서는
if((fd=open("/home/mistake/password", O_RDONLY, 0400)) < 0) 로 써야 한다.
괄호를 추가하여 fd에 open의 결과값을 대입하는 연산을 먼저 하도록 해야 한다.
이 잘못된 코드로 인해 fd에는 비교 연산자의 결과가 저장된다. open함수가 정상적으로 호출되면 파일 디스크립터를 반환한다.
이는 0보다 크므로, 0보다 작은 지 비교하는 연산은 false를 반환한다. 따라서 fd에는 false에 해당하는 0이 저장되게 된다.

이 코드는 위의 코드에서 생성된 잘못된 fd(0이 저장되어 있음)를 이용하여 read를 하는 코드이다. 파일디스크립터 0번은 STDIN으로 정의되어 있다. 따라서, 이 read 함수는 STDIN에서 데이터를 읽게 된다. password 파일에 무엇이 적혀있든 상관 없다.
결론적으로 STDIN으로 입력한 값에 XOR 인코딩을 적용한 값을 입력하면 우회할 수 있다. 주의할 점은 문자열은 10글자여야 한다는 점이다. 문자열 길이가 10임을 가정하고 XOR와 strncmp를 적용하고 있기 때문이다.

A(아스키코드 0x41)을 read함수의 입력값으로 이용했다. 0x41과 1을 XOR하여 나오는 값인 0x40에 해당하는 문자는 @이다. 이를 scanf 입력값으로 이용했다.
flag는 Mommy, the operator priority always confuses me :( 이다.