January 07, 2017

pwnable.kr collision solution


해설> 아버지는 오늘 내게 MD5 해시 충돌에 대해 알려주었다.
뭔가 그런 비슷한 것을 해보고 싶다!

The home directory for the col account contains col, col.c, and flag files. The result of compiling the col.c file seems to be the col file.
col 계정의 홈 디렉터리에는 col, col.c, flag 파일이 있다. col.c 파일의 컴파일 결과가 col 파일인 것으로 추정된다.




The contents of the col.c file are shown in the image above. This program executes the flag file if the hashcode value and the return value(=res) of the check_password() function are the same.
col.c 파일을 열어보면 위 그림과 같다. 이 프로그램은 hashcode 값과 check_password 함수의 리턴 값(=res)이 동일하면 flag 파일을 실행한다.

The owner of the col file is col_pwn, and the sticky-bit is set to control the flag file.
col 파일의 소유자는 col_pwn이며 sticky-bit가 설정되어있어 flag 파일을 제어할 수 있다.

The string length of argv[1] should be 20.
argv[1]의 문자열 길이는 20이어야 한다.

The data type of argv[1] is changed at the check_password() function(char * → int *). Since char is a 1 Byte data type and int is a 4 Byte data type, the data in p[0] ~ p[19] is stored in ip[0] ~ ip[4].
argv[1]은 check_password() 함수에서 데이터 형식이 변경된다(char * → int *). char는 1 Byte 데이터 형식이고 int는 4 Byte 데이터 형식이기 때문에, p[0] ~ p[19]에 들어있던 데이터는 ip[0] ~ ip[4]에 저장된다.

The flag file can be read only if the value of ip[0] + ip[1] + ip[2] + ip[3] + ip[4] is 0x21DD09EC. When dividing 0x21DD09EC by 5 and setting it to 20 bytes, it is 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CECC(=0x21DD09EC * 5 + 4).
ip[0] + ip[1] + ip[2] + ip[3] + ip[4]의 값이 0x21DD09EC면 flag 파일을 열람할 수 있다. 0x21DD09EC를 5로 나누고 20byte로 맞추면, 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CECC 이다(=0x21DD09EC * 5 + 4).




Pwnable.kr Linux uses little endian. The "Int* ip = (int*)p;" code puts four p's(1 Byte * 4) in the ip(=4 Bytes). In this case, the p is input each 1 Byte inversely. So, when you input argument argv[1], you have to input each 1 Byte inversely to operate as intended.
pwnable.kr 리눅스는 리틀엔디을 사용한다. "int* ip = (int*)p;" 코드는 ip(=4 Byte)에 4개의 p(1 Byte * 4)를 입력한다. 이 때 p는 1 바이트씩 역으로 입력된다. 그래서 argv[1] 아규먼트 입력 시 1byte 단위로 역으로 입력해야 의도대로 동작한다.

You can enter 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CECC using "echo -e" or 0x6C5CEC8 * 4 + 0x6C5CECC using "python -c 'print'". This method is to input each 1 byte ASCII code with exactly 20 characters. Now clear the level by entering the key that appears.
"echo -e"를 이용하여 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CEC8 + 0x6C5CECC를 입력해도 되고, "python -c 'print'"를 이용하여 0x6C5CEC8 * 4 + 0x6C5CECC로 입력해도 된다. 이 방법은 1 Byte 단위로 ASCII 코드를 입력하는 방식이며, 정확히 20글자가 된다. 이제 나오는 키를 입력하여 레벨 클리어.

ps.
□When you use perl( perl을 사용할 경우) : ./col `perl -e 'print "\xC8\xCE\xC5\x06"x4,"","\xCC\xCE\xC5\x06"'`