#include #include #include #ifdef __linux__ #define _alloca alloca #endif int getbuf(void); void test(void); int cookie=0x11223344; unsigned long rand1_h,rand1_l,rand_div; /* 产生一个0~divv-1之间的随机数,同时更新随机数种子 */ void GenerateRandomNumber(unsigned long divv) { long long x = rand1_h; x *= 0x6AC690C5; x += rand1_l; rand1_h = (unsigned long)x; rand1_l = (unsigned long)(x>>32); if (divv==0) return; rand_div = rand1_h % divv; } /* 输入16进制字符串,并转换为对应的字符串,以\0结束 */ char*getxs(char*dest) { int c; int even =1; /* Have read even number of digits */ int otherd =0; /* Other hex digit of pair */ char*sp = dest; while ((c = getchar()) != EOF && c !='\n' && c != '\r') { if (isxdigit(c)) { int val; if ('0'<= c && c <='9') val = c -'0'; else if ('A'<= c && c <='F') val = c -'A'+10; else val = c -'a'+10; if (even) { otherd = val; even =0; } else { *sp++= otherd *16+ val; even =1; } } } *sp++='\0'; return dest; } /* 获取一行输入字符串 */ int getbuf(void) { char buf[12]; getxs(buf); return 1; } /* 主测试程序 */ void test(void) { int val; char *localbuf; volatile int bird = 0xdeadbeef; //金丝雀保护机制 GenerateRandomNumber(23); localbuf = (char *)_alloca(rand_div+1); //在栈上分配随机空间 localbuf[0] = 'l'; val = getbuf(); /* 检测是否栈被破坏 */ if (bird == 0xdeadbeef) { printf("鸟还活着!\n"); } else printf("不妙!鸟被杀死,栈已经被你破坏了!\n"); if (val == cookie) { printf("不错哦,缓冲区溢出成功,而且getbuf返回 0X%08X\n", val); } else if (val == 1) { printf("缓冲区没有溢出.....攻击失败,请重来吧\n"); } else { printf("不对哦,虽然缓冲区溢出成功,但是getbuf返回 0X%08X\n", val); } } /* 第1只木马,只需要修改返回地址,即可进入 */ void Trojan1(void) { printf("恭喜你!你已经成功偷偷运行了第1只木马!\n"); printf("通过第1只木马测试\n"); exit(0); } /* 第2只木马,不仅需要修改返回地址,而且要修改栈中返回的结果 */ void Trojan2(int val) { if (val == cookie) { printf("不错哦!第2只木马运行了,而且通行密码是正确的!(0X%08X)\n", val); } else printf("需要加油!虽然第2只木马运行了,但是通行密码是不正确的!(0X%08X)\n", val); if (val == cookie) printf("通过第2只木马测试\n"); exit(0); } /* 第3只木马,本关任务是构造特定的机器代码放置在栈内,然后将返回地址置为该段特定代码的入口。此段代码负责将global_value设置为想要的cookie值 */ /* 汇编指令程序: MOV EAX,cookie MOV global_val,EAX PUSH Trojan3 RET 0: a1 e4 c1 04 08 MOV EAX,0x804c1e4 5: a3 ec c1 04 08 MOV 0x804c1ec,EAX a: 68 eb 8c 04 08 PUSH $0x8048ceb f: c3 RET */ int global_value = 0; void Trojan3(int val) { if (global_value == cookie) { printf("厉害!第3只木马运行了,而且你修改了全局变量正确!global_value = 0X%08X\n", global_value); } else printf("差一点!第3只木马运行了,但是全局变量修改错误!global_value = 0X%08X\n", global_value); if (global_value == cookie) printf("通过第3只木马测试\n"); exit(0); } /* 第4只木马,本关任务是构造特定的机器代码放置在栈内,然后将返回地址置为该段特定代码的入口。此段代码负责将global_value设置为想要的cookie值,需要正常返回 */ /* 汇编指令程序: MOV EAX,cookie MOV global_val,EAX PUSH Trojan3 RET 0: a1 e4 c1 04 08 MOV EAX,0x804c1e4 5: a3 ec c1 04 08 MOV 0x804c1ec,EAX a: 68 eb 8c 04 08 PUSH $0x8048ceb f: c3 RET */ void Trojan4(int val) { if (global_value == cookie) { printf("厉害!第4只木马运行了,而且你修改了全局变量正确!global_value = 0X%08X\n", global_value); } else printf("差一点!第4只木马运行了,但是全局变量不对!global_value = 0X%08X\n", global_value); if (global_value == cookie) printf("通过第4只木马测试\n"); return; // 正常返回,需要修复栈 } /* 主程序,依据学号,随机生成cookie值 */ int main(int argc, char *argv[]) { int i; char *MyRandomBuffer; printf("\t2018超级缓冲区炸弹,欢迎你!\n"); printf("============================\n"); if (argc == 1) { printf("使用方法:%s 学号后6位 [学号后6位] [学号后6位] ...\n",argv[0]); printf("你需要输入攻击字符串,以便种入木马,一旦出错,哇哈哈....\n"); printf("请以十六进制形式输入攻击字符串,例如00 aa bb cc等等\n"); return 0; } printf("欢迎你前来挑战! %s \n",argv[1]); /*依据学号,初始化一个随机数发生器*/ rand1_h = (unsigned long)atoi(argv[1]); rand1_l=0x29A; GenerateRandomNumber(0); for (i=2;i