CSAPP:缓冲区溢出攻击实验(Part 1)
asd
posted @ Wed, 16 Mar 2011 16:44:55 -1100
in ASSEMBLY
, 2719 readers
这是源码:
/* Bomb program that is solved using a buffer overflow attack */ #include <stdio.h> #include <stdlib.h> #include <ctype.h> /* Like gets, except that characters are typed as pairs of hex digits. Nondigit characters are ignored. Stops when encounters newline */ 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') { 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; } /* $begin getbuf-c */ int getbuf() { char buf[12]; getxs(buf); return 1; } void test() { int val; printf("Type Hex string:"); val = getbuf(); printf("getbuf returned 0x%x\n", val); } /* $end getbuf-c */ int main() { int buf[16]; /* This little hack is an attempt to get the stack to be in a stable position */ int offset = (((int) buf) & 0xFFF); int *space = (int *) alloca(offset); *space = 0; /* So that don't get complaint of unused variable */ test(); return 0; }
想办法让test的printf语句不返回1,其实 可以指定返回内容:D
恩,首先 既然是用缓冲区溢出的漏洞,那要先了解stack frame的结构,反汇编必不可少了
gcc -o dis_buff.s -S buff.c
.file "buff.c" .text .globl getxs .type getxs, @function getxs: pushl %ebp movl %esp, %ebp subl $40, %esp movl $1, -16(%ebp) movl $0, -20(%ebp) movl 8(%ebp), %eax movl %eax, -24(%ebp) jmp .L2 .L8: call __ctype_b_loc movl (%eax), %eax movl -12(%ebp), %edx addl %edx, %edx addl %edx, %eax movzwl (%eax), %eax movzwl %ax, %eax andl $4096, %eax testl %eax, %eax je .L2 cmpl $47, -12(%ebp) jle .L3 cmpl $57, -12(%ebp) jg .L3 movl -12(%ebp), %eax subl $48, %eax movl %eax, -28(%ebp) jmp .L4 .L3: cmpl $64, -12(%ebp) jle .L5 cmpl $70, -12(%ebp) jg .L5 movl -12(%ebp), %eax subl $55, %eax movl %eax, -28(%ebp) jmp .L4 .L5: movl -12(%ebp), %eax subl $87, %eax movl %eax, -28(%ebp) .L4: cmpl $0, -16(%ebp) je .L6 movl -28(%ebp), %eax movl %eax, -20(%ebp) movl $0, -16(%ebp) jmp .L2 .L6: movl -20(%ebp), %eax movl %eax, %edx sall $4, %edx movl -28(%ebp), %eax leal (%edx,%eax), %eax movl %eax, %edx movl -24(%ebp), %eax movb %dl, (%eax) addl $1, -24(%ebp) movl $1, -16(%ebp) .L2: call getchar movl %eax, -12(%ebp) cmpl $-1, -12(%ebp) je .L7 cmpl $10, -12(%ebp) jne .L8 .L7: movl -24(%ebp), %eax movb $0, (%eax) addl $1, -24(%ebp) movl 8(%ebp), %eax leave ret .size getxs, .-getxs .globl getbuf .type getbuf, @function getbuf: pushl %ebp movl %esp, %ebp subl $40, %esp movl %gs:20, %eax movl %eax, -12(%ebp) xorl %eax, %eax leal -24(%ebp), %eax movl %eax, (%esp) call getxs movl $1, %eax movl -12(%ebp), %edx xorl %gs:20, %edx je .L12 call __stack_chk_fail .L12: leave ret .size getbuf, .-getbuf .section .rodata .LC0: .string "Type Hex string:" .LC1: .string "getbuf returned 0x%x\n" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp subl $40, %esp movl $.LC0, %eax movl %eax, (%esp) call printf call getbuf movl %eax, -12(%ebp) movl $.LC1, %eax movl -12(%ebp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf leave ret .size test, .-test .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $84, %esp movl %gs:20, %eax movl %eax, -12(%ebp) xorl %eax, %eax leal -84(%ebp), %eax andl $4095, %eax movl %eax, -16(%ebp) movl -16(%ebp), %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp movl %esp, %eax addl $15, %eax shrl $4, %eax sall $4, %eax movl %eax, -20(%ebp) movl -20(%ebp), %eax movl $0, (%eax) call test movl $0, %eax movl -12(%ebp), %edx xorl %gs:20, %edx je .L17 call __stack_chk_fail .L17: movl -4(%ebp), %ecx leave leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
有了反汇编之后,发现诡异的几行:85,93,135,157出现了个诡异的%gs:20以及个诡异的函数__stack_chk_fail.
查阅资料后,了解到__stack_chk_fail是GCC较新版本的一个栈保护的函数,大概的原理是通过调用在调用对栈可能构成危险的函数前存入一个特殊的值%gs:20并放如当前栈中,在函数调用结束后,用__stack_chk_fail函数对该特殊值进行检查该特殊值是否被改变,若改变,则栈被破坏。所以,目前__stack_chk_fail也是个阻碍,为了方便,暂时先不需要理会这个gcc的栈保护机制。
所以,目前重点研究的汇编代码如下:
gcc -fno-stack-protector -o dis_buff_nochk.s -S buff.c
.file "buff.c" .text .globl getxs .type getxs, @function getxs: pushl %ebp movl %esp, %ebp subl $40, %esp movl $1, -24(%ebp) movl $0, -20(%ebp) movl 8(%ebp), %eax movl %eax, -16(%ebp) jmp .L2 .L8: call __ctype_b_loc movl (%eax), %eax movl -28(%ebp), %edx addl %edx, %edx addl %edx, %eax movzwl (%eax), %eax movzwl %ax, %eax andl $4096, %eax testl %eax, %eax je .L2 cmpl $47, -28(%ebp) jle .L3 cmpl $57, -28(%ebp) jg .L3 movl -28(%ebp), %eax subl $48, %eax movl %eax, -12(%ebp) jmp .L4 .L3: cmpl $64, -28(%ebp) jle .L5 cmpl $70, -28(%ebp) jg .L5 movl -28(%ebp), %eax subl $55, %eax movl %eax, -12(%ebp) jmp .L4 .L5: movl -28(%ebp), %eax subl $87, %eax movl %eax, -12(%ebp) .L4: cmpl $0, -24(%ebp) je .L6 movl -12(%ebp), %eax movl %eax, -20(%ebp) movl $0, -24(%ebp) jmp .L2 .L6: movl -20(%ebp), %eax movl %eax, %edx sall $4, %edx movl -12(%ebp), %eax leal (%edx,%eax), %eax movl %eax, %edx movl -16(%ebp), %eax movb %dl, (%eax) addl $1, -16(%ebp) movl $1, -24(%ebp) .L2: call getchar movl %eax, -28(%ebp) cmpl $-1, -28(%ebp) je .L7 cmpl $10, -28(%ebp) jne .L8 .L7: movl -16(%ebp), %eax movb $0, (%eax) addl $1, -16(%ebp) movl 8(%ebp), %eax leave ret .size getxs, .-getxs .globl getbuf .type getbuf, @function getbuf: pushl %ebp movl %esp, %ebp subl $40, %esp leal -20(%ebp), %eax movl %eax, (%esp) call getxs movl $1, %eax leave ret .size getbuf, .-getbuf .section .rodata .LC0: .string "Type Hex string:" .LC1: .string "getbuf returned 0x%x\n" .text .globl test .type test, @function test: pushl %ebp movl %esp, %ebp subl $40, %esp movl $.LC0, %eax movl %eax, (%esp) call printf call getbuf movl %eax, -12(%ebp) movl $.LC1, %eax movl -12(%ebp), %edx movl %edx, 4(%esp) movl %eax, (%esp) call printf leave ret .size test, .-test .globl main .type main, @function main: leal 4(%esp), %ecx andl $-16, %esp pushl -4(%ecx) pushl %ebp movl %esp, %ebp pushl %ecx subl $84, %esp leal -80(%ebp), %eax andl $4095, %eax movl %eax, -16(%ebp) movl -16(%ebp), %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp movl %esp, %eax addl $15, %eax shrl $4, %eax sall $4, %eax movl %eax, -12(%ebp) movl -12(%ebp), %eax movl $0, (%eax) call test movl $0, %eax movl -4(%ebp), %ecx leave leal -4(%ecx), %esp ret .size main, .-main .ident "GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5" .section .note.GNU-stack,"",@progbits
Mon, 02 May 2022 09:19:46 -1100
I consider something truly interesting about your weblog so I saved to fav. Merchant Service Commission
====================================================================
I just want to complete a quick comment as a way to express gratitude to you personally for all those wonderful pointers you’re posting at this site. Time consuming internet investigation has by the end for the day been rewarded with top quality strategies to tell my guests. I might say that many people guests can be extremely endowed to happen in an amazing network with methods . marvellous individuals with useful hints. I feel quite privileged to obtain used your webpages and check toward really more fabulous minutes reading here. Thank you for most things. How to Sell Merchant Services