7.2 KiB
Przepełnienie liczb całkowitych
Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLANY SUBSKRYPCYJNE!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR-y do HackTricks i HackTricks Cloud na githubie.
Podstawowe informacje
W centrum przepełnienia liczb całkowitych leży ograniczenie narzucone przez rozmiar typów danych w programowaniu komputerowym i interpretację danych.
Na przykład 8-bitowa liczba całkowita bez znaku może reprezentować wartości od 0 do 255. Jeśli spróbujesz przechować wartość 256 w 8-bitowej liczbie całkowitej bez znaku, zawiśnie ona do 0 ze względu na ograniczenie jej pojemności. Podobnie, dla 16-bitowej liczby całkowitej bez znaku, która może przechowywać wartości od 0 do 65 535, dodanie 1 do 65 535 spowoduje zawinięcie wartości z powrotem do 0.
Co więcej, 8-bitowa liczba całkowita ze znakiem może reprezentować wartości od -128 do 127. Wynika to z faktu, że jeden bit jest używany do reprezentowania znaku (dodatni lub ujemny), pozostawiając 7 bitów do reprezentowania wartości bezwzględnej. Najbardziej ujemna liczba jest reprezentowana jako -128 (binarnie 10000000
), a najbardziej dodatnia liczba to 127 (binarnie 01111111
).
Maksymalne wartości
Dla potencjalnych podatności internetowych bardzo ważne jest poznanie maksymalnie obsługiwanych wartości:
{% tabs %} {% tab title="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" %}
Integer overflows occur when the result of an arithmetic operation exceeds the maximum size that the data type can hold. This can lead to unexpected behavior and security vulnerabilities in a program. To prevent integer overflows, always check the input values and ensure that the result of an operation does not exceed the maximum size of the data type. Additionally, using data types with larger sizes can help prevent integer overflows.{% endtab %}
#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;
}
Przykłady
Czyste przepełnienie
Wydrukowany wynik będzie wynosił 0, ponieważ przepełniliśmy typ char:
#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;
}
Konwersja ze znakowanej na nieznakowaną
Rozważ sytuację, w której liczba całkowita ze znakiem jest odczytywana z wejścia użytkownika, a następnie używana w kontekście traktującym ją jako liczbę całkowitą bez znaku, bez odpowiedniej walidacji:
#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;
}
W tym przykładzie, jeśli użytkownik wprowadzi liczbę ujemną, zostanie ona zinterpretowana jako duża liczba całkowita bez znaku ze względu na sposób interpretacji wartości binarnych, co potencjalnie prowadzi do nieoczekiwanego zachowania.
Inne Przykłady
- https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html
- Do przechowywania rozmiaru hasła użyto tylko 1B, więc istnieje możliwość przepełnienia i sprawienia, że zostanie ono uznane za długość 4, podczas gdy faktycznie wynosi 260, aby ominąć ochronę sprawdzającą długość
- https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html
- Mając parę liczb, znajdź za pomocą z3 nową liczbę, która pomnożona przez pierwszą da drugą:
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
- https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/
- Do przechowywania rozmiaru hasła użyto tylko 1B, więc istnieje możliwość przepełnienia i sprawienia, że zostanie ono uznane za długość 4, podczas gdy faktycznie wynosi 260, aby ominąć ochronę sprawdzającą długość i nadpisać na stosie następną zmienną lokalną, omijając obie ochrony
ARM64
To nie zmienia się w ARM64, jak można zobaczyć w tym poście na blogu.
Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!
Inne sposoby wsparcia HackTricks:
- Jeśli chcesz zobaczyć swoją firmę reklamowaną w HackTricks lub pobrać HackTricks w formacie PDF, sprawdź PLAN SUBSKRYPCYJNY!
- Zdobądź oficjalne gadżety PEASS & HackTricks
- Odkryj Rodzinę PEASS, naszą kolekcję ekskluzywnych NFT
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Podziel się swoimi sztuczkami hakerskimi, przesyłając PR do HackTricks i HackTricks Cloud github repos.