链接器标志“execstack”未应用于“.rodata”、“.data”或“.bss”部分……哪里错了?
linker flag `execstack` not applied at `.rodata`, `.data`, or `.bss` section.... What is Wrong?
目前我正在研究系统漏洞利用,并发现一些有趣的系统漏洞利用称为缓冲区溢出使用shellcode。
我使用 exit(0) 系统调用编写了终止当前进程的 shellcode。下面是我的代码。
#include <stdio.h>
char shell[100] =
"\xb0\x01" // mov al, 1
"\x31\xdb" // xor ebx, ebx
"\xcd\x80" ; // int 0x80
int main() {
((void(*)())shell)();
printf("this not should be printed\n");
return 0;
}
写完上面的代码后,我用gcc编译,使用-m32标志来编译x86架构(我的CPU架构是AMD x86_64),和使用 -fno-stack-protector、-z execstack 使 .data
、.rodata
和 stack
部分可执行文件。
所以编译的命令是这样的
gcc -m32 -fno-stack-protector -z execstack -o shellcode shellcode.c
.
之后,我执行测试程序 (shellcode.c),但是,结果显示存在分段错误(即使编译时使用了内存保护!!)。这是结果:
zsh: segmentation fault ./shellcode
因此,我使用 checksec、readelf 仔细检查了 shellcode 二进制文件。首先 readelf 说 .rodata、.data、.bss 部分不可执行。像这样。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00160 0x00160 R 0x4
INTERP 0x000194 0x08048194 0x08048194 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x002e8 0x002e8 R 0x1000
LOAD 0x001000 0x08049000 0x08049000 0x0022c 0x0022c R E 0x1000
LOAD 0x002000 0x0804a000 0x0804a000 0x00190 0x00190 R 0x1000
LOAD 0x002f0c 0x0804bf0c 0x0804bf0c 0x00198 0x0019c RW 0x1000
DYNAMIC 0x002f14 0x0804bf14 0x0804bf14 0x000e8 0x000e8 RW 0x4
NOTE 0x0001a8 0x080481a8 0x080481a8 0x00044 0x00044 R 0x4
GNU_EH_FRAME 0x002024 0x0804a024 0x0804a024 0x00044 0x00044 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10
GNU_RELRO 0x002f0c 0x0804bf0c 0x0804bf0c 0x000f4 0x000f4 R 0x1
正如你在上面看到的,stack 变成了可执行文件。但是,不是 .data
、.rodata
和 .bss
部分。
下面是关于 shellcode 内存保护的额外信息(使用 checksec)。
ELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 65) Symbols No 0 0 ./shellcode
如您所见,没有堆栈金丝雀,NX 位设置...但是,shellcode
程序继续出现分段错误...。这有什么问题...??/ ??
P.S 我正在使用kali linux 2021.02
标题说“execstack 未应用于 .rodata
、.data
或 .bss
部分 ”。
正确:
execstack
是一个链接器标志,“ 将 object 标记为需要可执行堆栈。”
它对 .data
、.bss
或 .rodata
没有任何作用。
当我 运行 你的程序(在 x86_64 上)时,我得到:
(gdb) r
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
Program received signal SIGSEGV, Segmentation fault.
0x0000000000601040 in shell ()
(gdb) bt
#0 0x0000000000601040 in shell ()
#1 0x0000000000400517 in main () at foo.c:9
(gdb) disassemble /s 0x0000000000601040
Dump of assembler code for function shell:
=> 0x0000000000601040 <+0>: mov [=10=]x1,%al
0x0000000000601042 <+2>: xor %ebx,%ebx
0x0000000000601044 <+4>: int [=10=]x80
0x0000000000601046 <+6>: add %al,(%rax)
0x0000000000601048 <+8>: add %al,(%rax)
...
然而,当我将代码更改为:
include <stdio.h>
int main() {
char shell[100] =
"\xb0\x01" // mov al, 1
"\x31\xdb" // xor ebx, ebx
"\xcd\x80" ; // int 0x80
((void(*)())shell)();
printf("this not should be printed\n");
return 0;
}
没有 -z execstack
的执行也得到 SIGSEGV
,但有选项它只是退出(零):
(gdb) r
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffdd50 in ?? ()
(gdb) bt
#0 0x00007fffffffdd50 in ?? ()
#1 0x000000000040054e in main () at foo.c:9
(gdb) disassemble /s 0x00007fffffffdd50
No function contains specified address.
### "make CFLAGS="-Wall -g -zexecstack" foo"
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
[Inferior 1 (process 24663) exited normally]
(gdb) q
目前我正在研究系统漏洞利用,并发现一些有趣的系统漏洞利用称为缓冲区溢出使用shellcode。 我使用 exit(0) 系统调用编写了终止当前进程的 shellcode。下面是我的代码。
#include <stdio.h>
char shell[100] =
"\xb0\x01" // mov al, 1
"\x31\xdb" // xor ebx, ebx
"\xcd\x80" ; // int 0x80
int main() {
((void(*)())shell)();
printf("this not should be printed\n");
return 0;
}
写完上面的代码后,我用gcc编译,使用-m32标志来编译x86架构(我的CPU架构是AMD x86_64),和使用 -fno-stack-protector、-z execstack 使 .data
、.rodata
和 stack
部分可执行文件。
所以编译的命令是这样的
gcc -m32 -fno-stack-protector -z execstack -o shellcode shellcode.c
.
之后,我执行测试程序 (shellcode.c),但是,结果显示存在分段错误(即使编译时使用了内存保护!!)。这是结果:
zsh: segmentation fault ./shellcode
因此,我使用 checksec、readelf 仔细检查了 shellcode 二进制文件。首先 readelf 说 .rodata、.data、.bss 部分不可执行。像这样。
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00160 0x00160 R 0x4
INTERP 0x000194 0x08048194 0x08048194 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x002e8 0x002e8 R 0x1000
LOAD 0x001000 0x08049000 0x08049000 0x0022c 0x0022c R E 0x1000
LOAD 0x002000 0x0804a000 0x0804a000 0x00190 0x00190 R 0x1000
LOAD 0x002f0c 0x0804bf0c 0x0804bf0c 0x00198 0x0019c RW 0x1000
DYNAMIC 0x002f14 0x0804bf14 0x0804bf14 0x000e8 0x000e8 RW 0x4
NOTE 0x0001a8 0x080481a8 0x080481a8 0x00044 0x00044 R 0x4
GNU_EH_FRAME 0x002024 0x0804a024 0x0804a024 0x00044 0x00044 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10
GNU_RELRO 0x002f0c 0x0804bf0c 0x0804bf0c 0x000f4 0x000f4 R 0x1
正如你在上面看到的,stack 变成了可执行文件。但是,不是 .data
、.rodata
和 .bss
部分。
下面是关于 shellcode 内存保护的额外信息(使用 checksec)。
ELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORTIFY Fortified Fortifiable FILE
Partial RELRO No canary found NX disabled No PIE No RPATH No RUNPATH 65) Symbols No 0 0 ./shellcode
如您所见,没有堆栈金丝雀,NX 位设置...但是,shellcode
程序继续出现分段错误...。这有什么问题...??/ ??
P.S 我正在使用kali linux 2021.02
标题说“execstack 未应用于 .rodata
、.data
或 .bss
部分 ”。
正确:
execstack
是一个链接器标志,“ 将 object 标记为需要可执行堆栈。”
它对 .data
、.bss
或 .rodata
没有任何作用。
当我 运行 你的程序(在 x86_64 上)时,我得到:
(gdb) r
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
Program received signal SIGSEGV, Segmentation fault.
0x0000000000601040 in shell ()
(gdb) bt
#0 0x0000000000601040 in shell ()
#1 0x0000000000400517 in main () at foo.c:9
(gdb) disassemble /s 0x0000000000601040
Dump of assembler code for function shell:
=> 0x0000000000601040 <+0>: mov [=10=]x1,%al
0x0000000000601042 <+2>: xor %ebx,%ebx
0x0000000000601044 <+4>: int [=10=]x80
0x0000000000601046 <+6>: add %al,(%rax)
0x0000000000601048 <+8>: add %al,(%rax)
...
然而,当我将代码更改为:
include <stdio.h>
int main() {
char shell[100] =
"\xb0\x01" // mov al, 1
"\x31\xdb" // xor ebx, ebx
"\xcd\x80" ; // int 0x80
((void(*)())shell)();
printf("this not should be printed\n");
return 0;
}
没有 -z execstack
的执行也得到 SIGSEGV
,但有选项它只是退出(零):
(gdb) r
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
Program received signal SIGSEGV, Segmentation fault.
0x00007fffffffdd50 in ?? ()
(gdb) bt
#0 0x00007fffffffdd50 in ?? ()
#1 0x000000000040054e in main () at foo.c:9
(gdb) disassemble /s 0x00007fffffffdd50
No function contains specified address.
### "make CFLAGS="-Wall -g -zexecstack" foo"
Starting program: /tmp/foo
Missing separate debuginfos, use: zypper install glibc-debuginfo-2.31-7.30.x86_64
[Inferior 1 (process 24663) exited normally]
(gdb) q