<phase_1> - string comparision
0x555555556a50 에 있는 문자열이 “All your base are belong to us.” 이고, strings_not_equal함수에 해당 문자열을 넘겨주고 입력 받은 문자열과 해당 문자열을 비교해서 같으면 retq로 넘어감을 알 수 있었습니다.
Answer : All your base are belong to us.
<phase_2> - loops
6개의 숫자를 입력 받고 가장 먼저 입력 받은 수(%rsp)와 1을 비교해서 같지 않다면 bomb입니다.
따라서 첫 번째 숫자는 1임을 알 수 있었습니다.
%rsp(입력 받은 배열의 첫 부분)을 %rbx에 넘겨주고 %rbp 에는 배열의 마지막 주소값을 넘겨줍니다.
Loop 부분입니다.
%rbx는 입력 받은 배열의 현재 index라고 볼 수 있습니다.
<+56>의 cmp를 통해서 %rbp(배열의 마지막 주소값)에 도달하면 retq가 있는곳으로 점프합니다.
현재 인덱스에 있는 값을 %eax에 넘겨주고, %eax += %eax가 실행되고 계산된 %eax값이 다음 인덱스의 배열에 있는 값과 같다면 loop의 시작지점으로 돌아갑니다.
따라서 1부터 시작하는 2의 거듭제곱을 6개 나열한 것이 답이 됩니다.
Answer : 1 2 4 8 16 32
<phase_3> - conditionals/switches
숫자 2개를 입력받음을 알 수 있습니다.
첫 번째 숫자는 1이상 7이하임을 알 수 있습니다.
%eax에 0을 입력 후, %eax – 0x2b3 + 0x214 – 0x158 + 0x158 - 0x158 + 0x158 - 0x158 를 계산한 값(-503)과 %rsp의 두번째 숫자를 비교해서 같으면 retq로 넘어갑니다. <+128>을 보면 첫 번째 입력값과 5를 비교하므로 첫 번째 숫자는 1이상 5이하임을 알 수 있습니다.
Answer : 1 -503
<phase_4> - recursive calls and the stack discipline
Phase_3과 마찬가지로 숫자 2개를 입력 받습니다
첫 번째 숫자는 0xe이하이다.
Func4함수의 인자로 (0xe, 0, 첫 번째 입력) 넘겨줍니다.
<+79>를 보면 두 번째 입력 숫자가 5인 경우에만 retq로 넘어감을 알 수 있습니다. 따라서 두 번째 입력은 ‘5’임을 알 수 있었습니다.
<+74>를 보면 func4의 결과 값(%rax)은 5가 되어야 함을 알 수 있습니다.
Func4 함수로 넘어갑니다.
<+40>과 <+52>에 func4 함수를 호출하는 경우가 있기 때문에 func4는 재귀함수 임을 알 수 있습니다. <+57>을 보면 %eax = 1 + 2*%rax가 됨을 알 수 있습니다.
Phase_4의<+74> 조건을 보아 %eax가 5가 되려면 가장 먼저 실행된 func4는 %rax로 1을 받고 재귀호출을 끝내야 함을 알 수 있습니다.
Func4의 핵심은 %esi가 시작점, %edx가 끝점, %ecx가 둘의 중간점이 되고 %ecx와 %edi가 같을 때 까지 절반씩 범위를 줄여나가는 이분탐색임을 알 수 있습니다. %eax = 1 + 2*%rax 식을 통해서 재귀함수는 2번 수행되어야 하고, [0, 14]에서 이분탐색을 2번 실행하면 10을 얻을 수 있습니다.
Answer : 10 5
<phase_5> - pointers
길이가 6인 문자열을 입력 받아야 함을 알 수 있습니다.
<+33> 부터 <+49>는 loop입니다. 임의의 문자열 ex) abcdef, ghijkl 등을 입력하고
반복문들 돌면서
왼쪽과 같은 결과를 얻어냈습니다.
<+51>을 보면 알파벳들의 합이 0x37인 경우에 끝이 나므로 0x37을 만드는 문자열이 답이 됩니다.
One of Answers : adejcp
<phase_6> - linked lists/pointers/structs
6개의 숫자를 받습니다.
노드에 저장된 숫자를 모두 확인했습니다. Node6는 바로 나오지 않아 node5와 연결된 주소를 통해 값을 알아냈습니다.
(%rbx)는 현재 보고있는 숫자입니다.(입력한 숫자 순서)
%rax는 다음에 볼 숫자입니다.(입력한 숫자 순서)
(%rbx)가 %eax보다 더 작다면 폭발합니다.
따라서 우리가 입력하는 6개의 숫자는 이미 저장된 배열을 어떤 순서로 읽어 들일지를 정하는 입력이고, 입력한 순서에 따라서 배열을 읽는데 내림차순으로 읽어야 함을 알 수 있습니다.
Answer : 2 5 4 6 3 1
<secret_phase> - BST(Binary Search Tree)
Phase_defused 함수를 disas해보면 phase_4에서 2개의 숫자를 입력 받는 것 대신에 문자열을 추가로 입력하면 입력 받은 문자열과 “DrEvil”을 비교해서, 같으면 secret_phase를 실행합니다.
입력 받은 숫자가 0x3e8보다 크면 폭발합니다.
주어진 노드의 첫 번째 값은 0x24(36)임을 알 수 있고, 연결된 2개의 노드 주소(0x55758170, 0x55758190)을 통해서 다음 값들을 알 수 있습니다. 연결된 노드가 없을 때까지 찾아본 결과
아래 그림과 같이 나타남을 알 수 있었습니다
Fun7코드를 보면 입력 값 보다 현재 노드가 크다면 왼쪽으로 움직이고 %eax *= 2가 수행됩니다.
입력 값 보다 현재 노드가 작다면 오른쪽으로 움직이고 %eax = 1 + 2*%eax가 수행됩니다.
Fun7의 리턴값이 4인 경우에 retq로 이동할 수 있으므로
36에서 7을 찾는 과정을 수식으로 나타낸다면
2 * (2 * (0 + 1)) = 4가 되어 해결 할 수 있습니다
Answer : 7
'CS > SystemSoftware' 카테고리의 다른 글
SystemSoftware - Buffer OverFlow #2 (0) | 2021.05.19 |
---|---|
SystemSoftware - Buffer OverFlow #1 (0) | 2021.05.19 |
SystemSoftware - Machine data(Assembly) #2 (0) | 2021.04.30 |
SystemSoftware - Machine data(Assembly) #1 (1) | 2021.04.28 |
SystemSoftware - float #2 (0) | 2021.04.20 |