201 lines
5.7 KiB
C
201 lines
5.7 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <ctype.h>
|
||
|
||
#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<argc;i++)
|
||
{
|
||
rand1_l = (unsigned long)atoi(argv[i]);
|
||
GenerateRandomNumber(0);
|
||
}
|
||
|
||
cookie = (int)rand1_h;
|
||
printf("你的通行密码是0X%08X\n",cookie);
|
||
printf("============================\n");
|
||
printf("请输入攻击字符串(十六进制串):");
|
||
GenerateRandomNumber(512);
|
||
MyRandomBuffer = (char *)_alloca(rand_div+1); //在栈上分配随机空间
|
||
MyRandomBuffer[0] = 'h';
|
||
test();
|
||
|
||
return 0;
|
||
}
|