廢除應用程序的ASLR特性
ASLR (Address Space Layout Randomization),即地址空間隨機布局。大部分主流的操作系統都已實現了ASLR,以防范對已知地址進行惡意攻擊。iOS從4.3開始支持ASLR,Android從4.0也支持了ASLR機制。
ASLR的存在,給iOS系統越獄造成了很大的困難,某些不完美越獄方案就是因為攻破不了或者繞不開ASLR,所以每次重新啟動後地址再度隨機偏移,需要重新進行越獄操作。與此同時,ASLR也給應用層攻擊帶來了一些困難,不同進程會造成不同的地址空間偏移,而且在運行時才可確定其偏移量,不易鎖定攻擊地址。
Mach-O文件的文件頭會記錄二進制的屬性標識,有個flag叫做PIE (Position Independent Enable)。開啟了PIE的二進制文件,在執行時會產生ASLR。
我們可以使用otool工具,來查看任意應用程序二進制文件的屬性,以支付寶為例:
otool -hv Portal
有PIE標識,表示該程序在啟動時會產生隨機地址布局。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD48cD48YnIgLz48L3A+PHA+PGltZyBzcmM9"/uploadfile/Collfiles/20140304/20140304081123134.jpg" alt="\" />removePIE 是個去掉PIE flag的工具。
壞消息是,年久失修,它不支持iOS7。
好消息是,我們還有2個變通方法可以走。
#include#include #include #include #include void hexify(unsigned char *data, uint32_t size){ while(size--) printf("%02x", *data++);} void fcopy(FILE *f1, FILE *f2){ char buffer[BUFSIZ]; size_t n; while ((n = fread(buffer, sizeof(char), sizeof(buffer), f1)) > 0){ if (fwrite(buffer, sizeof(char), n, f2) != n) printf("Error copying backup");} } int main(int argc, char *argv[]){ struct mach_header currentHeader; int32_t magic = 0; FILE *fp; //edited file pointer FILE *fw; //backup file pointer char fwName[80]; char fwPrefix[4] = ".bak"; //app.bak if(argc < 1){ printf("Please enter the filename binary: in the format removePIE filename"); return EXIT_FAILURE;} if((fp = fopen(argv[1], "rb+")) == NULL) { printf("Error, unable to open file\n"); return EXIT_FAILURE; } //create app.bak filename strlcpy(fwName, argv[1], strlen(argv[1])+1); strlcat(fwName, fwPrefix, strlen(fwPrefix)+1); if((fw = fopen(fwName, "wb")) == NULL){ return EXIT_FAILURE;} if((fread(&magic, sizeof(int32_t), 1, fp)) == (int)NULL) {printf("Error reading magic constant in file\n"); return EXIT_FAILURE;} printf("magic : %x", magic); if(magic == 0xbebafeca){ //little endian printf("loading header\n"); fseek(fp, 0, SEEK_SET); if((fread(¤tHeader, sizeof(currentHeader), 1, fp)) == (int)NULL) { printf("Error reading MACH-O header"); return EXIT_FAILURE; } fseek(fp, 0, SEEK_SET); //set fp back to 0 to get full copy printf("\nbacking up application binary...\n"); fcopy(fp, fw); fclose(fw); printf("\nbinary backed up to:\t%s\n", fwName); printf("\nmach_header:\t"); hexify((unsigned char *)¤tHeader,sizeof(currentHeader)); printf("\noriginal flags:\t"); hexify((unsigned char *)¤tHeader.flags, sizeof(currentHeader.flags)); printf("\nDisabling ASLR/PIE ...\n"); currentHeader.flags &= ~MH_PIE; printf("new flags:\t"); hexify((unsigned char *)¤tHeader.flags, sizeof(currentHeader.flags)); fseek(fp, 0, SEEK_SET); if((fwrite(¤tHeader, sizeof(char), 28, fp)) == (int)NULL) { printf("Error writing to application file %s\n",fwName); } printf("\nASLR has been disabled for %s\n", argv[1]); //exit and close memory //free(mach_header); fclose(fp); return EXIT_SUCCESS; } else if(magic == MH_CIGAM) // big endian { printf("file is big-endian, not an iOS binary"); return EXIT_FAILURE; } else { printf("File is not a MACH_O binary"); return EXIT_FAILURE; } //exit return EXIT_FAILURE; }
./MyRemovePIE Portal