5.4 KiB
整数オーバーフロー
htARTE(HackTricks AWS Red Team Expert) を通じてゼロからヒーローまでAWSハッキングを学ぶ!
HackTricks をサポートする他の方法:
- HackTricks で企業を宣伝したい場合や HackTricks をPDFでダウンロード したい場合は SUBSCRIPTION PLANS をチェックしてください!
- 公式PEASS&HackTricksグッズを入手する
- The PEASS Familyを発見し、独占的な NFTs のコレクションを見つける
- **💬 Discordグループ に参加するか、telegramグループ に参加するか、Twitter 🐦 @hacktricks_live をフォローする
- ハッキングトリックを共有するために、PRを HackTricks と HackTricks Cloud のGitHubリポジトリに提出する
基本情報
整数オーバーフローの中心には、コンピュータプログラミングのデータ型のサイズとデータの解釈によって課せられる制限があります。
たとえば、8ビット符号なし整数は 0 から 255 の値を表すことができます。8ビット符号なし整数に値 256 を格納しようとすると、その格納容量の制限により、値が 0 にラップアラウンドします。同様に、16ビット符号なし整数は 0 から 65,535 の値を保持でき、65,535 に 1 を加えると値が 0 に戻ります。
さらに、8ビット符号付き整数は -128 から 127 の値を表すことができます。これは、1ビットが符号(正または負)を表すために使用され、残りの7ビットが大きさを表すためです。最も負の数は -128(バイナリ 10000000
)で表され、最も正の数は 127(バイナリ 01111111
)です。
最大値
潜在的な Web脆弱性 に関して、サポートされる最大値を知ることは非常に興味深いです:
{% 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" %} 整数オーバーフローは、整数演算において結果が変数のデータ型の範囲を超える場合に発生します。これは、不正な値を生成し、プログラムの動作を乱す可能性があります。整数オーバーフローは、バッファオーバーフローと同様に、悪意のある攻撃者がプログラムの脆弱性を悪用するために利用されることがあります。整数オーバーフローを防ぐためには、適切な入力検証とデータ型の適切な選択が重要です。 {% 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;
}
例
純粋なオーバーフロー
charをオーバーフローさせたため、印刷される結果は0になります:
#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;
}
符号付きから符号なしへの変換
ユーザー入力から読み取った符号付き整数が、適切な検証なしに符号なし整数として扱われる状況を考えてみましょう:
#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
- プログラムは数値の最後のバイトのみを検証して入力のサイズをチェックしているため、最後のバイトが許容範囲内にあれば任意のサイズを追加することが可能です。その後、入力はret2winを用いてバッファオーバーフローを起こします。
- https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html
- 与えられた数値の組み合わせから、z3を使用して最初の数値と掛け合わせると第二の数値が得られる新しい数値を見つけます:
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
\