[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fwFAlzIVXN-n9zCUdwU4wcRVBCubf45M-cA9VmDcewiE":3},{"id":4,"question":5,"answer":6,"answerHtml":7,"slug":8,"keywords":9,"article":10,"status":34,"aiModel":39,"aiConfidence":39,"updatedAt":51,"createdAt":51,"_status":50},268,"How do I set up remote debugging for Server Backup Manager by adding JVM debug parameters?","Add the line `additional.19=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000` to the configuration file `\u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf`. For JDK 5-8 use `address=8000`; avoid the `address=*:8000` syntax meant for JDK 9+. Then restart the service with `\u002Fetc\u002Finit.d\u002Fcdp-server restart` and attach your IDE to port 8000. The full setup is covered in the [Server Backup Manager Vulnerability Debugging Environment Setup](\u002Fnews\u002Fserver-backup-manager-vulnerability-debugging-environment-setup).","\u003Cp>Add the line `additional.19=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000` to the configuration file `\u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf`. For JDK 5-8 use `address=8000`; avoid the `address=*:8000` syntax meant for JDK 9+. Then restart the service with `\u002Fetc\u002Finit.d\u002Fcdp-server restart` and attach your IDE to port 8000. The full setup is covered in the [Server Backup Manager Vulnerability Debugging Environment Setup](\u002Fnews\u002Fserver-backup-manager-vulnerability-debugging-environment-setup).\u003C\u002Fp>\u003Cp>\u003Ca href=\"\u002Fnews\u002Fserver-backup-manager-vulnerability-debugging-environment-setup\">Read the related One Day Sec article\u003C\u002Fa>\u003C\u002Fp>","how-do-i-set-up-remote-debugging-for-server-backup-manager-by-adding-jvm-debug-p-1777484386459","remote debugging, JVM debugging, JDWP, Server Backup Manager",{"id":11,"title":12,"slug":13,"description":14,"content":15,"contentHtml":30,"cover":31,"author":32,"views":19,"readingTime":33,"status":34,"publishedAt":35,"seo":36,"tags":41,"qaPairs":42,"meta":47,"updatedAt":48,"createdAt":49,"_status":50},70,"Server Backup Manager Vulnerability Debugging Environment Setup","server-backup-manager-vulnerability-debugging-environment-setup","Learn to set up a vulnerability debugging environment for Server Backup Manager (SBM), including installation, debugging configuration, and user database file extraction.",{"root":16},{"type":17,"format":18,"indent":19,"version":20,"children":21,"direction":29},"root","",0,1,[22],{"type":23,"format":18,"indent":19,"version":20,"children":24,"direction":29},"paragraph",[25],{"mode":26,"text":27,"type":28,"style":18,"detail":19,"format":19,"version":20},"normal","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Server Backup Manager (SBM) is a fast, cost-effective, and high-performance backup software suitable for Linux and Windows servers in both physical and virtual environments. This article will introduce the method for setting up a vulnerability debugging environment for Server Backup Manager.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Environment Setup\u003C\u002Fli>\u003Cli>Debugging Environment Setup\u003C\u002Fli>\u003Cli>User Database File Extraction\u003C\u002Fli>\u003Cli>Brief Introduction to CVE-2022-36537\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Environment Setup\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Installation Reference: http:\u002F\u002Fwiki.r1soft.com\u002Fdisplay\u002FServerBackupManager\u002FInstall+and+Upgrade+Server+Backup+Manager+on+Debian+and+Ubuntu.html\u003C\u002Fp>\u003Cp>The reference provides two installation methods, but during my testing, I encountered the error of missing the file \u002Fetc\u002Finit.d\u002Fcdp-server in both cases.\u003C\u002Fp>\u003Cp>Here, we switch to installing an older version of Server Backup Manager, and the installation is successfully completed. The specific steps are as follows:\u003C\u002Fp>\u003Ch3>1. Download the installation package\u003C\u002Fh3>\u003Cp>http:\u002F\u002Fr1soft.mirror.iweb.ca\u002Frepo.r1soft.com\u002Frelease\u002F6.2.2\u002F78\u002Ftrials\u002FR1soft-ServerBackup-Manager-SE-linux64-6-2-2.zip\u003C\u002Fp>\u003Ch3>2. Install\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>unzip R1soft-ServerBackup-Manager-SE-linux64-6-2-2.zip\u003Cbr>dpkg -i *.deb\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>3. Configure\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>serverbackup-setup --user admin --pass 123456\u003Cbr>serverbackup-setup --http-port 8080 --https-port 8443\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Start the service\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u002Fetc\u002Finit.d\u002Fcdp-server restart\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The web management pages are as follows:\u003C\u002Fp>\u003Cp>http:\u002F\u002F127.0.0.1:8080\u003C\u002Fp>\u003Cp>https:\u002F\u002F127.0.0.1:8443\u003C\u002Fp>\u003Ch2>0x03 Debugging Environment Setup\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>The research process is as follows:\u003C\u002Fp>\u003Ch4>(1)\u003C\u002Fh4>\u003Cp>Examining the file \u002Fetc\u002Finit.d\u002Fcdp-server reveals it is a text file. From its content, the default installation path is identified as \u002Fusr\u002Fsbin\u002Fr1soft, with the main program located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Fbin\u002Fcdpserver.\u003C\u002Fp>\u003Cp>The web path is: \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps, which contains the following two default files:\u003C\u002Fp>\u003Cul>\u003Cli>r1soft-api.war\u003C\u002Fli>\u003Cli>zk-web.war\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(2)\u003C\u002Fh4>\u003Cp>Checking process information: ps aux |grep cdp\u003C\u002Fp>\u003Cp>Returns:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>root        2250  0.3  0.1  20836  2488 ?        Sl   22:18   0:01 .\u002Fcdpserver \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003Cbr>root        2252 22.6 51.2 8747176 1036408 ?     Sl   22:18   1:55 .\u002Fcdpserver \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Obtaining the configuration file path: \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003C\u002Fp>\u003Ch4>(3)\u003C\u002Fh4>\u003Cp>Adding Java debugging parameters by modifying the file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf, with the following content added:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>additional.19=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Here, use the parameter address=8000 corresponding to JDK5-8; do not use the parameter address=*:8000 corresponding to JDK9 and higher versions.\u003C\u002Fp>\u003Ch4>(4)\u003C\u002Fh4>\u003Cp>Restart the service: \u002Fetc\u002Finit.d\u002Fcdp-server restart\u003C\u002Fp>\u003Ch4>(5)\u003C\u002Fh4>\u003Cp>Download the source code from the server\u003C\u002Fp>\u003Cp>Source code location 1: JAR files in \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u003C\u002Fp>\u003Cp>Source code location 2: Extract the class files from the folder \\WEB-INF\\classes\\ in \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps\u002Fzk-web.war\u003C\u002Fp>\u003Ch4>(6)\u003C\u002Fh4>\u003Cp>Set breakpoints in IDEA and configure remote debugging; successful remote debugging is shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770018749050_0_e007226451.png\">\u003C\u002Fp>\u003Ch2>0x04 User Database File Extraction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>The research process is as follows:\u003C\u002Fp>\u003Ch4>(1) Locating the user creation operation\u003C\u002Fh4>\u003Cp>The file is located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps\u002Fzk-web.war\\WEB-INF\\classes\\com\\r1soft\\backup\\server\\web\\user\\Controller.class, with the core code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public void onDoCreate(Event evt) {\u003Cbr>        Clients.clearBusy();\u003Cbr>        if (this.createWindow == null) {\u003Cbr>            throw new IllegalStateException(\"CreateWindow object is not available\");\u003Cbr>        } else {\u003Cbr>            User currentUser = SessionUtil.getCurrentUser();\u003Cbr>            User user = new User();\u003Cbr>            user.setUsername(this.createWindow.getUsername());\u003Cbr>            user.setPassword((new PasswordEncoder()).encodePassword(this.createWindow.getPassword(), (Object)null));\u003Cbr>            user.setName(this.createWindow.getName());\u003Cbr>            user.setEmailAddress(this.createWindow.getEmailAddress());\u003Cbr>            user.setUserType(this.createWindow.getUserType());\u003Cbr>            List\u003Cvolume> volumes = new ArrayList();\u003Cbr>            Map\u003Cstring, string=\"\"> attributes = new HashMap();\u003Cbr>            attributes.putAll(this.createWindow.getAttributesMap());\u003Cbr>            if (!user.isSuperUser()) {\u003Cbr>                if (this.createWindow.getUserType().equals(UserType.SUB_USER)) {\u003Cbr>                    user.getAdministrators().addAll(this.createWindow.getAdministrators());\u003Cbr>                    if (currentUser.isPowerUser() &amp;&amp; !user.getAdministrators().contains(currentUser)) {\u003Cbr>                        user.getAdministrators().add(currentUser);\u003Cbr>                    }\u003Cbr>                } else if (this.createWindow.getUserType().equals(UserType.POWER_USER)) {\u003Cbr>                    user.getSubUsers().addAll(this.createWindow.getSubUsers());\u003Cbr>                }\u003Cbr>\u003Cbr>                user.getGroups().addAll(this.createWindow.getGroups());\u003Cbr>                Set\u003Cuseragentpermission> permissions = new HashSet(this.createWindow.getUserAgentPermissions());\u003Cbr>                Iterator i$ = permissions.iterator();\u003Cbr>\u003Cbr>                while(i$.hasNext()) {\u003Cbr>                    UserAgentPermission permission = (UserAgentPermission)i$.next();\u003Cbr>                    permission.setUser(user);\u003Cbr>                }\u003Cbr>\u003Cbr>                user.getUserAgentPermissions().addAll(permissions);\u003Cbr>                volumes.addAll(this.createWindow.getVolumes());\u003Cbr>                if (user.isPowerUser()) {\u003Cbr>                    attributes.putAll(this.createWindow.getPowerUserAttributesMap());\u003Cbr>                }\u003Cbr>            }\u003Cbr>\u003Cbr>            if (this.createWindow.getSelectedLocale() != null) {\u003Cbr>                attributes.put(UserAttributes.SELECTED_LOCALE.getDataKey(), this.createWindow.getSelectedLocale().toString());\u003Cbr>            }\u003Cbr>\u003Cbr>            try {\u003Cbr>                UserFacade.make().createUser(SessionUtil.buildActivitySource(), user, volumes, attributes);\u003Cbr>                WebUtil.showSuccessBox(logger, \"Messages.UI.successfully-created-user\", new Object[]{user.getUsername()});\u003Cbr>            } catch (UserException var9) {\u003Cbr>                this.showErrorBox(var9, \"Messages.UI.could-not-create-user\", new Object[]{user.getUsername()});\u003Cbr>            }\u003Cbr>\u003Cbr>            this.createWindow.detach();\u003Cbr>            this.createWindow = null;\u003Cbr>        }\u003Cbr>    }\u003C\u002Fuseragentpermission>\u003C\u002Fstring,>\u003C\u002Fvolume>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Follow up on (new PasswordEncoder()).encodePassword(this.createWindow.getPassword(), (Object)null), specific location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.facade-&gt;PasswordEncoder.class, core code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public String encodePassword(String var1, Object var2) throws DataAccessException {\u003Cbr>        MessageDigest var3 = null;\u003Cbr>\u003Cbr>        try {\u003Cbr>            var3 = MessageDigest.getInstance(\"SHA-1\");\u003Cbr>        } catch (NoSuchAlgorithmException var7) {\u003Cbr>            throw new RuntimeException(var7);\u003Cbr>        }\u003Cbr>\u003Cbr>        try {\u003Cbr>            var3.update(var1.getBytes(\"UTF-8\"));\u003Cbr>        } catch (UnsupportedEncodingException var6) {\u003Cbr>            throw new RuntimeException(var6);\u003Cbr>        }\u003Cbr>\u003Cbr>        byte[] var4 = var3.digest();\u003Cbr>        String var5 = (new BASE64Encoder()).encode(var4);\u003Cbr>        return var5;\u003Cbr>    }\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>From the above code, the encryption algorithm for user passwords can be derived\u003C\u002Fp>\u003Ch4>(2) Locate the specific code implementation for user creation\u003C\u002Fh4>\u003Cp>Follow up on UserFacade.make().createUser(SessionUtil.buildActivitySource(), user, volumes, attributes);, the specific location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.facade-&gt;UserFacade.class, the core code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public User createUser(ActivitySource var1, User var2, List\u003Cvolume> var3, Map\u003Cstring, string=\"\"> var4) throws UserException {\u003Cbr>\u002F\u002FHide code\u003Cbr>            this.validateUser(var2);\u003Cbr>\u003Cbr>            try {\u003Cbr>                if (var4 != null &amp;&amp; !var4.isEmpty()) {\u003Cbr>                    HashSet var5 = new HashSet();\u003Cbr>                    Iterator var6 = Arrays.asList(UserFacade.PowerUserAttributes.values()).iterator();\u003Cbr>\u003Cbr>                    while(var6.hasNext()) {\u003Cbr>                        PowerUserAttributes var7 = (PowerUserAttributes)var6.next();\u003Cbr>                        String var8 = var4.containsKey(var7.getDataKey()) ? (String)var4.get(var7.getDataKey()) : var7.getDefaultValue();\u003Cbr>                        var5.add(new UserData(var2, var7.getDataKey(), var8));\u003Cbr>                        var4.remove(var7.getDataKey());\u003Cbr>                    }\u003Cbr>\u003Cbr>                    var6 = var4.entrySet().iterator();\u003Cbr>\u003Cbr>                    while(var6.hasNext()) {\u003Cbr>                        Map.Entry var13 = (Map.Entry)var6.next();\u003Cbr>                        var5.add(new UserData(var2, (String)var13.getKey(), (Serializable)var13.getValue()));\u003Cbr>                    }\u003Cbr>\u003Cbr>                    var2 = com.r1soft.backup.server.om.facade.UserFacade.getInstance().persistPOJOWithData(var2, var5);\u003Cbr>                } else {\u003Cbr>                    var2 = (User)EntityManagerFacade.persistPOJO(var2);\u003Cbr>                }\u003Cbr>\u002F\u002FHide code\u003Cbr>    }\u003C\u002Fstring,>\u003C\u002Fvolume>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Follow up on (User)EntityManagerFacade.persistPOJO(var2), located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.om.entity-&gt;EntityManagerFacade.class. The core code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>private static EntityManagerFactory emf = null;\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" baseentity\u003C?=\"\">&gt;, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; facadeMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" ipojo\u003C?=\"\" baseentity\u003C?=\"\">, ?, ?&gt;&gt;, Class\u003C!--? extends BaseEntity\u003C?-->&gt;&gt; pojoToEntityMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" ipojo\u003C?=\"\" baseentity\u003C?=\"\">, ?, ?&gt;&gt;, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; pojoToFacadeMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" object=\"\">, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; pojoIDToFacadeMap = new HashMap();\u003Cbr>protected static final QueryOrderByType DEFAULT_SORT_DIRECTION;\u003Cbr>protected static final String PERSISTENCEUNITNAME = \"CDP-PU\";\u003Cbr>protected static final String HIBERNATECONFFILE = \"com\u002Fr1soft\u002Fbackup\u002Fserver\u002Fom\u002Fhibernate.cfg.xml\";\u003Cbr>protected static final String DBUSER = \"r1derbyuser\";\u003Cbr>protected static final String DBPASS = \"V?Rdp*eT6N9t8aW3KDoh\";\u003Cbr>protected static final String H2PATH = \"h2\u002Fr1backup\";\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>From the above code, it can be seen that the JDBC H2 database is used here to store data. The configuration file is \"com\u002Fr1soft\u002Fbackup\u002Fserver\u002Fom\u002Fhibernate.cfg.xml\", and the actual corresponding file location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.om.hibernate.cfg.xml. Its core content is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   \u003Cproperty name=\"hibernate.connection.url\">jdbc:h2:.\u002Fdata\u002Fh2\u002Fr1backup\u003C\u002Fproperty>\u003Cbr>   \u003Cbr>   \u003Cproperty name=\"hibernate.connection.driver_class\">org.h2.Driver\u003C\u002Fproperty>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Based on the above content, we can obtain the complete database connection parameters, and the actual database file location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Fdata\u002Fh2\u002Fr1backup.h2.db.\u003C\u002Fp>\u003Cp>Data validation test is performed here: manually create a user admin2 with the password set to 123456. Through dynamic debugging, the encrypted password content is derived as fEqNCco3Yq9h5ZUglD3CZJT4lBs=. Then, open the file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fdata\u002Fh2\u002Fr1backup.h2.db in binary mode. The username and encrypted password content can be obtained from the file content, as shown in the figure below.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770018762692_1_9d8fe475d7.png\">\u003C\u002Fp>\u003Ch2>0x05 CVE-2022-36537 Brief Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Vulnerability analysis article: https:\u002F\u002Fmedium.com\u002Fnumen-cyber-labs\u002Fcve-2022-36537-vulnerability-technical-analysis-with-exp-667401766746\u003C\u002Fp>\u003Cp>The article mentions that triggering RCE requires uploading a com.mysql.jdbc.Driver file containing a Payload.\u003C\u002Fp>\u003Cp>This operation can only be exploited once, for the following reasons:\u003C\u002Fp>\u003Cp>By default, there is an uploadable icon on the Database Driver page of the management backend, as shown in the figure below.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770018783143_2_d2f6ef3eb1.png\">\u003C\u002Fp>\u003Cp>After uploading, the uploadable icon will no longer be displayed, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fuploads\u002Fdocx_image_1770018792987_3_724e248aee.png\">\u003C\u002Fp>\u003Cp>Triggering RCE is achieved by uploading the MySQL DataBase Driver through the program, so this function becomes unavailable after one attack and cannot be reused\u003C\u002Fp>\u003Cp>Attack detection: After triggering RCE, a file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fdatabase-drivers\u002Fmysql-connector.jar will be uploaded to the system, where com\\mysql\\jdbc\\Driver.class is the payload used by the attacker\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces solutions to some issues encountered during the setup of the Server Backup Manager debugging environment, analyzes methods for extracting user database files, and provides recommendations for detecting CVE-2022-36537.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>","text","ltr","\u003Chtml>\u003Chead>\u003C\u002Fhead>\u003Cbody>\u003Ch2>0x00 Preface\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Server Backup Manager (SBM) is a fast, cost-effective, and high-performance backup software suitable for Linux and Windows servers in both physical and virtual environments. This article will introduce the method for setting up a vulnerability debugging environment for Server Backup Manager.\u003C\u002Fp>\u003Ch2>0x01 Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article will cover the following topics:\u003C\u002Fp>\u003Cul>\u003Cli>Environment Setup\u003C\u002Fli>\u003Cli>Debugging Environment Setup\u003C\u002Fli>\u003Cli>User Database File Extraction\u003C\u002Fli>\u003Cli>Brief Introduction to CVE-2022-36537\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>0x02 Environment Setup\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Installation Reference: http:\u002F\u002Fwiki.r1soft.com\u002Fdisplay\u002FServerBackupManager\u002FInstall+and+Upgrade+Server+Backup+Manager+on+Debian+and+Ubuntu.html\u003C\u002Fp>\u003Cp>The reference provides two installation methods, but during my testing, I encountered the error of missing the file \u002Fetc\u002Finit.d\u002Fcdp-server in both cases.\u003C\u002Fp>\u003Cp>Here, we switch to installing an older version of Server Backup Manager, and the installation is successfully completed. The specific steps are as follows:\u003C\u002Fp>\u003Ch3>1. Download the installation package\u003C\u002Fh3>\u003Cp>http:\u002F\u002Fr1soft.mirror.iweb.ca\u002Frepo.r1soft.com\u002Frelease\u002F6.2.2\u002F78\u002Ftrials\u002FR1soft-ServerBackup-Manager-SE-linux64-6-2-2.zip\u003C\u002Fp>\u003Ch3>2. Install\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>unzip R1soft-ServerBackup-Manager-SE-linux64-6-2-2.zip\u003Cbr>dpkg -i *.deb\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>3. Configure\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>serverbackup-setup --user admin --pass 123456\u003Cbr>serverbackup-setup --http-port 8080 --https-port 8443\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch3>4. Start the service\u003C\u002Fh3>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>\u002Fetc\u002Finit.d\u002Fcdp-server restart\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>The web management pages are as follows:\u003C\u002Fp>\u003Cp>http:\u002F\u002F127.0.0.1:8080\u003C\u002Fp>\u003Cp>https:\u002F\u002F127.0.0.1:8443\u003C\u002Fp>\u003Ch2>0x03 Debugging Environment Setup\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>The research process is as follows:\u003C\u002Fp>\u003Ch4>(1)\u003C\u002Fh4>\u003Cp>Examining the file \u002Fetc\u002Finit.d\u002Fcdp-server reveals it is a text file. From its content, the default installation path is identified as \u002Fusr\u002Fsbin\u002Fr1soft, with the main program located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Fbin\u002Fcdpserver.\u003C\u002Fp>\u003Cp>The web path is: \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps, which contains the following two default files:\u003C\u002Fp>\u003Cul>\u003Cli>r1soft-api.war\u003C\u002Fli>\u003Cli>zk-web.war\u003C\u002Fli>\u003C\u002Ful>\u003Ch4>(2)\u003C\u002Fh4>\u003Cp>Checking process information: ps aux |grep cdp\u003C\u002Fp>\u003Cp>Returns:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>root        2250  0.3  0.1  20836  2488 ?        Sl   22:18   0:01 .\u002Fcdpserver \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003Cbr>root        2252 22.6 51.2 8747176 1036408 ?     Sl   22:18   1:55 .\u002Fcdpserver \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Obtaining the configuration file path: \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf\u003C\u002Fp>\u003Ch4>(3)\u003C\u002Fh4>\u003Cp>Adding Java debugging parameters by modifying the file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fserver.conf, with the following content added:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>additional.19=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>\u003Cstrong>Note:\u003C\u002Fstrong>\u003C\u002Fp>\u003Cp>Here, use the parameter address=8000 corresponding to JDK5-8; do not use the parameter address=*:8000 corresponding to JDK9 and higher versions.\u003C\u002Fp>\u003Ch4>(4)\u003C\u002Fh4>\u003Cp>Restart the service: \u002Fetc\u002Finit.d\u002Fcdp-server restart\u003C\u002Fp>\u003Ch4>(5)\u003C\u002Fh4>\u003Cp>Download the source code from the server\u003C\u002Fp>\u003Cp>Source code location 1: JAR files in \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u003C\u002Fp>\u003Cp>Source code location 2: Extract the class files from the folder \\WEB-INF\\classes\\ in \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps\u002Fzk-web.war\u003C\u002Fp>\u003Ch4>(6)\u003C\u002Fh4>\u003Cp>Set breakpoints in IDEA and configure remote debugging; successful remote debugging is shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770018749050_0_e007226451-1.png\">\u003C\u002Fp>\u003Ch2>0x04 User Database File Extraction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>The research process is as follows:\u003C\u002Fp>\u003Ch4>(1) Locating the user creation operation\u003C\u002Fh4>\u003Cp>The file is located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Fwebapps\u002Fzk-web.war\\WEB-INF\\classes\\com\\r1soft\\backup\\server\\web\\user\\Controller.class, with the core code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public void onDoCreate(Event evt) {\u003Cbr>        Clients.clearBusy();\u003Cbr>        if (this.createWindow == null) {\u003Cbr>            throw new IllegalStateException(\"CreateWindow object is not available\");\u003Cbr>        } else {\u003Cbr>            User currentUser = SessionUtil.getCurrentUser();\u003Cbr>            User user = new User();\u003Cbr>            user.setUsername(this.createWindow.getUsername());\u003Cbr>            user.setPassword((new PasswordEncoder()).encodePassword(this.createWindow.getPassword(), (Object)null));\u003Cbr>            user.setName(this.createWindow.getName());\u003Cbr>            user.setEmailAddress(this.createWindow.getEmailAddress());\u003Cbr>            user.setUserType(this.createWindow.getUserType());\u003Cbr>            List\u003Cvolume> volumes = new ArrayList();\u003Cbr>            Map\u003Cstring, string=\"\"> attributes = new HashMap();\u003Cbr>            attributes.putAll(this.createWindow.getAttributesMap());\u003Cbr>            if (!user.isSuperUser()) {\u003Cbr>                if (this.createWindow.getUserType().equals(UserType.SUB_USER)) {\u003Cbr>                    user.getAdministrators().addAll(this.createWindow.getAdministrators());\u003Cbr>                    if (currentUser.isPowerUser() &amp;&amp; !user.getAdministrators().contains(currentUser)) {\u003Cbr>                        user.getAdministrators().add(currentUser);\u003Cbr>                    }\u003Cbr>                } else if (this.createWindow.getUserType().equals(UserType.POWER_USER)) {\u003Cbr>                    user.getSubUsers().addAll(this.createWindow.getSubUsers());\u003Cbr>                }\u003Cbr>\u003Cbr>                user.getGroups().addAll(this.createWindow.getGroups());\u003Cbr>                Set\u003Cuseragentpermission> permissions = new HashSet(this.createWindow.getUserAgentPermissions());\u003Cbr>                Iterator i$ = permissions.iterator();\u003Cbr>\u003Cbr>                while(i$.hasNext()) {\u003Cbr>                    UserAgentPermission permission = (UserAgentPermission)i$.next();\u003Cbr>                    permission.setUser(user);\u003Cbr>                }\u003Cbr>\u003Cbr>                user.getUserAgentPermissions().addAll(permissions);\u003Cbr>                volumes.addAll(this.createWindow.getVolumes());\u003Cbr>                if (user.isPowerUser()) {\u003Cbr>                    attributes.putAll(this.createWindow.getPowerUserAttributesMap());\u003Cbr>                }\u003Cbr>            }\u003Cbr>\u003Cbr>            if (this.createWindow.getSelectedLocale() != null) {\u003Cbr>                attributes.put(UserAttributes.SELECTED_LOCALE.getDataKey(), this.createWindow.getSelectedLocale().toString());\u003Cbr>            }\u003Cbr>\u003Cbr>            try {\u003Cbr>                UserFacade.make().createUser(SessionUtil.buildActivitySource(), user, volumes, attributes);\u003Cbr>                WebUtil.showSuccessBox(logger, \"Messages.UI.successfully-created-user\", new Object[]{user.getUsername()});\u003Cbr>            } catch (UserException var9) {\u003Cbr>                this.showErrorBox(var9, \"Messages.UI.could-not-create-user\", new Object[]{user.getUsername()});\u003Cbr>            }\u003Cbr>\u003Cbr>            this.createWindow.detach();\u003Cbr>            this.createWindow = null;\u003Cbr>        }\u003Cbr>    }\u003C\u002Fuseragentpermission>\u003C\u002Fstring,>\u003C\u002Fvolume>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Follow up on (new PasswordEncoder()).encodePassword(this.createWindow.getPassword(), (Object)null), specific location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.facade-&gt;PasswordEncoder.class, core code as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public String encodePassword(String var1, Object var2) throws DataAccessException {\u003Cbr>        MessageDigest var3 = null;\u003Cbr>\u003Cbr>        try {\u003Cbr>            var3 = MessageDigest.getInstance(\"SHA-1\");\u003Cbr>        } catch (NoSuchAlgorithmException var7) {\u003Cbr>            throw new RuntimeException(var7);\u003Cbr>        }\u003Cbr>\u003Cbr>        try {\u003Cbr>            var3.update(var1.getBytes(\"UTF-8\"));\u003Cbr>        } catch (UnsupportedEncodingException var6) {\u003Cbr>            throw new RuntimeException(var6);\u003Cbr>        }\u003Cbr>\u003Cbr>        byte[] var4 = var3.digest();\u003Cbr>        String var5 = (new BASE64Encoder()).encode(var4);\u003Cbr>        return var5;\u003Cbr>    }\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>From the above code, the encryption algorithm for user passwords can be derived\u003C\u002Fp>\u003Ch4>(2) Locate the specific code implementation for user creation\u003C\u002Fh4>\u003Cp>Follow up on UserFacade.make().createUser(SessionUtil.buildActivitySource(), user, volumes, attributes);, the specific location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.facade-&gt;UserFacade.class, the core code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   public User createUser(ActivitySource var1, User var2, List\u003Cvolume> var3, Map\u003Cstring, string=\"\"> var4) throws UserException {\u003Cbr>\u002F\u002FHide code\u003Cbr>            this.validateUser(var2);\u003Cbr>\u003Cbr>            try {\u003Cbr>                if (var4 != null &amp;&amp; !var4.isEmpty()) {\u003Cbr>                    HashSet var5 = new HashSet();\u003Cbr>                    Iterator var6 = Arrays.asList(UserFacade.PowerUserAttributes.values()).iterator();\u003Cbr>\u003Cbr>                    while(var6.hasNext()) {\u003Cbr>                        PowerUserAttributes var7 = (PowerUserAttributes)var6.next();\u003Cbr>                        String var8 = var4.containsKey(var7.getDataKey()) ? (String)var4.get(var7.getDataKey()) : var7.getDefaultValue();\u003Cbr>                        var5.add(new UserData(var2, var7.getDataKey(), var8));\u003Cbr>                        var4.remove(var7.getDataKey());\u003Cbr>                    }\u003Cbr>\u003Cbr>                    var6 = var4.entrySet().iterator();\u003Cbr>\u003Cbr>                    while(var6.hasNext()) {\u003Cbr>                        Map.Entry var13 = (Map.Entry)var6.next();\u003Cbr>                        var5.add(new UserData(var2, (String)var13.getKey(), (Serializable)var13.getValue()));\u003Cbr>                    }\u003Cbr>\u003Cbr>                    var2 = com.r1soft.backup.server.om.facade.UserFacade.getInstance().persistPOJOWithData(var2, var5);\u003Cbr>                } else {\u003Cbr>                    var2 = (User)EntityManagerFacade.persistPOJO(var2);\u003Cbr>                }\u003Cbr>\u002F\u002FHide code\u003Cbr>    }\u003C\u002Fstring,>\u003C\u002Fvolume>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Follow up on (User)EntityManagerFacade.persistPOJO(var2), located at \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.om.entity-&gt;EntityManagerFacade.class. The core code is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>private static EntityManagerFactory emf = null;\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" baseentity\u003C?=\"\">&gt;, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; facadeMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" ipojo\u003C?=\"\" baseentity\u003C?=\"\">, ?, ?&gt;&gt;, Class\u003C!--? extends BaseEntity\u003C?-->&gt;&gt; pojoToEntityMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" ipojo\u003C?=\"\" baseentity\u003C?=\"\">, ?, ?&gt;&gt;, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; pojoToFacadeMap = new HashMap();\u003Cbr>private static Map\u003Cclass\u003C? extends=\"\" object=\"\">, Class\u003C!--? extends BaseOMFacade\u003C? extends BaseEntity\u003C?-->, ?, ? extends IPOJO\u003C!--? extends BaseEntity\u003C?-->, ?, ?&gt;, ?&gt;&gt;&gt; pojoIDToFacadeMap = new HashMap();\u003Cbr>protected static final QueryOrderByType DEFAULT_SORT_DIRECTION;\u003Cbr>protected static final String PERSISTENCEUNITNAME = \"CDP-PU\";\u003Cbr>protected static final String HIBERNATECONFFILE = \"com\u002Fr1soft\u002Fbackup\u002Fserver\u002Fom\u002Fhibernate.cfg.xml\";\u003Cbr>protected static final String DBUSER = \"r1derbyuser\";\u003Cbr>protected static final String DBPASS = \"V?Rdp*eT6N9t8aW3KDoh\";\u003Cbr>protected static final String H2PATH = \"h2\u002Fr1backup\";\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fclass\u003C?>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>From the above code, it can be seen that the JDBC H2 database is used here to store data. The configuration file is \"com\u002Fr1soft\u002Fbackup\u002Fserver\u002Fom\u002Fhibernate.cfg.xml\", and the actual corresponding file location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Flib\u002Fcdpserver.jar-&gt;com.r1soft.backup.server.om.hibernate.cfg.xml. Its core content is as follows:\u003C\u002Fp>\u003Ctable>\u003Ctbody>\u003Ctr>\u003Ctd>\u003Cp>   \u003Cproperty name=\"hibernate.connection.url\">jdbc:h2:.\u002Fdata\u002Fh2\u002Fr1backup\u003C\u002Fproperty>\u003Cbr>   \u003Cbr>   \u003Cproperty name=\"hibernate.connection.driver_class\">org.h2.Driver\u003C\u002Fproperty>\u003C\u002Fp>\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Cp>Based on the above content, we can obtain the complete database connection parameters, and the actual database file location is \u002Fusr\u002Fsbin\u002Fr1soft\u002Fdata\u002Fh2\u002Fr1backup.h2.db.\u003C\u002Fp>\u003Cp>Data validation test is performed here: manually create a user admin2 with the password set to 123456. Through dynamic debugging, the encrypted password content is derived as fEqNCco3Yq9h5ZUglD3CZJT4lBs=. Then, open the file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fdata\u002Fh2\u002Fr1backup.h2.db in binary mode. The username and encrypted password content can be obtained from the file content, as shown in the figure below.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770018762692_1_9d8fe475d7-1.png\">\u003C\u002Fp>\u003Ch2>0x05 CVE-2022-36537 Brief Introduction\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>Vulnerability analysis article: https:\u002F\u002Fmedium.com\u002Fnumen-cyber-labs\u002Fcve-2022-36537-vulnerability-technical-analysis-with-exp-667401766746\u003C\u002Fp>\u003Cp>The article mentions that triggering RCE requires uploading a com.mysql.jdbc.Driver file containing a Payload.\u003C\u002Fp>\u003Cp>This operation can only be exploited once, for the following reasons:\u003C\u002Fp>\u003Cp>By default, there is an uploadable icon on the Database Driver page of the management backend, as shown in the figure below.\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770018783143_2_d2f6ef3eb1-1.png\">\u003C\u002Fp>\u003Cp>After uploading, the uploadable icon will no longer be displayed, as shown in the figure below\u003C\u002Fp>\u003Cp>\u003Cimg alt=\"Alt text\" src=\"\u002Fapi\u002Fmedia\u002Ffile\u002Fdocx_image_1770018792987_3_724e248aee-1.png\">\u003C\u002Fp>\u003Cp>Triggering RCE is achieved by uploading the MySQL DataBase Driver through the program, so this function becomes unavailable after one attack and cannot be reused\u003C\u002Fp>\u003Cp>Attack detection: After triggering RCE, a file \u002Fusr\u002Fsbin\u002Fr1soft\u002Fconf\u002Fdatabase-drivers\u002Fmysql-connector.jar will be uploaded to the system, where com\\mysql\\jdbc\\Driver.class is the payload used by the attacker\u003C\u002Fp>\u003Ch2>0x06 Summary\u003C\u002Fh2>\u003Cp>---\u003C\u002Fp>\u003Cp>This article introduces solutions to some issues encountered during the setup of the Server Backup Manager debugging environment, analyzes methods for extracting user database files, and provides recommendations for detecting CVE-2022-36537.\u003C\u002Fp>\u003C\u002Fbody>\u003C\u002Fhtml>",1466,"Onedaysec",6,"published","2026-02-02T08:06:59.473Z",{"title":37,"description":14,"keywords":38,"ogImage":39,"canonicalUrl":39,"noIndex":40},"Server Backup Manager Vulnerability Debugging & Environment Setup Guide","Server Backup Manager, SBM, vulnerability debugging, environment setup, CVE-2022-36537, Linux backup software, debugging setup, user database extraction",null,false,[],{"docs":43,"hasNextPage":40},[44,45,4,46],270,269,267,{"title":39,"description":39,"image":39},"2026-07-24T15:37:14.471Z","2026-07-23T16:01:17.994Z","draft","2026-07-23T16:04:55.469Z"]