Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将返回地址修改为外壳代码_C_Assembly_Buffer_Buffer Overflow_Exploit - Fatal编程技术网

C 将返回地址修改为外壳代码

C 将返回地址修改为外壳代码,c,assembly,buffer,buffer-overflow,exploit,C,Assembly,Buffer,Buffer Overflow,Exploit,我有两个C程序。一个是外壳代码,另一个是易受攻击的程序 我想在不缓冲易受攻击程序的情况下更改返回地址 例如: \uuuu asm\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu 但这种方法对我不起作用,我曾尝试在linux中用gdb运行易受攻击的程序,并将外壳代码重定向到它(gdb)运行vuln

我有两个C程序。一个是外壳代码,另一个是易受攻击的程序

我想在不缓冲易受攻击程序的情况下更改返回地址

例如:

\uuuu asm\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

但这种方法对我不起作用,我曾尝试在linux中用gdb运行易受攻击的程序,并将外壳代码重定向到它
(gdb)运行vuln
,但eip或ebp从未改变。 有人能看看我的外壳代码程序,看看错误在哪里吗

外壳代码程序

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

void shellcode() {
__asm__(".byte 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90"); /* you may put your shellcode here */
printf("hey guyz!\n");
exit(0);
}

void bang(int val) {

__asm__("movl $shellcode, 4(%ebp)");

}

int main() {
bang(0);
}
#包括
#包括
无效外壳代码(){
__asm_uuu(“.byte 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90”);/*您可以将外壳代码放在这里*/
printf(“嘿,伙计!\n”);
出口(0);
}
虚空爆炸(int-val){
__asm_uuuuuuu(“movl$外壳代码,4(%ebp)”);
}
int main(){
bang(0);
}
易受攻击程序

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

int bof(char *string) {

char buffer[1024];

strcpy(buffer, string);

return 1;
}

int main(int argc, char *argv[]) {

bof(argv[1]);
printf("Done..\n");

return 1;
}
#包括
#包括
#包括
整数bof(字符*字符串){
字符缓冲区[1024];
strcpy(缓冲区、字符串);
返回1;
}
int main(int argc,char*argv[]){
转炉(argv[1]);
printf(“完成…”\n);
返回1;
}

您试图实现的目标被称为一个目标

基本上, 您在堆栈中写入的字节数超过了应写入的字节数,并覆盖了返回地址

当您输入函数时,堆栈如下所示(简化):

因此,您必须写入至少1025个字节才能到达返回地址。 一旦您这样做,函数返回,它将尝试返回您在那里输入的任何值

下面是一个例子:

假设我们有一个名为“exploit.txt”的文件,里面填充了32个a:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

易受攻击的程序如下所示:

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

void func(FILE *f)
{
   long size;
   char c[12];  // You should only write 12 bytes here
   fseek(f, 0, SEEK_END);
   size = ftell(f);
   rewind(f);
   fread(c, 1, size, f);    // no bounds checking
}

int main(int argc, char **argv)
{
   FILE *f = NULL;
   if(f = open("exploit.txt", "r"))
   {
      func(f);
      fclose(f);
   }

   printf("done.\n");
   return 0;
}
#包括
#包括
void func(文件*f)
{
长尺寸;
char c[12];//您应该只在此处写入12个字节
fseek(f,0,SEEK_END);
尺寸=ftell(f);
倒带(f);
fread(c,1,size,f);//无边界检查
}
int main(int argc,字符**argv)
{
文件*f=NULL;
如果(f=open(“exploit.txt”,“r”))
{
func(f);
fclose(f);
}
printf(“完成。\n”);
返回0;
}
当您运行程序时,您将在地址0x4141处崩溃,因为读取文件导致溢出,并且返回地址被覆盖

在这种类型的攻击中,外壳代码将在开头有一个特定的返回地址,
指向易受攻击的可执行文件中的某个位置,然后跳回堆栈上的外壳代码(
jmp esp

但是请注意,这很可能不适用于现代编译器,因为它们添加了, 因此,如果您想尝试它,您必须在编译器中禁用这些选项

您可能还想了解更多关于


希望有帮助

你能描述一下预期的行为吗?@AB_,程序运行正常并打印printf(“完成”)。在向它注入外壳代码后,没有任何变化。我认为外壳代码中的问题。你能在你这边检查一下吗?不打印“完成”吗?不复制字符串吗?请specific@AB_,它会打印“完成”。这就是你所期望的?
#include <stdio.h>
#include <stdlib.h>

void func(FILE *f)
{
   long size;
   char c[12];  // You should only write 12 bytes here
   fseek(f, 0, SEEK_END);
   size = ftell(f);
   rewind(f);
   fread(c, 1, size, f);    // no bounds checking
}

int main(int argc, char **argv)
{
   FILE *f = NULL;
   if(f = open("exploit.txt", "r"))
   {
      func(f);
      fclose(f);
   }

   printf("done.\n");
   return 0;
}