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
반응형
'Security > DreamHack' 카테고리의 다른 글
[Dreamhack] Windows Search #729 (0) | 2024.11.05 |
---|---|
[DreamHack] Reversing Basic Challenge #0, #1, #2, #3 (#14, #15, #16, #17) / 어셈블리어 / 악성코드 분석 방법 (0) | 2024.04.04 |
[Dreamhack] ROT128 #852 (0) | 2024.04.03 |
[DreamHack] addition-quiz #1114 (0) | 2024.03.30 |
[DreamHack] Path Finder #702 (0) | 2024.03.30 |
댓글