hacktricks/binary-exploitation/integer-overflow.md

121 lines
5.8 KiB
Markdown

# Ganzzahlüberlauf
{% hint style="success" %}
Lernen Sie AWS-Hacking:<img src="/.gitbook/assets/arte.png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="/.gitbook/assets/arte.png" alt="" data-size="line">\
Lernen Sie GCP-Hacking: <img src="/.gitbook/assets/grte.png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="/.gitbook/assets/grte.png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
<details>
<summary>Unterstützen Sie HackTricks</summary>
* Überprüfen Sie die [**Abonnementpläne**](https://github.com/sponsors/carlospolop)!
* **Treten Sie der** 💬 [**Discord-Gruppe**](https://discord.gg/hRep4RUj7f) oder der [**Telegram-Gruppe**](https://t.me/peass) bei oder **folgen** Sie uns auf **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks\_live)**.**
* **Teilen Sie Hacking-Tricks, indem Sie PRs an die** [**HackTricks**](https://github.com/carlospolop/hacktricks) und [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) Github-Repositories senden.
</details>
{% endhint %}
## Grundlegende Informationen
Im Herzen eines **Ganzzahlüberlaufs** liegt die Beschränkung durch die **Größe** von Datentypen in der Computerprogrammierung und die **Interpretation** der Daten.
Beispielsweise kann ein **8-Bit-Unsigned-Integer** Werte von **0 bis 255** darstellen. Wenn Sie versuchen, den Wert 256 in einem 8-Bit-Unsigned-Integer zu speichern, wird er aufgrund der Begrenzung seiner Speicherkapazität auf 0 zurückgesetzt. Ebenso wird bei einem **16-Bit-Unsigned-Integer**, der Werte von **0 bis 65.535** speichern kann, durch Hinzufügen von 1 zu 65.535 der Wert auf 0 zurückgesetzt.
Darüber hinaus kann ein **8-Bit-Signed-Integer** Werte von **-128 bis 127** darstellen. Dies liegt daran, dass ein Bit zur Darstellung des Vorzeichens (positiv oder negativ) verwendet wird, sodass 7 Bits zur Darstellung des Betrags verbleiben. Die negativste Zahl wird als **-128** dargestellt (binär `10000000`), und die positivste Zahl ist **127** (binär `01111111`).
### Maximalwerte
Für potenzielle **Web-Schwachstellen** ist es sehr interessant, die maximal unterstützten Werte zu kennen:
{% 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" %}
Integer-Überlauf tritt auf, wenn eine arithmetische Operation das Maximum darstellbare Integer überschreitet und zu einem Wert führt, der kleiner als das Minimum ist. Dies kann zu unerwartetem Verhalten führen, wie z.B. dem Überschreiben von Speicherbereichen oder der Ausführung von Schadcode. Integer-Überläufe sind häufige Schwachstellen in C-Programmen, die von Hackern ausgenutzt werden können, um Sicherheitslücken auszunutzen.
{% endtab %}
```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;
}
```
## Beispiele
### Reines Überlauf
Das gedruckte Ergebnis wird 0 sein, da wir das Zeichen überlaufen haben:
```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;
}
```
### Vorzeichenbehaftete in vorzeichenlose Konvertierung
Betrachten Sie eine Situation, in der eine vorzeichenbehaftete Ganzzahl aus Benutzereingaben gelesen und dann in einem Kontext verwendet wird, der sie als vorzeichenlose Ganzzahl behandelt, ohne ordnungsgemäße Validierung:
```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;
}
```
### Weitere Beispiele
* [https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/int\_overflow\_post/index.html)
* Es wird nur 1 Byte verwendet, um die Größe des Passworts zu speichern, daher ist es möglich, es zu überlaufen und es glauben zu machen, dass seine Länge 4 beträgt, während es tatsächlich 260 beträgt, um den Längenprüfschutz zu umgehen.
* [https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer\_exploitation/puzzle/index.html)
* Gegeben ein paar Zahlen, finden Sie mit Hilfe von z3 eine neue Zahl, die mit der ersten multipliziert die zweite ergibt:&#x20;
```
(((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/)
* Es wird nur 1 Byte verwendet, um die Größe des Passworts zu speichern, daher ist es möglich, es zu überlaufen und es glauben zu machen, dass seine Länge 4 beträgt, während es tatsächlich 260 beträgt, um den Längenprüfschutz zu umgehen und in den Stapel die nächste lokale Variable zu überschreiben und beide Schutzmechanismen zu umgehen.
## ARM64
Dies **ändert sich nicht in ARM64**, wie Sie in [**diesem Blog-Beitrag**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/) sehen können.