Security/DreamHack
[DreamHack] Broken Password #634
고간디
2024. 6. 14. 12:35
int __fastcall main(int argc, const char **argv, const char **envp)
{
int fd; // [rsp+Ch] [rbp-44h]
_QWORD *v5; // [rsp+10h] [rbp-40h] BYREF
__int64 v6; // [rsp+18h] [rbp-38h] BYREF
char s2[40]; // [rsp+20h] [rbp-30h] BYREF
unsigned __int64 v8; // [rsp+48h] [rbp-8h]
v8 = __readfsqword(40u);
proc_init();
fd = open("/dev/urandom", 0);
read(fd, password, 8uLL);
close(fd);
puts("can u guess me?");
sleep(0);
read_input(s2, 32);
if ( !strncmp(password, s2, 8uLL) )
{
system("cat flag");
}
else
{
puts("wrong... :p");
puts("can you try another path? maybe impossible");
printf("> ");
read_input(&v5, 8);
printf("> ");
read_input(&v6, 8);
*v5 = v6;
puts("wish your happy sleep");
}
return 0;
}
prob 파일 하나만 주어진다.
else 문에 있는 포인터 때문에 저걸로 문제를 풀어야 하는 걸까 고민했었는데 솔직히 저걸로 풀어내는 건 말이 안 된다 생각했다..
/dev/urandom은 난수를 뽑아낸다.
뽑아낸 난수가 아마 password 변수로 들어가는 것 같다.
strncmp() 함수를 사용해 입력한 값이 password와 일치하면 플래그를 출력해준다.
#include <string.h>
int strncmp(const char *string1, const char *string2, size_t count);
두 문자열을 비교하는데 NULL 문자, \0으로 문자열이 끝날 때까지만 비교를 수행한다.
string1이 sting2보다 작으면 음수, 같으면 0, 크면 양수를 리턴한다.
주어진 문제에서는 0 을 반환해야 플래그를 얻어낼 수 있다.
세 번째 인수로 비교 길이를 전달해주더라도 널 문자를 만나게 되면 비교가 종료된다.
이를 이용해서 문제를 풀어내야 한다.
/dev/urandom은 계속해서 값이 바뀌는 난수를 꺼내온다.
입력값으로 그냥 엔터를 주면 \0이랑 문자열 비교가 이루어진다.
이때 /dev/urandom의 난수의 첫 값이 00이면 \00랑 비교했을 때 0을 바로 반환하게 된다.
하지만 /dev/urandom을 내 맘대로 조작할 수는 없기 때문에 첫 값이 00인 난수가 뽑일 때까지 계속해서 시도해봤다.
256번 시도하면 적어도 1번은 00이 등장할 것이다.
계속 엔터값만을 보내다 보면 이렇게 플래그를 얻을 수 있다.
728x90
반응형