---
# System prepended metadata

title: '*SOME WEB THINGs THAT I LEARNED (part 5)*'
tags: [Learn with me xD]

---

# *SOME WEB THINGs THAT I LEARNED (part 5)*

#### Recently i got some new things that i learned from some challs that i want to share.

##### Welcome back everyone xDD, it's been so long since my last blog. Today let's continue with the series. >.<

## 1. The difference between MySQL and PostgreSQL
- This is a new feature that i recently learned about MySQL and PostgreSQL. I will explain this through a CTF challenge that i recently ... did not solve xD.
#### InsoBank - Insomni'hack CTF
### a) Source code:
- Let's analyze through the source code.
- The web app uses both MySQL and PostgreSQL to store the data of the user and the ID of the transactions, calculate the user's balance and anything else that related to money's transactions.
- Here it declared which database to use:![image](https://hackmd.io/_uploads/BJPZHPoY6.png)

- It will then define all the routes, i'll go through only the important ones here.
- The **```/validate```** routes:
    - It will first validate the JWT to see if we are logged in.
    - Then create a connection and a cursor to the SQL server. Keep in mind, this server is MySQL, not PostgreSQL.
    - It will then grab the total amount of the user's money, then perform to subtract the money from the total balance when performing transactions.![image](https://hackmd.io/_uploads/HJVMPcsKa.png)
    - Do you notice that? It only executes all the sql related to transactions only in MySQL, but not PostgreSQL. Keep this in mid for later ok?
    - Then it will update everything in both database to set the property ```verified``` to true (which means that the transaction is already transacted).![image](https://hackmd.io/_uploads/Sk2S8iota.png)

- The **```/transfer```** route:
    - First, it validates the user through the JWT, take in the batchid, amount and recipient from our request. Then it will check if the amount of money we transfer is greater than 0 or not.![image](https://hackmd.io/_uploads/BydLFsiKa.png)
    - It will then check for the id of the batch, the user id and whether the property ```verified``` is false or not (which means that the transaction hasn't been performed). If the batch id doesn't exist, nor the user id is not equal to our id, will return an error.![image](https://hackmd.io/_uploads/r14fghjF6.png)
    - Then it will check if 1 id(there are 3 id for each recipient, like 1 account 3 wallets) will receive the money twice. If so, then will return an error as well.![image](https://hackmd.io/_uploads/S1PFx3stT.png)
    - Here's is where it will get interesting. The next part will grab our balance and add the info into both the databases, MySQL and PostgreSQL.![image](https://hackmd.io/_uploads/H11U-hjK6.png)

- That's will cover the 2 important route of this challenge. Also, lets look at how the challenge declared the tables for the databases.:
    - MySQL:![image](https://hackmd.io/_uploads/By0zcJTK6.png)
    - PostgreSQL:![image](https://hackmd.io/_uploads/H1nEq1pFT.png)
    
    - Notice that in MySQL, it will save the amount of money we transfer, define the value for the amount column as ```DECIMAL(10,2)```, which means 10 digits, with 2 as the number of digits to the right of the decimal point.
### b) Plan:
- Now this challenge got a lot of ways to solve. I'll cover the first 2 first, the last one i'll update later.
- The first solution is abuse the ```DECIMAL(10,2)```. With 2 digits to the right, MySQL will automatically round our number up or down when we input more than 2 digits to the right of our input.
![image](https://hackmd.io/_uploads/HJMtnJptp.png)

- As you can see, it round the number 0.005 to 0.01. Now we can abuse this to get some extra money to our account.

- The second solution is related to the fact the web app is using 2 kind of databases. Running docker and testing, we can see that, when we enter a number that is too long, specifically more than 75 digits, it will return an error in MySQL server of the challenge.
- What is this mean? Well, remember i told you guys that, the server uses 2 databases, but only calculate our balance in MySQL, not PostgreSQL. So if we input a super long number, this will cause MySQL to returns an error, but not PostgreSQL. So the amount we transfer will not be subtract from our balance, since the calculation for subtraction is in MySQL, not PostgreSQL.


![image](https://hackmd.io/_uploads/SkYieg6Yp.png)

### c) Exploitation
#### Abuse MySQL rounding:
- Send the request the amount 0.0005,our balance will now have 9.995. Both will get round up to 10 and 0.01 => Extra 0.01.
![image](https://hackmd.io/_uploads/H1dQMgpYT.png)

- Start the transaction
![image](https://hackmd.io/_uploads/ByesXe6F6.png)
![image](https://hackmd.io/_uploads/HJZlEepKT.png)

###### Thực thi poc sai :)) đi dọn nhà đây sẽ làm lại sau

#### MySQL and PostgreSQL difference in data processing
- Sending a request with the amount ```09.0000000000000000000000000000000000000000000000000000000000000000000000000``` which would cause MySQL to returns an error, but not PostgreSQL.
![image](https://hackmd.io/_uploads/BJt_6g6Fa.png)
![image](https://hackmd.io/_uploads/SJ9FTgTFp.png)

- MySQL got an error, but not Postgre => The amount we want to transfer is in Postgre, now we need to transfer something valid, in order for that batch to be validate and executed.
![image](https://hackmd.io/_uploads/HyIy0e6Fp.png)
![image](https://hackmd.io/_uploads/ByXe0xTK6.png)

- Check the balance, we see this:
![image](https://hackmd.io/_uploads/ryBf0xaYT.png)

- Now transfer everything to one recipient and get the flag.
![image](https://hackmd.io/_uploads/S1l9AxTFp.png)
![image](https://hackmd.io/_uploads/ByvZ1WpKa.png)
![image](https://hackmd.io/_uploads/By4SJ-pFa.png)


## 2. The basics of Prototype Pollution
#### Filestorage - Dreamhack
### a) The basics:
- Before we go through the challenge, let's learn some of the basics of prototype pollution from what i have learned over the past few days. Let's begin >.<
#### \[1] Javascript's Object
- A Javascript's object is a collection of properties, which contains what's called a *```key:value```* pair. For example something looks like this:
```javascript
const user =  {
    username: "kietdeptrai",
    interest: "skibidi toilet",
    age: 20
}
```
- As you can see, it contains 3 properties: username, interest and age, alongside with each of the values.
- Now an object can also contains a function, something like this:
```javascript
const user =  {
    username: "wiener",
    interest: "skibidi toilet",
    age: 20,
    buyProduct: function(){
        //code here 
    }
}
```
#### \[2] Javascript's Prototype
- Prototypes are something that Javascript use when it comes to inheritance. An object can inherits another object's properties.
- For example, when you create a String in Javascript:
```javascript
let exampleString = "";
```
- This ```exampleString``` will inherits every properties from ```String.protoptype```. Remember when you type ```exampleString.{something}``` and then you receive a drop box with functions you can use like ```toLowerCase``` or something, thats the function that ```exampleString``` inherits.![image](https://hackmd.io/_uploads/H1Hic2At6.png)
#### \[3] How inheritance works
- For visualization, let's use an example:
```javascript
const user =  {
    username: "kietdeptrai",
    job: "skbidi",
    age: 20
}
```
- When you access one of its property, it will first try to find that property directly from that object. If that object does not contains that property, it will try to look for it in the object's prototype instead. For example, myObject will inherits both propertyA and B. 
- So if you call to propertyA, it will first look into myObject => does not exist => look into its prototype => exist.
![image](https://hackmd.io/_uploads/HygVv6AFp.png)

#### \[4] Access Object's prototype with __proto__
- The property that is used to point to an object prototype is not called prototype, but rather called ```__proto__```. Now it's not a default name, but it's just something all web browsers decide to use. So, you can use it to access a property's prototype, for example the above user object:
```javascript
username.__proto__                        // String.prototype
username.__proto__.__proto__              // Object.prototype
username.__proto__.__proto__.__proto__    // null (no more prototype)
```
- In addition, you can even use it to change the property of a prototype. Now what if an attacker use it to change a property to something sus?
- This could cause what so called a **```Prototype Pollution```**. Prototype pollution is a JavaScript vulnerability that enables an attacker to add arbitrary properties to global object prototypes, which may then be inherited by user-defined objects. 
- Let's look at the challenge for some better understanding.

### b) The challenge:
#### \[1] Source code
- Let's analyze through the source code.
- The challenge first defines 2 functions:
    - ```isObject```: it will set the type of the input data as object.
    - ```setValue```: this function is vulenrable to prototype pollution. The function takes in 3 params:
        - obj: the object
        - key: the property path
        - value: the value we want to assign
- The function ```setValue``` iterates through the keylist, by splitting the key value into an array using the dot(.) seperators. It will then recursively traverse through the object.
    -  Checks the object if has more than 0 property.
    -  Check if its an object. If not, create an empty object for the property.
    -  Call the ```setValue``` function to set the property by joining the ```value``` using the dot(.)seperator.
    -  If ```keylist.length == 0```, then it will assign the value to the key, since there is no property for it to recursively checks.
- Now this function is use in the ```/test?func=rename``` route. Without any sanitization, an attacker can pollute this with something fishy.
![image](https://hackmd.io/_uploads/rkERGLy56.png)

- The other things that we need to look at is the ```/readfile``` route. When the parameter ```filename``` is ```null```, it will return the value of ***```read['filename']```***. From the home page, **```read```** is an empty object, and the **```filename```** property is set to ```fake```. This will return us the fake flag. Got any ideas yet?
![image](https://hackmd.io/_uploads/SJlJvq1qT.png)

- We need to pollute this property, changing it from ```fake``` to ```flag``` so that when you access the ```/readfile``` route, it will return us the flag.
#### \[3] Plan
- Now the plan is simple. Pollute the **```read```** object's **```filename```** property, changing it to ```flag```. Now we got another problem. Let's try sending an attack and see what the problem is.
![image](https://hackmd.io/_uploads/SJx0nke5a.png)

- Now let's access ```/readfile?filename=``` with filename param is empty. If we polluted the **```filename```** property successfully, we should receive the flag, right?
![image](https://hackmd.io/_uploads/rJX_RkecT.png)

- WHY??? Welp let's take a step back and look at the basics. When the server call to the property, it will first find the property inside the object, in this case **```read```**. But look back at the code, the **```filename```** property already exists in the object. So it will still return the fake flag. 
- Prototype pollution will pollute the prototype of the object, so when we send the payload, we didn't pollute **```read```**, we polluted the prototype of **```read```**. So what can we do now?
- In the ```/test``` route, there's a interesting function:
![image](https://hackmd.io/_uploads/HyZqegx9T.png)
- The *```reset```* function resets the **```read```** object, which makes the object empty. Any ideas yet? The **```read```** object will be empty now => **```filename```** property doesn't exist now => The server will look for that property in the object prototype => Found the polluted **```filename```** in the object prototype with the value ```flag``` => Calls to it and returns the flag.

- Oh yeah, and btw, i forgot one thing, too lazy to update everythign above so ... xD. The web app is vuln to ```LFI``` which because of how the server read the file in ```/readfile``` route by appending the filename to the path. In addition, the flag is in the ```/``` path => the filename we should change to is something like this ```../../../flag```.
#### \[3] Exploitation
- First we send the following request:
![image](https://hackmd.io/_uploads/ryufElx5T.png)

- Then visit the ```reset``` function.
![image](https://hackmd.io/_uploads/H1Wxzexca.png)

- Now the```/readfile?filename=``` route.
![image](https://hackmd.io/_uploads/Byh7Egg9a.png)


### What i learned
- I'm not sure what i learned here though from the SQL chall. It's a pretty interesting bug. I've been looking for docs that writes about this but all i can find is that: The error code 1366 HY000 appears when you input into a column with an invalid value.
- You can google for it and read yourself for more information. I'll update about my wu about it later, too lazy today lmao :v.
- Pretty fun reading about prototype pollution and get to share what i understand about it xD. I did learn a lot from it too. 
- Overall, pretty cool sharing what i learnt, will do this more often xDDDD


#### More challenges to come xD
## Thank you for reading >.< Gud bye
![image](https://hackmd.io/_uploads/rk-UgZatp.png)




