Integer Overflow

Reading time: 5 minutes

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें

Basic Information

एक integer overflow के केंद्र में कंप्यूटर प्रोग्रामिंग में डेटा प्रकारों के आकार द्वारा लगाए गए प्रतिबंध और डेटा की व्याख्या है।

उदाहरण के लिए, एक 8-बिट unsigned integer 0 से 255 तक के मानों का प्रतिनिधित्व कर सकता है। यदि आप 8-बिट unsigned integer में मान 256 को स्टोर करने का प्रयास करते हैं, तो यह अपनी संग्रहण क्षमता की सीमा के कारण 0 पर लिपट जाता है। इसी तरह, एक 16-बिट unsigned integer के लिए, जो 0 से 65,535 तक के मानों को रख सकता है, 65,535 में 1 जोड़ने से मान फिर से 0 पर लिपट जाएगा।

इसके अलावा, एक 8-बिट signed integer -128 से 127 तक के मानों का प्रतिनिधित्व कर सकता है। इसका कारण यह है कि एक बिट को संकेत (सकारात्मक या नकारात्मक) का प्रतिनिधित्व करने के लिए उपयोग किया जाता है, जिससे 7 बिट्स को परिमाण का प्रतिनिधित्व करने के लिए छोड़ दिया जाता है। सबसे नकारात्मक संख्या को -128 (बाइनरी 10000000) के रूप में दर्शाया जाता है, और सबसे सकारात्मक संख्या 127 (बाइनरी 01111111) है।

Max values

संभावित web vulnerabilities के लिए अधिकतम समर्थित मानों को जानना बहुत दिलचस्प है:

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);
}

उदाहरण

शुद्ध ओवरफ्लो

छापी गई परिणाम 0 होगी क्योंकि हमने 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

एक ऐसी स्थिति पर विचार करें जहाँ एक साइन किया हुआ पूर्णांक उपयोगकर्ता इनपुट से पढ़ा जाता है और फिर इसे एक संदर्भ में उपयोग किया जाता है जो इसे एक असाइन किया हुआ पूर्णांक के रूप में मानता है, बिना उचित सत्यापन के:

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

  • केवल 1B का उपयोग पासवर्ड के आकार को स्टोर करने के लिए किया जाता है, इसलिए इसे ओवरफ्लो करना संभव है और इसे 4 की लंबाई के रूप में सोचने के लिए मजबूर करना जबकि वास्तव में इसकी लंबाई 260 है, ताकि लंबाई जांच सुरक्षा को बायपास किया जा सके।

  • 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/
  • केवल 1B का उपयोग पासवर्ड के आकार को स्टोर करने के लिए किया जाता है, इसलिए इसे ओवरफ्लो करना संभव है और इसे 4 की लंबाई के रूप में सोचने के लिए मजबूर करना जबकि वास्तव में इसकी लंबाई 260 है, ताकि लंबाई जांच सुरक्षा को बायपास किया जा सके और स्टैक में अगले स्थानीय चर को ओवरराइट किया जा सके और दोनों सुरक्षा को बायपास किया जा सके।

ARM64

यह ARM64 में नहीं बदलता जैसा कि आप इस ब्लॉग पोस्ट में देख सकते हैं।

tip

AWS हैकिंग सीखें और अभ्यास करें:HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें: HackTricks Training GCP Red Team Expert (GRTE)

HackTricks का समर्थन करें