标签归档:cve-2014-6271

由bash:cve-2014-6271 学习execve 2

关于bash的测试方法如下:

我们使用ltrace 跟踪一下

看一下问题发生的的原因:

官方提供的第一次patch

但产生了一个新的问题:

由于函数体满足() { ,也没有发现”;”,bash在eval的时候遇到语法问题(x)=被忽略了,就执行>/my echo valunerable

第二次提供了

由bash:cve-2014-6271 学习execve

我们先了解一下execve:

函数说明:
execve()用来执行参数filename字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,最后一个参数则为传递给执行文件的新环境变量数组。
返回值:
如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
这个代码会执行/bin/sh 使用参数-c 和 env 。 在当前的环境PATH中,运行env环境的程序,该环境变量包含了5个values。执行后的 结果为:

该段也包含了”_”,”SHLVL”,”PWD”环境变量。
我们调试一下该程序运行的信息

测试:

使用gdb进行分析一下

Execve()需要各种参数
将数据存放在堆栈中,表示要执行的命令/bin/sh在0×0.依次将参数存入堆栈中。第一个参数必须是该程序的名字mov $0x48e9b0,%edi。Edi为第一参数寄存器。Rsi指向第二寄存器。
在execve执行程序时,我们需要/bin/sh的字符串,一个指针指向这个字符串,和一个指向参数的指针。我们可以看到execve()调用之前的数据表示,一个指向/bin/sh字符串后跟一个指向参数的指针数组(堆栈所在的rsi寄存器),其他的ecx和edx分别为第三第四参数寄存器。

Execve(name[0],name, envp))
Execve 是怎么执行的呢?我们看一下内核里面的代码实现

execve
经过了

可以分析内核的一段代码:

附录:
X86-64中,所有寄存器都是64位,相对32位的x86来说,标识符发生了变化,比如:从原来的%ebp变成了%rbp。为了向后兼容性,%ebp依然可以使用,不过指向了%rbp的低32位。
X86-64寄存器的变化,不仅体现在位数上,更加体现在寄存器数量上。新增加寄存器%r8到%r15。加上x86的原有8个,一共16个寄存器。
刚刚说到,寄存器集成在CPU上,存取速度比存储器快好几个数量级,寄存器多了,GCC就可以更多的使用寄存器,替换之前的存储器堆栈使用,从而大大提升性能。
让寄存器为己所用,就得了解它们的用途,这些用途都涉及函数调用,X86-64有16个64位寄存器,分别是:%rax,%rbx,%rcx,%rdx,%esi,%edi,%rbp,%rsp,%r8,%r9,%r10,%r11,%r12,%r13,%r14,%r15。其中:
• %rax 作为函数返回值使用。
• %rsp 栈指针寄存器,指向栈顶
• %rdi,%rsi,%rdx,%rcx,%r8,%r9 用作函数参数,依次对应第1参数,第2参数。。。
• %rbx,%rbp,%r12,%r13,%14,%15 用作数据存储,遵循被调用者使用规则,简单说就是随便用,调用子函数之前要备份它,以防他被修改
• %r10,%r11 用作数据存储,遵循调用者使用规则,简单说就是使用之前要先保存原值
x86-64寄存器2