C 格式字符串利用

C 格式字符串利用,c,exploit,C,Exploit,我一直在关注一本名为《黑客:利用的艺术》的书,但是当我负责理解格式字符串利用时,我遇到了一个常规 #include <stdio.h> #include <string.h> int main(int argc, char *argv[]){ int test = 43; //int *whereat = &test; char buffer[100]; memset(buffer, '\0', 100); strcpy

我一直在关注一本名为《黑客:利用的艺术》的书,但是当我负责理解格式字符串利用时,我遇到了一个常规

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

int main(int argc, char *argv[]){
    int test = 43;
    //int *whereat = &test;
    char buffer[100];

    memset(buffer, '\0', 100);
    strcpy(buffer, argv[1]);
    buffer[strlen(argv[1])] = '\n';
    printf(buffer);

    if(test == 62){
        printf("\nHacked\n");
    }else{
        printf("\n");
        printf("%d", test);
        printf("\n");   
    }

}
#包括
#包括
int main(int argc,char*argv[]){
int检验=43;
//int*where=&test;
字符缓冲区[100];
内存集(缓冲区,'\0',100);
strcpy(缓冲区,argv[1]);
缓冲区[strlen(argv[1])]='\n';
printf(缓冲区);
如果(测试==62){
printf(“\n标记\n”);
}否则{
printf(“\n”);
printf(“%d”,测试);
printf(“\n”);
}
}
上面的代码是我设置的一个测试虚拟,为了显示被黑客攻击的消息,您必须用62覆盖测试。为了做到这一点,我使用gdb来确定测试的地址为0x7FFFFFDEC4。我最熟悉四字节地址,所以当地址变长时,我不确定该怎么办。也就是说,我尝试将较长的地址写入输入字符串的前6个字节,作为“\xc4\xde\xff\xff\xff\xff”以及7“%08x”(用于到达堆栈上的字符串)和%n,以至少覆盖测试变量,但我的尝试尚未成功(我正在运行ubuntu,ASLR被关闭,堆栈金丝雀也被关闭,所以我一直得到的segfault肯定是由于地址不当造成的。非常感谢您的帮助,如果有其他信息可以帮助我,请告诉我

我用于测试的地址来自gdb:

(gdb) list 1
warning: Source file is more recent than executable.
1   #include <stdio.h>
2   #include <string.h>
3   
4   int main(int argc, char *argv[]){
5       
6       int test = 43;
7       //int *whereat = &test;
8       char buffer[100];
9       memset(buffer, '\0', 100);
10      strcpy(buffer, argv[1]);
(gdb) break 7
Breakpoint 1 at 0x40065c: file fmt_exploit.c, line 7.
(gdb) run aa
Starting program: /home/ubuntu/Desktop/dir/fmt_exploit aa

Breakpoint 1, main (argc=2, argv=0x7fffffffdfb8) at fmt_exploit.c:13
13      printf(buffer);
(gdb) print &test
$1 = (int *) 0x7fffffffdec4
(gdb)列表1
警告:源文件比可执行文件更新。
1#包括
2#包括
3.
4 int main(int argc,char*argv[]){
5.
6智力测验=43;
7//int*where=&test;
8字符缓冲区[100];
9个内存集(缓冲区,'\0',100);
10个strcpy(缓冲区,argv[1]);
(gdb)突破7
0x40065c处的断点1:文件fmt_aploit.c,第7行。
(gdb)运行aa
启动程序:/home/ubuntu/Desktop/dir/fmt\u
fmt_漏洞处的主断点1(argc=2,argv=0x7fffffffdfb8)。c:13
13 printf(缓冲区);
(gdb)打印和测试
$1=(int*)0x7fffffffdec4

从最后一行可以看出,测试的地址是0x7fffffffdec4。我应该如何将此地址写入字符串以使“%n”覆盖成为可能?

我根本不知道这与原始地址有什么关系。
argv[1]的内容
仅由
strcpy
strlen
函数查看,对吗?因此
strcpy
将执行缓冲区溢出,或者
buffer[strlen(argv[1])]
。在
buffer[strlen(argv[1])的情况下
,要进行缓冲区溢出,您必须给它一个太长的字符串,对吗?我仍然不明白为什么要将内存地址放入输入字符串,或者您认为这会起什么作用。@RandomDavis在我正在阅读的书中描述了一个格式字符串漏洞,它是可变函数所特有的对printf的函数调用没有一个补码变量,当从控制台输入“%08x”时,它会检索位于堆栈上的值,如果传递了补码变量,则该值应该位于堆栈上,通过这样做,最终可以到达字符串中的地址。此后,可以使用“%n”任意写入地址。我会找到这本书的链接。@RandomDavis 184页在64位系统上,地址是8字节,而不是6字节。@stark我想是的,这就是为什么我对我得到的gdb输出有点困惑(添加到问题中)。有什么解释为什么地址是6字节长的吗?我根本不明白这与原始地址有什么关系。
argv[1]
的内容只被
strcpy
strlen
函数查看,对吗?所以要么
strcpy
会造成缓冲区溢出,要么
buffer[strlen(argv[1])
。对于
缓冲区[strlen(argv[1])]
,要进行缓冲区溢出,您必须给它一个太长的字符串,对吗?我仍然不明白为什么要将内存地址放入输入字符串,或者您认为这会起什么作用。@RandomDavis在我正在阅读的书中描述了一个格式字符串漏洞,它是可变函数所特有的对printf的函数调用没有一个补码变量,当从控制台输入“%08x”时,它会检索位于堆栈上的值,如果传递了补码变量,则该值应该位于堆栈上,通过这样做,最终可以到达字符串中的地址。此后,可以使用“%n”任意写入地址。我会找到这本书的链接。@RandomDavis 184页在64位系统上,地址是8字节,而不是6字节。@stark我这么认为,这就是为什么我对我得到的gdb输出(添加到问题中)有点困惑的原因。有没有解释为什么地址是6字节长的?