Website Hacking
Fundamentals
Outline
- Basics of website operation
- Cross-Site Scripting
- SQL Injection
- Command Injection
- Path Traversal
The Life of an HTTP request
- Step 1: Enter a URL into the address bar
- What’s in a URL?
URL Exercise
Given the URL:
https://www.google.com/search?q=hackbash+2024&num=10#ip=1
What is the:
- Protocol?
- Domain name?
- Port number?
- Path to resource?
- The value of query parameter “num”?
- The anchor?
https://hackbash.nusgreyhats.org/challenges
The Life of an HTTP request
- Browser looks up the IP address corresponding to the
domain name using DNS
- Establishes a connection to the web server using the IP
address and port number
- The exact mechanics of how these network connections happen
will be covered in the Networking & Forensics lesson
- Time to make our request
HTTP Request Format
Path
Method
Request Method
- Specifies what you want to do with the resource
- Two main methods: GET and POST
- GET retrieves the resource
- GET requests are not supposed to modify contents of the server,
but developers sometimes ignore these guidelines
- POST sends data to the resource for the server to do
something with
- Other methods: PUT, DELETE, HEAD etc.
HTTP Request with body
HTTP Headers
- Allows the client and server to define additional information
about an HTTP request/response
- Common HTTP headers in a request include
- Host: Identifies the domain and port where the request is being
sent
- Content-Length: The size of the message body in bytes
- Referer [sic]: Identifies the webpage that requested the resource
- User-Agent: Identifies the client software that made the request
- Cookie: Any cookies the client has that are associated with the
server (we will find out more about these later)
Over to the server
- Server receives the HTTP request, parses it
- What goes on behind the scenes? Well…
The simple case
Retrieving data
- Can be stored on the filesystem or on a database
- Many types: relational, document-oriented, graph…
- We look at relational databases in this lesson
- Language to query relational databases: Structured Query
Language (SQL)
Presenting data
- After the data is retrieved, it needs to be assembled into a
format that the browser can display
- HTML - HyperText Markup Language
Presenting data
- HTML by itself is static
- Once a page has loaded, that’s what you get until you navigate to
a new page
- Can’t dynamically make things appear and disappear, change info
in real-time…
- That’s fine for pages that looked like this:
Presenting data
But we want this:
JavaScript
- A scripting language to augment webpages with dynamic
behaviour
- Can either be included within HTML or from an external
source
Delivering the response
- We’ve crafted our response, time to wrap it and send it to
the client
HTTP Response Format
HTTP Status Codes
- 200 OK: All is good, here’s your page
- 404 Not Found
- 403 Forbidden: You can’t do that, you have no permission
- 400 Bad Request: Something’s wrong with the way you
made your request
- 500 Internal Server Error: I messed up
Back to the browser
- Browser receives the HTML and parses it
- Makes further HTTP requests to get images, stylesheets,
script files etc.
- Renders the page according to the HTML
- Runs any scripts it encounters along the way
Play with HTTP requests!
Install Burp Suite
https://portswigger.net/burp/communitydownload
• Free web security testing toolkit
• Main feature — HTTP Proxy
Burp Suite — Getting Started
• Open the embedded
browser under the
“Proxy” tab
• Go to any website
• Check Burp Suite —
the intercepted
request is shown
Burp Suite — Getting Started
• Turn off the intercept
for now
• Your requests will
show up in the HTTP
history tab
Burp Suite — Getting Started
• Right click > Send to
Repeater
• From Repeater, you
can modify the HTTP
request and resend it
Play with JavaScript!
Cross-Site Scripting: What is it?
• Simply put, the attacker executes JavaScript on a website
other than one that they own (cross-site)
Some Example Code
Cookies
- How would you design a system where multiple webpages
need authentication with a common set of credentials?
Cookies
- How would you design a system where multiple webpages
need authentication with a common set of credentials?
- HTTP’s answer: Cookies
Making HTTP requests in JavaScript
- How can JavaScript pull information from websites to
dynamically update a page?
- The fetch API
Making HTTP requests in JavaScript
- What if I do fetch(“https://gmail.com”)?
Same Origin Policy
- Web pages only permitted to access data from other pages
if they have the same origin
- What is the origin? Scheme + Host + Port
Same Origin Policy
- But if an attacker introduces his malicious JavaScript within
the same origin…
Cookie Stealing
- Better yet…
On the attacker’s browser
How to prevent Cross-Site Scripting?
- Filter user input when it arrives at the server
- Reject anything that does not conform to expected input
- Encode data on output
- Depending on where the user data is being output, this may mean
HTML encoding, JavaScript encoding, etc.
- Using the wrong encoding scheme for the context can lead to
bypassses!
- Set sensitive cookies to HttpOnly so that they are not
accessible directly by JavaScript
- Prevents stealing the cookie directly, but still lets attackers do
what they want as the user under the origin
- Content Security Policy
- Tell the browser that only certain scripts should execute
SQL Injection
- Web applications will often have to retrieve data from a
database
- Often times the retrieval depends on data provided by the
user
- E.g. retrieving a product’s details according to an ID supplied by
the user
- Logging in with a username and password
Example: logging in
Example: logging in
Does the SQL query return any rows?
- If yes → The username and password is valid, log in as that
user
- If no → Either invalid username or password
What does the code look like?
What if…
What if…
- Will that query return anything?
- Yes → log in as that user
- Attacker can log in as a user knowing only their username
- But wait, there’s more
How to prevent SQL injection
- The root cause of SQL injection is concatenating user input
directly with SQL commands
- The SQL server cannot tell which is which
- Solution: parameterised queries
- Put placeholders in the query where user data should go and pass
in the user data separately at execution time
- This way the SQL server can differentiate between the two
Command Injection
- Same basic idea as SQL injection: directly inserting user
data into a command that will be run by a shell is unsafe
- Symbols such as ; & ` $() etc can be evaluated by the shell
as instructions to execute a new command
- E.g. user enters “127.0.0.1;cat /etc/passwd” → server executes “ping
-c 127.0.0.1; cat /etc/passwd”
Preventing Command Injection
- Don’t call OS commands from application code
- See if what you want to do can be achieved using platform
APIs/libraries instead
- If you really need to:
- Validate the user input to ensure it only contains what you expect
- Don’t try escaping “dangerous characters” – this can be
error-prone and subject to bypasses
- See if user data can be passed in through places other than the
command line (environment variables? stdin?)
- Use APIs that don’t parse the command line through a shell
before running
Path Traversal
Using the previous vulnerabilities as inspiration, see if you can
spot anything wrong with this code:
Hint: in a terminal, how do you go up two directories with one
command?
How to prevent?
- Validate your user input to make sure it only contains a
certain allowed set of values
- Use platform filesystem APIs to check that the file being
accessed is within a “safe” directory