보안/System Hacking
[pwnable.kr] collision
melonbbang-ruffy
2025. 2. 18. 18:09
https://pwnable.kr/play.php
pwnable.kr
md5 hash collision 문제인듯
서버로 접속해 들어가보자.
flag 파일이 보이는데 r--r----- 권한인 것을 보아 파일 소유자 / 루트 계정 아니면 열 수 없을듯
col.c 코드를 살펴보자
code
더보기
#include <stdio.h>
#include <string.h>
unsigned long hashcode = 0x21DD09EC;
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
int main(int argc, char* argv[]){
if(argc<2){
printf("usage : %s [passcode]\n", argv[0]);
return 0;
}
if(strlen(argv[1]) != 20){
printf("passcode length should be 20 bytes\n");
return 0;
}
if(hashcode == check_password( argv[1] )){
system("/bin/cat flag");
return 0;
}
else
printf("wrong passcode.\n");
파일을 실행할 경우 -> 사용자의 입력값을 받아 passcode와 비교한다.
passcode는 20바이트의 크기를 가지고 있는 것으로 보이고, 20바이트 문자열을 5개의 4바이트 정수로 변환 후 덧셈 연산을 수행하기 때문에 원하는 합(0x21DD09EC)을 만들어내는 임의의 20바이트 문자열을 만들어 낼 경우 플래그 값을 알아낼 수 있을것으로 보인다.
null = 0x00
null 값을 제외한, 각 5개의 4바이트로 이루어진 수를 조합할 때 hashcode인 0x21dd09ec 보다 작은 임의의 무작위 값을 만들고, hashcode에서 해당 수를 뺀 값을 16진수로 나타낸 후, 리틀 엔디언 형식으로 순서를 바꿔서 해당 파일을 실행할 때 인자로 넣어주면 될 듯 하다
Exploit
payload는 다음과 같다.
4바이트 임의의 정수를 0x08 이라고 하자. 해당 정수를 4개 생성하고, 0x08080808 을 hashcode 값에서 빼 보자.
0x01bce9cc가 나온다.
리틀 엔디언 형식이므로 0xCC 0xE9 0xBC 0x01 이런 식으로 보내야 될듯
payload는 다음과 같다.
./col "$(python -c 'import sys; sys.stdout.write("\x08"*16 + "\xCC\xE9\xBD\x01")')"
플래그 획득