shell bypass 403

GrazzMean Shell

Uname: Linux serv.m-auto.co 3.10.0-1160.42.2.el7.x86_64 #1 SMP Tue Sep 7 14:49:57 UTC 2021 x86_64
Software: nginx/1.28.2
PHP version: 8.1.34 [ PHP INFO ] PHP os: Linux
Server Ip: 41.215.243.19
Your Ip: 216.73.216.151
User: m-auto.co_vxasg6smqe (10000) | Group: psacln (1003)
Safe Mode: OFF
Disable Function:
opcache_get_status,mail

name : odoo_api.php
<?php
require_once 'odoo_config.php';

class OdooAPI {
    private $url;
    private $db;
    private $username;
    private $password;
    private $uid;
    
    public function __construct() {
        $this->url = OdooConfig::ODOO_URL;
        $this->db = OdooConfig::ODOO_DB;
        $this->username = OdooConfig::ODOO_USERNAME;
        $this->password = OdooConfig::ODOO_PASSWORD;
        $this->uid = null;
    }
    
    /**
     * Create XML-RPC request manually
     */
    private function createXmlRpcRequest($method, $params) {
        $xml = '<?xml version="1.0"?>' . "\n";
        $xml .= '<methodCall>' . "\n";
        $xml .= '<methodName>' . htmlspecialchars($method) . '</methodName>' . "\n";
        $xml .= '<params>' . "\n";
        
        foreach ($params as $param) {
            $xml .= '<param>' . $this->encodeValue($param) . '</param>' . "\n";
        }
        
        $xml .= '</params>' . "\n";
        $xml .= '</methodCall>' . "\n";
        
        return $xml;
    }
    
    /**
     * Encode value for XML-RPC
     */
    private function encodeValue($value) {
        if (is_string($value)) {
            return '<value><string>' . htmlspecialchars($value) . '</string></value>';
        } elseif (is_int($value)) {
            return '<value><int>' . $value . '</int></value>';
        } elseif (is_bool($value)) {
            return '<value><boolean>' . ($value ? '1' : '0') . '</boolean></value>';
        } elseif (is_array($value)) {
            if (array_keys($value) === range(0, count($value) - 1)) {
                // Indexed array
                $xml = '<value><array><data>';
                foreach ($value as $item) {
                    $xml .= $this->encodeValue($item);
                }
                $xml .= '</data></array></value>';
                return $xml;
            } else {
                // Associative array (struct)
                $xml = '<value><struct>';
                foreach ($value as $key => $val) {
                    $xml .= '<member>';
                    $xml .= '<name>' . htmlspecialchars($key) . '</name>';
                    $xml .= $this->encodeValue($val);
                    $xml .= '</member>';
                }
                $xml .= '</struct></value>';
                return $xml;
            }
        } elseif (is_null($value) || $value === false) {
            return '<value><boolean>0</boolean></value>';
        } else {
            return '<value><string>' . htmlspecialchars((string)$value) . '</string></value>';
        }
    }
    
    /**
     * Parse XML-RPC response
     */
    private function parseXmlRpcResponse($xml) {
        $doc = new DOMDocument();
        $doc->loadXML($xml);
        
        $fault = $doc->getElementsByTagName('fault');
        if ($fault->length > 0) {
            throw new Exception('XML-RPC Fault');
        }
        
        $params = $doc->getElementsByTagName('param');
        if ($params->length > 0) {
            return $this->decodeValue($params->item(0)->firstChild);
        }
        
        return false;
    }
    
    /**
     * Decode XML-RPC value
     */
    private function decodeValue($node) {
        if (!$node) return null;
        
        $value = $node->firstChild;
        if (!$value) return null;
        
        switch ($value->nodeName) {
            case 'string':
                return $value->nodeValue;
            case 'int':
            case 'i4':
                return (int)$value->nodeValue;
            case 'boolean':
                return (bool)$value->nodeValue;
            case 'array':
                $result = [];
                $data = $value->getElementsByTagName('value');
                foreach ($data as $item) {
                    $result[] = $this->decodeValue($item);
                }
                return $result;
            case 'struct':
                $result = [];
                $members = $value->getElementsByTagName('member');
                foreach ($members as $member) {
                    $name = $member->getElementsByTagName('name')->item(0)->nodeValue;
                    $val = $member->getElementsByTagName('value')->item(0);
                    $result[$name] = $this->decodeValue($val);
                }
                return $result;
            default:
                return $value->nodeValue;
        }
    }
    
    /**
     * Authenticate with Odoo
     */
    private function authenticate() {
        if ($this->uid !== null) {
            return $this->uid;
        }
        
        try {
            $xml = $this->createXmlRpcRequest('authenticate', [
                $this->db,
                $this->username,
                $this->password,
                []
            ]);
            
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $this->url . OdooConfig::XMLRPC_COMMON);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if ($httpCode !== 200) {
                throw new Exception('HTTP Error: ' . $httpCode);
            }
            
            $this->uid = $this->parseXmlRpcResponse($response);
            
            if (!$this->uid || $this->uid === false) {
                throw new Exception('Authentication failed');
            }
            
            return $this->uid;
        } catch (Exception $e) {
            error_log('Odoo Authentication Error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Execute Odoo method
     */
    private function execute($model, $method, $args = [], $kwargs = []) {
        $uid = $this->authenticate();
        if (!$uid) {
            return false;
        }
        
        try {
            $xml = $this->createXmlRpcRequest('execute_kw', [
                $this->db,
                $uid,
                $this->password,
                $model,
                $method,
                $args,
                $kwargs
            ]);
            
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $this->url . OdooConfig::XMLRPC_OBJECT);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            
            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if ($httpCode !== 200) {
                throw new Exception('HTTP Error: ' . $httpCode);
            }
            
            return $this->parseXmlRpcResponse($response);
        } catch (Exception $e) {
            error_log('Odoo API Error: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Create a new lead in CRM
     */
    public function createLead($data) {
        $leadData = [
            'name' => $data['name'] ?? 'New Lead',
            'contact_name' => $data['contact_name'] ?? '',
            'phone' => $data['phone'] ?? '',
            'email_from' => $data['email'] ?? '',
            'description' => $data['description'] ?? '',
            'source_id' => $this->getSourceId($data['source'] ?? ''),
            'stage_id' => OdooConfig::LEAD_STAGE_NEW,
            'country_id' => OdooConfig::DEFAULT_COUNTRY_ID,
            'company_id' => OdooConfig::DEFAULT_COMPANY_ID,
            'user_id' => false, // Unassigned initially
        ];
        
        // Add custom fields if provided
        if (isset($data['branch_name'])) {
            $leadData['x_branch'] = $data['branch_name'];
        }
        
        if (isset($data['service_type'])) {
            $leadData['x_service_type'] = $data['service_type'];
        }
        
        if (isset($data['car_info'])) {
            $leadData['x_car_info'] = $data['car_info'];
        }
        
        if (isset($data['visit_date'])) {
            $leadData['x_visit_date'] = $data['visit_date'];
        }
        
        if (isset($data['reservation_date'])) {
            $leadData['x_reservation_date'] = $data['reservation_date'];
        }
        
        return $this->execute('crm.lead', 'create', [$leadData]);
    }
    
    /**
     * Get or create source ID
     */
    private function getSourceId($sourceName) {
        if (empty($sourceName)) {
            return false;
        }
        
        // Search for existing source
        $sourceIds = $this->execute('utm.source', 'search', [['name', '=', $sourceName]]);
        
        if ($sourceIds && count($sourceIds) > 0) {
            return $sourceIds[0];
        }
        
        // Create new source if not found
        $sourceId = $this->execute('utm.source', 'create', [['name' => $sourceName]]);
        return $sourceId;
    }
    
    /**
     * Create partner (customer) record
     */
    public function createPartner($data) {
        $partnerData = [
            'name' => $data['name'] ?? '',
            'phone' => $data['phone'] ?? '',
            'email' => $data['email'] ?? '',
            'is_company' => false,
            'customer_rank' => 1,
            'country_id' => OdooConfig::DEFAULT_COUNTRY_ID,
        ];
        
        return $this->execute('res.partner', 'create', [$partnerData]);
    }
    
    /**
     * Search for existing partner by phone or email
     */
    public function findPartner($phone = '', $email = '') {
        $domain = [];
        
        if (!empty($phone)) {
            $domain[] = ['phone', '=', $phone];
        }
        
        if (!empty($email)) {
            if (!empty($domain)) {
                $domain = ['|'] + $domain + [['email', '=', $email]];
            } else {
                $domain[] = ['email', '=', $email];
            }
        }
        
        if (empty($domain)) {
            return false;
        }
        
        $partnerIds = $this->execute('res.partner', 'search', [$domain], ['limit' => 1]);
        
        return $partnerIds && count($partnerIds) > 0 ? $partnerIds[0] : false;
    }
    
    /**
     * Create activity/task for follow-up
     */
    public function createActivity($leadId, $activityType, $summary, $note = '') {
        $activityData = [
            'res_model' => 'crm.lead',
            'res_id' => $leadId,
            'activity_type_id' => $activityType,
            'summary' => $summary,
            'note' => $note,
            'date_deadline' => date('Y-m-d', strtotime('+1 day')),
        ];
        
        return $this->execute('mail.activity', 'create', [$activityData]);
    }
    
    /**
     * Test connection to Odoo
     */
    public function testConnection() {
        try {
            $uid = $this->authenticate();
            if ($uid) {
                // Try to read user info
                $userInfo = $this->execute('res.users', 'read', [$uid], ['fields' => ['name', 'login']]);
                return $userInfo !== false;
            }
            return false;
        } catch (Exception $e) {
            error_log('Odoo Connection Test Error: ' . $e->getMessage());
            return false;
        }
    }
}
?>
© 2026 GrazzMean