getenv() funkcja nie jest z natury reentrant ponieważ zwraca wartość wskazuje na statycznej danych .
W rzeczywistości, dla większej wydajności getenv(), implementacja może również zachować oddzielną kopię środowiska w strukturze danych, która może być przeszukiwana znacznie szybciej (np. Indeksowana tablica asocjacyjna lub drzewo binarne) i zaktualizuj zarówno go, jak i listę liniową w environ, gdy wywoływana jest setenv() lub unsetenv().
Tak więc adres zwracany przez getenv niekoniecznie musi pochodzić ze środowiska.
Układ pamięci procesu;
http://static.duartes.org/img/blogPosts/linuxFlexibleAddressSpaceLayout.png
http://d1gjlxt8vb0knt.cloudfront.net//wp-content/uploads/Memory-Layout-300x255.gif
mapa pamięci
import os
def mem_map():
path_hex = hex(id(os.getenv('PATH'))).rstrip('L')
path_address = int(path_hex, 16)
for line in open('/proc/self/maps'):
if 'stack' in line:
line = line.split()
first, second = line[0].split('-')
first, second = int(first, 16), int(second, 16)
#stack grows towards lower memory address
start, end = max(first, second), min(first, second)
print('stack:\n\tstart:\t0x{}\n\tend:\t0x{}\n\tsize:\t{}'.format(start, end, start - end))
if path_address in range(end, start+1):
print('\tgetenv("PATH") ({}) is in the stack'.format(path_hex))
else:
print('\tgetenv("PATH") ({}) is not in the stack'.format(path_hex))
if path_address > start:
print('\tgetenv("PATH") ({}) is above the stack'.format(path_hex))
else:
print('\tgetenv("PATH") ({}) is not above the stack'.format(path_hex))
print('')
continue
if 'heap' in line:
line = line.split()
first, second = line[0].split('-')
first, second = int(first, 16), int(second, 16)
#heap grows towards higher memory address
start, end = min(first, second), max(first, second)
print('heap:\n\tstart:\t0x{}\n\tend:\t0x{}\n\tsize:\t{}'.format(start, end, end - start))
if path_address in range(start, end+1):
print('\tgetenv("PATH") ({}) in the heap'.format(path_hex))
else:
print('\tgetenv("PATH") ({}) is not in the heap'.format(path_hex))
print('')
wyjścia;
heap:
start: 0x170364928
end: 0x170930176
size: 565248
getenv("PATH") (0xb74d2330) is not in the heap
stack:
start: 0x0xbffa8000L
end: 0x0xbff86000L
size: 139264
getenv("PATH") (0xb74d2330) is not in the stack
getenv("PATH") (0xb74d2330) is not above the stack
Środowisko znajduje się powyżej stosu. Więc jego adres powinien być wyższy niż stos. Ale pokazuje, że adres nie jest w stosie, a nie w stercie, a nie powyżej stosu. Czy to naprawdę adres? albo moje obliczenia są błędne!
Oto kod, aby sprawdzić, gdzie znajduje się obiekt w pamięci.
def where_in_mem(obj):
maps = {}
for line in open('/proc/self/maps'):
line = line.split()
start, end = line[0].split('-')
key = line[-1] if line[-1] != '0' else 'anonymous'
maps.setdefault(key, []).append((int(start, 16), int(end, 16)))
for key, pair in maps.items():
for start, end in pair:
# stack starts at higher memory address and grows towards lower memory address
if 'stack' in key:
if start >= id(obj) >= end:
print('Object "{}" ({}) in the range {} - {}, mapped to {}'.format(obj, hex(id(obj)), hex(start), hex(end), key))
continue
if start <= id(obj) <= end:
print('Object "{}" ({}) in the range {} - {}, mapped to {}'.format(obj, hex(id(obj)), hex(start), hex(end), key))
where_in_mem(1)
where_in_mem(os.getenv('PATH'))
Wyjście;
Object "1" (0xa17f8b0) in the range 0xa173000 - 0xa1fd000, mapped to [heap]
Object "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games" (0xb74a1330L) in the range 0xb7414000L - 0xb74d6000L, mapped to anonymous
Co anonimowy w powyższym wyjście?
Możliwe jest również, aby utworzyć odwzorowanie anonimowy pamięci, który nie odpowiada żadnemu plików, używany jest zamiast danych programowych. W Linuksie, jeśli zażądasz dużego bloku pamięci za pośrednictwem funkcji malloc(), biblioteka C utworzy takie anonimowe mapowanie zamiast korzystania z pamięci sterty. "Duże" oznacza większe niż MMAP_THRESHOLD bajty, domyślnie 128 kB i można je regulować za pomocą mallopt().
Anatomy of a Program in Memory
Więc os.environ['PATH']
jest w regionie malloc
ed.
Chciałbym dowiedzieć się więcej o przyczynie tego/potrzebującego. Jaka jest sztuczka? Jaki jest kod powłoki, który chcesz dołączyć? Dlaczego kod powłoki wymaga adresu pamięci zmiennej środowiskowej. itd. –
@ScottS. Dzięki za zainteresowanie, to jest dla prostego exploita przepełnienia BSS, wiem, że mógłbym użyć innego rozwiązania, znalazłem sposób, aby uzyskać go w C, ale jest o wiele łatwiejszy dostęp i praca z moim skryptem z pythonem. Aby uzyskać adres zmiennej środowiskowej, połącz ją z moim kodem powłoki i wykonaj wszystkie moje czynności. Zaczynam obserwować kod 'gdb-peda', szukając jak to działa. –
@ eki-al Czy możesz wysłać łącze do przykładu w C? – VirtualVDX