CSAPP:缓冲区溢出攻击实验(Part 2)

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

 

Avatar_small
AAA said:
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


Login *


loading captcha image...
(type the code from the image)
or Ctrl+Enter