{"id":121,"date":"2026-08-11T18:29:27","date_gmt":"2026-08-11T18:29:27","guid":{"rendered":"https:\/\/skytesting.nl\/?p=121"},"modified":"2026-08-11T18:29:27","modified_gmt":"2026-08-11T18:29:27","slug":"intigriti-challenge-july-2026","status":"publish","type":"post","link":"https:\/\/skytesting.nl\/?p=121","title":{"rendered":"Intigriti Challenge July 2026"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Improper Authorization checks in &#8216;Create Manifest&#8217;<\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An authorization flaw exists in the &#8216;Manifest Studio&#8217; functionality in the Registry Observatory app `<a target=\"_blank\" rel=\"noreferrer noopener\" href=\"https:\/\/challenge-0726.intigriti.io\/challenge.html\">https:\/\/challenge-0726.intigriti.io\/challenge.html<\/a>&#8216;.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A user with malicious intent can create a manifest for + view details about packages not part of their own namespace. Potentially sensitive information like the release notes (with a flag in it \ud83d\ude42 can be revealed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When creating a new manifest, one can specify the &#8216;scope&#8217; which refers to the namespace the package is part of. This value is passed to the server in a parameter called &#8216;manifest_b64&#8217;.<br>The information inside the &#8216;manifest_b64&#8217; contains the package details including scope definition, and this is by default the namespace value of the current namespace, like for example &#8216;skyw1per-6a470cf1&#8217; for my account.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By injecting this JSON formatted data with two packages with both different details, something interesting occurs. The application appears to perform its security boundary checks based on the first package entry, but the second package entry is used in publication.<br>By specifying a different (existing) package and scope for the second package, a publication can be created for an existing package outside of your own namespace.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Steps To Reproduce<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Login <\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Login to the app or create a new account:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"903\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image.png\" alt=\"\" class=\"wp-image-122\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image.png 933w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-300x290.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-768x743.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Update the manifest<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Update the manifest for the Hello World package:<br>Browse to Manifest Studio<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"903\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-1.png\" alt=\"\" class=\"wp-image-123\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-1.png 933w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-1-300x290.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-1-768x743.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Create a manifest for the package &#8216;hello-world&#8217; by first clicking on <code>Request Approval<\/code> and second on <code>Run preflight<\/code>. Capture these requests in BurpSuite of Caido.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"887\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-2-1024x887.png\" alt=\"\" class=\"wp-image-124\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-2-1024x887.png 1024w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-2-300x260.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-2-768x665.png 768w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-2.png 1043w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">This is an example of the intended usage of this feature.<br>With a successful attempt, the result is visible under <code>Publication History<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Create manifest outside of the namespace<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Demonstrating the Security boundary: Attempt to create manifest for a package outside of own namespace. Look in Burpsuite \/ Caido History for the request to endpoint <code>\/api\/manifests\/sign<\/code> which is the POST request made when the <code>request approval<\/code> button from step 2 is clicked.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"742\" height=\"525\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-3.png\" alt=\"\" class=\"wp-image-125\" style=\"border-width:1px\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-3.png 742w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-3-300x212.png 300w\" sizes=\"auto, (max-width: 742px) 100vw, 742px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Base64 decoded <code>manifest_b64<\/code> value:<\/p>\n\n\n\n<pre class=\"wp-block-code has-000000-color has-text-color has-75-rem-font-size\"><code>{\n  \"package\": {\n    \"scope\": \"skyw1per-6a470cf1\",\n    \"name\": \"hello-world\",\n    \"version\": \"1.0.0\"\n  },\n  \"metadata\": {\n    \"description\": \"Compatibility check\",\n    \"visibility\": \"private\"\n  },\n  \"operation\": \"preflight\"\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Lets change name to <code>security-notes<\/code> and scope to <code>core<\/code>.<br>Based on this comment and details, we know this other namespace and package should exist within the application.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"777\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-4-1024x777.png\" alt=\"\" class=\"wp-image-126\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-4-1024x777.png 1024w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-4-300x228.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-4-768x583.png 768w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-4.png 1032w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"777\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-5-1024x777.png\" alt=\"\" class=\"wp-image-127\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-5-1024x777.png 1024w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-5-300x228.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-5-768x583.png 768w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-5.png 1032w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">After applying the changes, base64 encode the entire JSON object and replace the <code>manifest_b64<\/code> value in your request.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"752\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-6-1024x752.png\" alt=\"\" class=\"wp-image-128\" style=\"border-width:1px\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-6-1024x752.png 1024w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-6-300x220.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-6-768x564.png 768w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-6.png 1026w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Expected result: A 401 response with the following error message:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"786\" height=\"565\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-7.png\" alt=\"\" class=\"wp-image-129\" style=\"border-width:1px\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-7.png 786w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-7-300x216.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-7-768x552.png 768w\" sizes=\"auto, (max-width: 786px) 100vw, 786px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Exploitation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Exploitation: Adding two json packages to the payload<br>Send the request to <code>\/api\/manifests\/sign<\/code> to repeater again. This time, lets use the following payload:<\/p>\n\n\n\n<pre class=\"wp-block-code has-000000-color has-text-color has-75-rem-font-size\"><code>{\n  \"package\": {\n    \"scope\": \"skyw1per-6a470cf1\",\n    \"name\": \"hello-world\",\n    \"version\": \"1.0.0\"\n  }, \"package\": {\n    \"scope\": \"core\",\n    \"name\": \"security-notes\",\n    \"version\": \"1.0.0\"\n  },\n  \"metadata\": {\n    \"description\": \"Compatibility check 123 test\",\n    \"visibility\": \"private\"\n  },\n  \"operation\": \"preflight\"\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Note this payload contains two sets of <code>package<\/code> details. The first one will be used for validation, and should check all requirements. the second one is the one used in the actual publication.<br>After applying the changes, base64 encode the entire JSON object and replace the <code>manifest_b64<\/code> value in your request.<br>Expected result: a 200 response with <code>approval_id<\/code>,<code>manifest_sha256<\/code>,<code>nonce<\/code>,<code>expires_at<\/code> and <code>signature<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"752\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-8-1024x752.png\" alt=\"\" class=\"wp-image-130\" style=\"border-width:1px\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-8-1024x752.png 1024w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-8-300x220.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-8-768x564.png 768w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-8.png 1026w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Next, locate the POST request to <code>\/api\/publications<\/code> and edit it in Repeater. For the <code>manifest_b64<\/code> body, use the same value as in the previous request. The other required parameters can be copied from the HTTP response of <code>\/api\/manifests\/sign<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full has-custom-border\"><img loading=\"lazy\" decoding=\"async\" width=\"1022\" height=\"775\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-9.png\" alt=\"\" class=\"wp-image-131\" style=\"border-width:1px\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-9.png 1022w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-9-300x227.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-9-768x582.png 768w\" sizes=\"auto, (max-width: 1022px) 100vw, 1022px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Expected result: HTTP 201 response.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Result<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Browse in the application to <code>Publication History<\/code>.<br>The last created item should be the core\/security-notes package, indicating the exploit has been successful.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1022\" height=\"775\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-10.png\" alt=\"\" class=\"wp-image-132\" srcset=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-10.png 1022w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-10-300x227.png 300w, https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-10-768x582.png 768w\" sizes=\"auto, (max-width: 1022px) 100vw, 1022px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The release notes from this package are readable:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" src=\"https:\/\/skytesting.nl\/wp-content\/uploads\/2026\/08\/image-11.png\" alt=\"\" class=\"wp-image-133\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">FLAG:<\/p>\n\n\n\n<pre class=\"wp-block-code has-000000-color has-text-color has-75-rem-font-size\"><code>INTIGRITI{019f8700-4613-74fb-923e-781903e4bee9}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Impact<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A user with malicious intent can publish a manifest for a package outside of their own namespace.<br>Due to this, a new version under &#8220;publication history&#8221; is created.<br>The user can view details of this package like the original release notes.<br>All they need to know is the namespace and the name of the package, no user interaction is required.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended solution<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The application should parse the manifest once and use the same package and namespace values for both authorization and publication.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ambiguous manifests containing multiple conflicting package entries should be rejected. Before publishing, the server should verify that the authenticated user is authorized to publish to the resolved namespace and package.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Improper Authorization checks in &#8216;Create Manifest&#8217; Summary An authorization flaw exists in the &#8216;Manifest Studio&#8217; functionality in the Registry Observatory app `https:\/\/challenge-0726.intigriti.io\/challenge.html&#8216;. A user with malicious intent can create a manifest for + view details about packages not part of their own namespace. Potentially sensitive information like the release notes (with a flag in it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-121","post","type-post","status-publish","format-standard","hentry","category-ctf-writeups"],"blocksy_meta":{"styles_descriptor":{"styles":{"desktop":"","tablet":"","mobile":""},"google_fonts":[],"version":8}},"_links":{"self":[{"href":"https:\/\/skytesting.nl\/index.php?rest_route=\/wp\/v2\/posts\/121","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/skytesting.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/skytesting.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/skytesting.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/skytesting.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=121"}],"version-history":[{"count":0,"href":"https:\/\/skytesting.nl\/index.php?rest_route=\/wp\/v2\/posts\/121\/revisions"}],"wp:attachment":[{"href":"https:\/\/skytesting.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/skytesting.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/skytesting.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}