├── Day_01
├── README.md
└── image
│ └── sqli.png
├── Day_02
├── README.md
└── image
│ └── Traversal.png
├── Day_03
├── README.md
└── image
│ └── juggling.png
├── Day_04
├── README.md
└── image
│ └── xxe.png
├── Day_05
├── README.md
└── image
│ └── RFI.png
├── Day_06
├── README.md
└── image
│ └── csrf.png
├── Day_07
├── README.md
└── image
│ └── idor.png
├── Day_08
├── README.md
└── image
│ └── commandi.png
├── Day_09
├── README.md
└── image
│ └── ssrf.png
├── Day_10
├── README.md
└── image
│ └── serialization.png
├── Day_11
├── README.md
└── image
│ └── reflectedXSS.png
├── Day_12
├── README.md
└── image
│ └── StoredXSS.png
├── Day_13
├── README.md
└── image
│ └── dom.png
└── README.md
/Day_01/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Description
4 | A SQL injection attack consists of insertion or “injection” of a SQL query via the input data from the client to the application. A successful SQL injection exploit can read sensitive data from the database, modify database data (Insert/Update/Delete), execute administration operations on the database (such as shutdown the DBMS), recover the content of a given file present on the DBMS file system and in some cases issue commands to the operating system. SQL injection attacks are a type of injection attack, in which SQL commands are injected into data-plane input in order to affect the execution of predefined SQL commands.
5 |
6 |
7 | An attacker can use SQL Injection to manipulate an SQL query via the input data from the client to the application, thus forcing the SQL server to execute an unintended operation constructed using untrusted input.
8 |
9 | # Impact
10 | A successful SQL Injection attack can result in a malicious user gaining complete access to all data in a database server with the ability to execute unauthorized SQL queries and compromise the confidentiality, integrity, and availability of the application. Depending on the backend DBMS used and the permissions granted to the user on the database, a SQL Injection could result in arbitrary file read/write and even remote code execution.
11 |
12 | The severity of attacks that have leveraged SQL Injection should not be understated. Notorious breaches, including the devastating and internationally renowned hacks of Sony Pictures and LinkedIn, for example, are reported to have been executed using SQL Injection.
13 |
14 | # Vulnerable example
15 |
16 | Consider the following Symfony controller for the endpoint `/items?q=...:`
17 |
18 | ```php
19 | class ItemsController extends Controller
20 | {
21 | /**
22 | * @Route("/", name="items_index")
23 | * @Method("GET")
24 | */
25 | public function index(Request $request)
26 | {
27 | // fetch the query parameters
28 | $pattern = $request->query->get('q');
29 |
30 | // get matching list
31 | $manager = $this->getDoctrine()->getManager();
32 | $rsm = new ResultSetMapping();
33 | $rsm->addScalarResult('name', 'name');
34 | $query = $manager->createNativeQuery("SELECT * FROM items WHERE name LIKE '%$pattern%'", $rsm);
35 | $items = $query->getResult();
36 |
37 | // render the template
38 | return $this->render('items/index.html.twig', [
39 | 'items' => $items
40 | ]);
41 | }
42 | }
43 | ```
44 |
45 |
46 | ### Example exploit 1:
47 | Injecting `/items?q=1'+UNION+SELECT+password+from+users` will tell the database to execute following query whcich displays the value of `password` column from `users` table.
48 |
49 | `SELECT * FROM items WHERE name LIKE '%' UNION SELECT 1,2,password,4,5 FROM users --%'`
50 |
51 | ### Example exploit 2:
52 | injecting `administrator'--` on username while loging in will tell the database to execute following query which result in login bypass for the user `administrator`
53 |
54 | `SELECT * FROM users WHERE username = 'administrator'--' AND password = '`
55 |
56 |
57 | ## Prevention
58 | The solution is always to avoid string concatenation; common solutions are (in order of preference, where possible):
59 |
60 | * using higher level APIs provided by the framework at hand;
61 |
62 | * using prepared statements;
63 |
64 | * using appropriate escaping.
65 |
66 | ```
67 | $stmt = $mysqli->prepare("SELECT * FROM items WHERE name LIKE ?");
68 | $stmt->bind_param("s", "%$value%");
69 | $stmt->execute();
70 | $result = $stmt->get_result();
71 | ```
72 |
73 | Reference: [OWASP](https://github.com/OWASP/CheatSheetSeries/blob/master/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.md)
74 |
--------------------------------------------------------------------------------
/Day_01/image/sqli.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_01/image/sqli.png
--------------------------------------------------------------------------------
/Day_02/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Description
4 |
5 | Directory traversal (also known as file path traversal) is a web security vulnerability that allows an attacker to read arbitrary files on the server that is running an application. This might include application code and data, credentials for back-end systems, and sensitive operating system files. In some cases, an attacker might be able to write to arbitrary files on the server, allowing them to modify application data or behavior, and ultimately take full control of the server.
6 |
7 | # Impact
8 |
9 | The damage an attacker can cause by employing this type of attack is really only limited by the value of the exposed information. If a developer has structured their web root folder to include sensitive configuration files, for example, the fallout will, of course, be highly damaging. Furthermore, as with many other attacks that are a part of the attacker's toolkit, the vulnerability can be used by an attacker as a stepping stone, leading to the full compromise of the system.
10 |
11 | # Vulnerable Example
12 |
13 | The example below shows a vulnerable Symfony controller that serves files from a directory in an unsecure way:
14 |
15 | ```php
16 | class FetchFileController extends Controller
17 | {
18 | const ROOT = '/path/to/root/';
19 |
20 | /**
21 | * @Route("/", name="fetch_file_index")
22 | * @Method("GET")
23 | */
24 | public function indexAction(Request $request)
25 | {
26 | $file_name = $request->query->get('filename');
27 | $file_data = @file_get_contents(self::ROOT . "/$file_name");
28 | return $this->render('fetch_file/index.html.twig', ['file_data' => $file_data]);
29 | }
30 | }
31 | ```
32 |
33 | The file_name query parameter is controlled by the user; it is possible to retrieve arbitrary files in the filesystem by injecting `../` in the file_name parameter as shown below:
34 |
35 | `http://example.com/fetch_file/?file_name=../../../../../etc/passwd`
36 | This results in the absolute path `/path/to/root/../../../../../etc/passwd`, and its canonicalized form: `/etc/passwd`.
37 |
38 | # Prevention
39 |
40 | Make sure to avoid using the user-provided value to escape the designed directory by means of ../. The basename function can be used to extract the base component of a path.
41 |
42 | To remediate the vulnerability in the previous example, the $file_name variable should be fixed as follows:
43 |
44 | `$file_name = basename($file_name);`
45 | The previous attack would result in reading the `/path/to/root/passwd` file (which does not exist).
46 |
47 | References: [OWASP](https://owasp.org/www-community/attacks/Path_Traversal) [PORTSWIGGER](https://portswigger.net/web-security/file-path-traversal)
--------------------------------------------------------------------------------
/Day_02/image/Traversal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_02/image/Traversal.png
--------------------------------------------------------------------------------
/Day_03/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Description
4 |
5 | Type Juggling (also known as Type Confusion) vulnerabilities are a class of vulnerability wherein an object is initialized or accessed as the incorrect type, allowing an attacker to potentially bypass authentication or undermine the type safety of an application, possibly leading to arbitrary code execution.
6 |
7 | # Impact
8 |
9 | A successful Type Juggling attack can result in the complete compromise of the confidentiality, integrity, and availability of the target system. For example, the type confusion vulnerability CVE-2015-0336 in Adobe Flash Player allows an attacker to execute arbitrary code, which could lead to unauthorized access or the modification of data.
10 |
11 |
12 | # Vulnerable Example
13 |
14 | ```php
15 | if($_POST['password'] == "secret") {
16 | ...
17 | }
18 | ```
19 | Here, by giving the password as 0, the statement will evaluate to true. This is because PHP attempts to convert "secret" to an integer, which it cannot, and thus, converts the string to 0.
20 |
21 |
22 |
23 | # Prevention
24 |
25 | Always use strict comparison where possible, using `===` instead of `==` and similarly `!==` in place of `!=`.
26 |
27 | References: [OWASP](https://owasp.org/www-pdf-archive/PHPMagicTricks-TypeJuggling.pdf)
28 |
--------------------------------------------------------------------------------
/Day_03/image/juggling.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_03/image/juggling.png
--------------------------------------------------------------------------------
/Day_04/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Description
4 |
5 | XML external entity injection (also known as XXE) is a web security vulnerability that allows an attacker to interfere with an application's processing of XML data. It often allows an attacker to view files on the application server filesystem, and to interact with any back-end or external systems that the application itself can access.
6 |
7 | # Vulnerable example
8 |
9 | ```php
10 | loadXML($xml, LIBXML_NOENT);
16 | echo($dom->textContent);
17 | ?>
18 | ```
19 |
20 | The script parses XML data in an unsafe way and can be exploited to inject a specially forged XML to disclose the `/etc/passwd` system file, referring its path as an external entity.
21 |
22 | `]>`
19 |
20 | When the victim visits attacker's page, the plugin will be disabled.
21 |
22 | # Prevention
23 |
24 | A number of code patterns that prevent CSRF attacks exist, and more than one can be applied at the same time as part of a defence in depth security strategy.
25 |
26 | - Developers should require anti-forgery tokens for any unsafe methods (POST, PUT, DELETE) and ensure that safe methods (GET, HEAD) do not have any side effects.
27 |
28 | - Developers should consider implementing a Synchronizer Token Pattern
29 |
30 | - If the origin header is present, developers should verify that its value matches the target origin.
31 |
32 | - Importantly, developers should enforce User Interaction based CSRF Defense like the use of Captcha,OTP,Re-authentication,etc.
33 |
34 | Reference: [Portswigger](https://portswigger.net/web-security/csrf), [Wordpress](https://plugins.trac.wordpress.org/changeset?reponame=&new=2110522%40deny-all-firewall&old=2110073%40deny-all-firewall)
35 |
--------------------------------------------------------------------------------
/Day_06/image/csrf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_06/image/csrf.png
--------------------------------------------------------------------------------
/Day_07/README.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
4 | # Description
5 | Insecure direct object references (IDOR) are a type of access control vulnerability that arises when an application uses user-supplied input to access objects directly. The term IDOR was popularized by its appearance in the OWASP 2007 Top Ten. However, it is just one example of many access control implementation mistakes that can lead to access controls being circumvented. IDOR vulnerabilities are most commonly associated with horizontal privilege escalation, but they can also arise in relation to vertical privilege escalation.
6 |
7 | # Example
8 | Following is a small code snippet of Ultimate Member 2.1.2 which was vulnerable to IDOR. (CVE-2020-6859)
9 | Lets try to analyze it:
10 |
11 | ```php
12 | function ajax_file_upload() {
13 | $ret['error'] = null;
14 | $ret = array();
15 |
16 | $nonce = $_POST['_wpnonce'];
17 | $id = $_POST['key'];
18 | $timestamp = $_POST['timestamp'];
19 | $user_id = empty( $_POST['user_id'] ) ? get_current_user_id() : $_POST['user_id'];
20 |
21 | UM()->fields()->set_id = $_POST['set_id'];
22 | UM()->fields()->set_mode = $_POST['set_mode'];
23 | .
24 | .
25 | .
26 | fileupload()->upload( $id, $nonce );
27 | ```
28 |
29 | If you see here, the current logged in user is not verified and the file is uploaded just with the help of the id and nonce. So, if we can get the id of any other user, we can upload a file to their account.
30 |
31 |
32 | # Fix
33 |
34 | ```php
35 | function ajax_file_upload() {
36 | $ret['error'] = null;
37 | $ret = array();
38 |
39 | $nonce = $_POST['_wpnonce'];
40 | $id = $_POST['key'];
41 | $timestamp = $_POST['timestamp'];
42 | $user_id = empty( $_POST['user_id'] ) ? get_current_user_id() : $_POST['user_id'];
43 |
44 | UM()->fields()->set_id = $_POST['set_id'];
45 | UM()->fields()->set_mode = $_POST['set_mode'];
46 |
47 | // Checks if the current user is the owner of the user_id
48 | if ( ! UM()->roles()->um_current_user_can( 'edit', $user_id ) ) {
49 | $ret['error'] = __( 'You haven\'t ability to edit this user', 'ultimate-member' );
50 | wp_send_json_error( $ret );
51 | }
52 | .
53 | .
54 | .
55 | else{
56 | fileupload()->upload( $id, $nonce );
57 | }
58 |
59 | ```
60 |
61 | If you see here, the current logged in user is verified before executing the upload function. So, only the current logged in user can upload a file with their respective id. [Full Commit](https://github.com/ultimatemember/ultimatemember/commit/249682559012734a4f7d71f52609b2f301ea55b1)
62 | # Preventions
63 |
64 | - Access Control Checks
65 | - Using Indirect References
66 | - Syntactic and Logical Validation
67 |
--------------------------------------------------------------------------------
/Day_07/image/idor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_07/image/idor.png
--------------------------------------------------------------------------------
/Day_08/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # Description
4 | Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application. Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell. In this attack, the attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application. Command injection attacks are possible largely due to insufficient input validation.
5 |
6 |
7 | # Example
8 | Let's analyze following code which does nslookup of a given domain.
9 |
10 | ```php
11 | Enter a domain name...";
18 | }
19 | else
20 | {
21 | echo "
" . shell_exec("nslookup " . $target) . "
"; 22 | } 23 | } 24 | ?> 25 | ``` 26 | If you see here, target is taken through post request which is fully user controlled. So, if we passed our command via target, it will go inside shell_exec() function then the command is passed to the shell. So, we can simply break the nslookup command and execute our own new command. 27 | 28 | # Exploit: 29 | ```html 30 | 31 | 32 | 37 | 38 | 39 | 40 | ``` 41 | As you can see here, we have simply breaked the nslookup command with `;` which means command seperation in linux. Then, we have passed our own command `id` which will give us the current user id. So, in this way we can execute any command we want just like we did `id` command in above POC. 42 | 43 | 44 | # Prevention: 45 | Developers must use structured mechanisms that automatically enforce the separation between data and code. 46 | 47 | Importantly, OS Command Injection vulnerabilities can be entirely prevented if developers stringently avoid OS Command call outs from the application layer. Alternative methods of implementing necessary levels of functionality almost always exist. 48 | 49 | If invoking the command shell is unavoidable, endeavor not to use functions that call out using a single string; rather, opt for functions that require a list of individual arguments. These functions typically perform appropriate quoting and filtering of arguments. 50 | 51 | References: [OWASP](https://www.owasp.org/index.php/Command_Injection) -------------------------------------------------------------------------------- /Day_08/image/commandi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_08/image/commandi.png -------------------------------------------------------------------------------- /Day_09/README.md: -------------------------------------------------------------------------------- 1 |  2 | 3 | # Description 4 | Server-side request forgery (also known as SSRF) is a web security vulnerability that allows an attacker to induce the server-side application to make requests to an unintended location. A successful SSRF attack can often result in unauthorized actions or access to data within the organization, either in the vulnerable application itself or on other back-end systems that the application can communicate with. In some situations, the SSRF vulnerability might allow an attacker to perform arbitrary command execution. 5 | 6 | # Example 7 | Let's have a look to following code which is vulnerable to SSRF. 8 | 9 | ```php 10 | 20 | ``` 21 | 22 | If you see the above code, the server tires to send the request to user controlled image_url and tires to dump the contents of the URL. 23 | 24 | # Exploitation 25 | Since the server is not validating the URL if it is image or not. neither checking schemas, attacker can exploit it to read internal files: 26 | 27 | `http://localost/ssrf.php?image_url=file:///etc/passwd` 28 | 29 | Reading AWS meta data: 30 | 31 | `http://localost/ssrf.php?image_url=http://169.254.169.254/latest/meta-data/hostname` 32 | 33 | # Prevention 34 | - Disabled unused URL schemas like file:// , ftp:// , gopher:// 35 | - Internal services has to protected by authentication to add an extra layer of protection 36 | 37 | References: [shieldfy](https://shieldfy.io/security-wiki/server-side-request-forgery/server-side-request-forgery/) -------------------------------------------------------------------------------- /Day_09/image/ssrf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_09/image/ssrf.png -------------------------------------------------------------------------------- /Day_10/README.md: -------------------------------------------------------------------------------- 1 |  2 | # Description 3 | Unsafe Deserialization (also referred to as Insecure Deserialization) is a vulnerability wherein malformed and untrusted data input is insecurely deserialized by an application. It is exploited to hijack the logic flow of the application end might result in the execution of arbitrary code. 4 | 5 | # Understanding Serialization and UnSerialization 6 | 7 | ## Serialize() 8 | 9 | The serialize() function converts a storable representation of a value. To serialize data means to convert a value to a sequence of bits, so that it can be stored in a file, a memory buffer, or transmitted across a network. 10 | 11 | Example: 12 | 13 | ```php 14 | 21 | 22 | ``` 23 | Returns: 24 | `a:2:{i:0;s:9:"Pentester";i:1;s:5:"Nepal";}` 25 | 26 | Understanding the serialized string; 27 | 28 | | String | Meaning | 29 | | ------------- | ------------- | 30 | |a:2{| Array of 2 values| 31 | |i:0| Integer, value [ index-0]| 32 | |S:9:"Pentester"| String, 9 chars long, string value "Pentester"| 33 | |i:1| Integer, value [index-1]| 34 | |S:5:"Nepal"| String , 5 chars long, string value "Nepal" 35 | 36 | 37 | ## unserialize() 38 | Convert serialized data back into actual data. 39 | 40 | Example: 41 | 42 | ```php 43 | 49 | ``` 50 | Returns: 51 | `array(2) { [0]=> string(9) "Pentester" [1]=> string(5) "Nepal" }` 52 | 53 | # Vulnerability 54 | 55 | For example, the following script creates an instance of the object FSResource, serializes it, and then prints the string representation of the object. 56 | 57 | ```php 58 | path = $path; 64 | if (file_exists($path)) { 65 | $this->content = file_get_contents($path); 66 | } 67 | } 68 | 69 | function __destruct() { 70 | file_put_contents($this->path, $this->content); 71 | } 72 | 73 | } 74 | 75 | $resource = new FSResource('/tmp/file'); 76 | print(serialize($resource)); 77 | 78 | # Prints the following string representation: 79 | # O:10:"FSResource":2:{s:4:"path";s:9:"/tmp/file";s:7:"content";s:0:"";} 80 | ``` 81 | 82 | The exploitation of deserialization in PHP is called PHP Object Injection, which happens when user-controlled input is passed as the first argument of the unserialize() function. This is a vulnerable script.php: 83 | 84 | ```php 85 | 89 | ``` 90 | 91 | To be exploitable, the vulnerable piece of code must have enough PHP code in scope to build a working POP chain, a chain of reusable PHP code that causes a meaningful impact when invoked. The chain usually starts by triggering `__destroy()` or `__wakeup()` PHP magic methods, called when the object is destroyed or deserialized, in order to call other gadgets to conduct malicious actions on the system. 92 | 93 | If the class FSResource defined in the paragrah above is in scope, an attacker could send an HTTP request containing a serialized representation of an FSResource object that creates a malicious PHP file to path with an arbitrary content when the `__destruct()` magic method is called upon destruction. 94 | 95 | # Exploit 96 | 97 | `http://localhost/script.php?data=O:10:%22FSResource%22:2:{s:4:%22path%22;s:9:%22shell.php%22;s:7:%22content%22;s:27:%22%3C?php%20system($_GET[%22cmd%22]);%22;}` 98 | 99 | The payload above decodes as `O:10:"FSResource":2:{s:4:"path";s:9:"shell.php";s:7:"content";s:27:" 24 | 25 | Back 26 | ``` 27 | 28 | If you see here, the variable `previousUrl` is taken from user controlled parameter `backurl` and is displayed without any sanitization which makes an attacker to execute malicious js code on the behalf of innocient victim. 29 | 30 | # Exploit: 31 | 32 | `https://localhost/sendtesterror.php?backurl=">` 33 | 34 | When victim visits this url, as discussed above, the javascript code `` triggers on victim's side and an alert pops up. similarly an attacker can steal the cookie with malicious javascript code and perfrom many other unintended actions from victim's side. 35 | 36 | 37 | # Fix: 38 | 39 | ```php 40 | 47 | 48 | Back 49 | 50 | 51 | ``` 52 | Now, the variable `previousUrl` is sanitized using the function `htmlentities()` before displaying it, which converts characters to HTML entities. View [full commit](https://github.com/MindscapeHQ/raygun4wordpress/pull/17/files). 53 | 54 | # Preventions: 55 | - Input Validation 56 | - Output Encoding 57 | - Content Security Policy (CSP) -------------------------------------------------------------------------------- /Day_11/image/reflectedXSS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/V35HR4J/30-Days-of-PHP-source-code-analysis/70f912fb2784c7a6e11f24766c28c5bb1f165dbc/Day_11/image/reflectedXSS.png -------------------------------------------------------------------------------- /Day_12/README.md: -------------------------------------------------------------------------------- 1 |  2 | # Description 3 | Stored cross-site scripting, also called persistent cross-site scripting, is a specific type of cross-site scripting (XSS) vulnerability. The terms stored or persistent mean that the attacker first sends the payload to the web application, then the application saves (i.e. stores/persists) the payload (for example, in a database or server-side text files), and finally, the application unintentionally executes the payload for every victim visiting of its web pages. 4 | 5 | # Example 6 | In this example, the developer wants to include a simple comment section on one of their pages (page.php) without deploying a full CMS such as WordPress. They include the following form on the page.php web page: 7 | 8 | ```html 9 | 16 | ``` 17 | 18 | The page.php file includes the following code: 19 | 20 | ```php 21 | // Add a new comment into the database 22 | (...) 23 | $name=$_POST["name"]; 24 | $comment=$_POST["comment"]; 25 | $sql = "INSERT INTO comments (name, comment) VALUES (?,?)"; 26 | $statement = $pdo->prepare($sql); 27 | $statement->execute([$name, $comment]); 28 | (...) 29 | // Display existing comments 30 | $comments = $db->query('SELECT * FROM comments')->fetchAll(); 31 | foreach($comments as $comment) { 32 | echo "