mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 22:52:06 +00:00
122 lines
7.1 KiB
Markdown
122 lines
7.1 KiB
Markdown
|
# Переповнення цілочисельних значень
|
|||
|
|
|||
|
{% hint style="success" %}
|
|||
|
Вивчайте та практикуйте хакінг AWS: <img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**Навчання HackTricks AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
|
|||
|
Вивчайте та практикуйте хакінг GCP: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**Навчання HackTricks GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|||
|
|
|||
|
<details>
|
|||
|
|
|||
|
<summary>Підтримайте HackTricks</summary>
|
|||
|
|
|||
|
* Перевірте [**плани підписки**](https://github.com/sponsors/carlospolop)!
|
|||
|
* **Приєднуйтесь до** 💬 [**групи Discord**](https://discord.gg/hRep4RUj7f) або [**групи Telegram**](https://t.me/peass) або **слідкуйте** за нами на **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
|
|||
|
* **Поширюйте хакерські трюки, надсилаючи PR до** [**HackTricks**](https://github.com/carlospolop/hacktricks) та [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) репозиторіїв на GitHub.
|
|||
|
|
|||
|
</details>
|
|||
|
{% endhint %}
|
|||
|
|
|||
|
## Основна інформація
|
|||
|
|
|||
|
У центрі **переповнення цілочисельних значень** лежить обмеження, накладене розміром типів даних у програмуванні для комп'ютерів та **інтерпретацією** даних.
|
|||
|
|
|||
|
Наприклад, **8-бітне беззнакове ціле число** може представляти значення від **0 до 255**. Якщо ви спробуєте зберегти значення 256 у 8-бітному беззнаковому цілому числі, воно обертається до 0 через обмеження його місткості. Так само для **16-бітного беззнакового цілого числа**, яке може утримувати значення від **0 до 65,535**, додавання 1 до 65,535 призведе до обертання значення назад до 0.
|
|||
|
|
|||
|
Більше того, **8-бітне знакове ціле число** може представляти значення від **-128 до 127**. Це тому, що один біт використовується для представлення знака (позитивний або від'ємний), залишаючи 7 біт для представлення величини. Найвід'ємніше число представлене як **-128** (двійкове `10000000`), а найпозитивніше число - **127** (двійкове `01111111`).
|
|||
|
|
|||
|
### Максимальні значення
|
|||
|
|
|||
|
Для потенційних **вразливостей веб-додатків** дуже цікаво знати максимально підтримувані значення:
|
|||
|
|
|||
|
{% tabs %}
|
|||
|
{% tab title="Rust" %}
|
|||
|
```rust
|
|||
|
fn main() {
|
|||
|
|
|||
|
let mut quantity = 2147483647;
|
|||
|
|
|||
|
let (mul_result, _) = i32::overflowing_mul(32767, quantity);
|
|||
|
let (add_result, _) = i32::overflowing_add(1, quantity);
|
|||
|
|
|||
|
println!("{}", mul_result);
|
|||
|
println!("{}", add_result);
|
|||
|
}
|
|||
|
```
|
|||
|
{% endtab %}
|
|||
|
|
|||
|
{% tab title="Українська" %}
|
|||
|
```c
|
|||
|
#include <stdio.h>
|
|||
|
#include <limits.h>
|
|||
|
|
|||
|
int main() {
|
|||
|
int a = INT_MAX;
|
|||
|
int b = 0;
|
|||
|
int c = 0;
|
|||
|
|
|||
|
b = a * 100;
|
|||
|
c = a + 1;
|
|||
|
|
|||
|
printf("%d\n", INT_MAX);
|
|||
|
printf("%d\n", b);
|
|||
|
printf("%d\n", c);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
```
|
|||
|
## Приклади
|
|||
|
|
|||
|
### Чистий переповнення
|
|||
|
|
|||
|
Надрукований результат буде 0, оскільки ми переповнили символ:
|
|||
|
```c
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main() {
|
|||
|
unsigned char max = 255; // 8-bit unsigned integer
|
|||
|
unsigned char result = max + 1;
|
|||
|
printf("Result: %d\n", result); // Expected to overflow
|
|||
|
return 0;
|
|||
|
}
|
|||
|
```
|
|||
|
### Перетворення зі знакового на беззнакове
|
|||
|
|
|||
|
Розгляньте ситуацію, де знакове ціле число зчитується з введення користувача, а потім використовується в контексті, який розглядає його як беззнакове ціле число, без належної перевірки:
|
|||
|
```c
|
|||
|
#include <stdio.h>
|
|||
|
|
|||
|
int main() {
|
|||
|
int userInput; // Signed integer
|
|||
|
printf("Enter a number: ");
|
|||
|
scanf("%d", &userInput);
|
|||
|
|
|||
|
// Treating the signed input as unsigned without validation
|
|||
|
unsigned int processedInput = (unsigned int)userInput;
|
|||
|
|
|||
|
// A condition that might not work as intended if userInput is negative
|
|||
|
if (processedInput > 1000) {
|
|||
|
printf("Processed Input is large: %u\n", processedInput);
|
|||
|
} else {
|
|||
|
printf("Processed Input is within range: %u\n", processedInput);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
```
|
|||
|
У цьому прикладі, якщо користувач вводить від'ємне число, воно буде інтерпретовано як велике беззнакове ціле через спосіб інтерпретації бінарних значень, що потенційно може призвести до непередбачуваної поведінки.
|
|||
|
|
|||
|
### Інші Приклади
|
|||
|
|
|||
|
* [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html)
|
|||
|
* Лише 1B використовується для зберігання розміру пароля, тому можливе переповнення та змушення його вважати довжиною 4, хоча насправді вона 260, щоб обійти захист перевірки довжини
|
|||
|
* [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html)
|
|||
|
* Задано кілька чисел, знайдіть за допомогою z3 нове число, яке помножене на перше, дасте друге: 
|
|||
|
|
|||
|
```
|
|||
|
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
|
|||
|
```
|
|||
|
* [https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)
|
|||
|
* Лише 1B використовується для зберігання розміру пароля, тому можливе переповнення та змушення його вважати довжиною 4, хоча насправді вона 260, щоб обійти захист перевірки довжини та перезаписати на стек наступну локальну змінну та обійти обидва захисти
|
|||
|
|
|||
|
## ARM64
|
|||
|
|
|||
|
Це **не змінюється в ARM64**, як можна побачити в [**цьому блозі**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
|