몬데...?
#include <stdio.h>
int main(){
unsigned int random;
random = rand(); // random value!
unsigned int key=0;
scanf("%d", &key);
if( (key ^ random) == 0xdeadbeef ){
printf("Good!\n");
system("/bin/cat flag");
return 0;
}
printf("Wrong, maybe you should try 2^32 cases.\n");
return 0;
}
key를 입력받고 key의 랜덤 상수제곱을 해서 0xdeadbeef와 같아야한다.
우선 좀 해봤다고 바로 gdb를 켜봤다.
나름 리버싱 책도 읽고 해서 자신있게 분석해봤는데 여전히 알 수가 없었다.
우선 생각한 공격부분을 말해보자면.
1. random()함수의 값을 조작.(내가 알기로는 random도 일정한 테이블이 있다고 알고 있으므로 같은 값을 추출할 수 있을것)
2. if문의 값을 강제로 0xdeadbeef로 패치
정도를 생각했었다.
여전히 write-up을 참고한다.
random에 취약점이 있는 것이 맞았다. seed값을 정해주지 않으면 같은 값이 나오고, 진짜 랜덤값을 얻으려면 srand(time(NULL))을 써야 한다.
레지스터는 이렇게 보는 구나. 계속 x/i $esp 이렇게 입력했는데 나오지 않았다.
eax에 random의 값이 저장되기 때문에 해당값을 실행해주고 eax를 확인해야한다.
write-up 마다 브레이크 포인트 잡는 게 천차만별이다.
0x0000000000400601 <+13>: call 0x400500 <rand@plt>
해당 함수 실행 다음에만 잡아주면 되는것 같다.
eax = 0x6b8b4567 값이 들어있는것을 확인할 수 있었다.
key ^ 0x6b8b4567 = 0xdeadbeef 가 되고 XOR은 key = 0x6b8b4567 ^ 0xdeadbeef를 만족한다.
3039230856이란 키 값이 나왔다.
Mommy, I thought libc random is unpredictable...
상대적으로 쉽다! 어제 뼈빠지게 고생해서 그런것 같다
passcode가 10pt 짜리 문제였다... 이러니까 어렵지. 앞으로는 점수 적은 순으로 풀어보자
'pwnable' 카테고리의 다른 글
[Toddler's Bottle] flag (0) | 2024.05.11 |
---|---|
[Toddler's Bottle] passcode (0) | 2024.05.11 |
[Toddler's Bottle] mistake (0) | 2024.05.11 |
[Toddler's Bottle] shellshock (0) | 2024.05.11 |
[Toddler's Bottle] black jack (0) | 2024.05.11 |