Prototype Pollution
Unicode Normalization
javascript의 취약점인 prototype pollution을 이용하는 문제다
지금까지 접한 워게임 중 제일 답답했던 문제다
문제에서 요구하는 바는 다음과 같다
순서대로 알아보자
About Unicode - https://unicode.org/reports/tr15/
Unicode Normalization - https://appcheck-ng.com/wp-content/uploads/unicode_normalization.html
toLowerCase() 함수는 입력받은 문자를 정규화를 거친 후 소문자로 바꾸게 된다
가장 보편적인 방식은 NFC방식이다
위 사이트에서 NFC 방식으로 충돌이 일어나는 문자를 3개 찾았다
즉, toLowerCase는 kelvin sign -> Capital K -> small k 의 과정을 거친다
로그인에 성공했으니 rce코드를 작성해야한다
Prototype pollution RCE - https://book.hacktricks.xyz/pentesting-web/deserialization/nodejs-proto-prototype-pollution/prototype-pollution-to-rce
위 블로그와 문제에서 제공된 /debug엔드포인트의 코드를 참고하여 작성했다
console.log(require('child_process').spawnSync('cat', ['/app/flag']).stdout.toString());
Node.js command line - https://nodejs.org/api/cli.html
--require
옵션은 import 전에 실행이 된다고 한다
--require
을 통해 방금 작성한 rce코드 파일을 지정해준다면 prototype pollution으로 실행할 수 있다
Javascript Object - https://developer.mozilla.org/ko/docs/Learn/JavaScript/Objects/Object_prototypes
prototype pollution - https://www.imperva.com/learn/application-security/prototype-pollution/
즉, __proto__
에 대한 입력값 검증이 없다면 다른 객체의 attr을 변경하거나 RCE가 가능하다는 말이다
prototype pollution이 발생하기 위한 조건은 다음과 같다
문제의 userfunc.js
에서 객체 병합이 존재하기 때문에 prototype pollution을 이용할 수 있다
merge함수를 사용하는 /raw
엔드포인트의 코드를 확인하면 아래와 같다
filename에 대한 입력값 검증없이, 심지어 템플릿 형태로 받기때문에 prototype pollution을 쉽게 사용 가능하다
a","__proto__":{"NODE_OPTIONS":"-r /app/publics/uploads/pollute.jpg"},"a":"b
payload를 injection한 후 debug모드를 실행하면 flag를 획득할 수 있다
아까 확인한 대로 rce코드가 먼저 나오는 걸 알 수 있다