One-Bit Man

WebページのURLが与えられた。
このページには、「Download Dockerfile」というリンクと、Filename、Position、Flipping-bitを入力するフォームがあった。
「Download Dockerfile」からは、以下のファイルを含むアーカイブファイルが得られた。

An URL of a web page was given.
The page had a link saying "Download Dockerfile" and a form that accepts Filename, Position, and Flipping-bit.
An archive file that contains these files was available from the "Download Dockerfile" link:

one-bit-man |-- Dockerfile `-- files |-- entrypoint.sh |-- flag |-- hack.php |-- htaccess |-- init.sql `-- readflag

これらのファイルから、以下のことが読み取れた。

I found these things from these files:

Filenameに /var/www/html/.htaccess、Positionに 67、Flipping-bitに 0 を入力して送信してみると、「bad filename」と出た。
この「bad filename」という文字列は、得られたアーカイブ中のファイルには入っていないようだった。

プレースホルダーの通り、Filenameに /var/www/html/index.php、Positionに 0、Flipping-bitに 0 を入力して送信してみると、
新しいWebページへのリンクと、そこを閲覧するためのユーザ名とパスワードが表示された。
このWebページにアクセスすると、PHPのソースコードが表示され、Wordpressが入っているらしいことがわかった。
index.phpの Position 0 を書き換えたため、<?php=?php になり、ソースコードが表示されたようである。

Positionを 20 にすることで書き換えるのをコメントにし、Wordpressを普通に動かしてみた。
左下の検索欄から適当に打った k を検索すると、Sample Page が見つかった。
そこにあった「your dashboard」というリンクをクリックすると、ログイン画面 (wp-login.php) が出てきた。

そこで、adminとしてログインできるようにする方法を探すため、以下のページから wordpress-5.8.2-ja.zip をダウンロードした。

I tried entering /var/www/html/.htaccess to Filename, 67 to Position, and 0 to Flipping-bit and sending, resulted in seeing "bad filename".
This string "bad filename" was not in the files in the archive.

According to the placeholder, I tried entering /var/www/html/index.php to Filename, 0 to Position, and 0 to Flipping-bit and sending.
As a result, a link to a new web page and a pair of username and password for the page appeared.
Visiting the web page, a PHP source code appeared and I found that Wordpress is installed there.
It looks like the source code is shown because the Position 0 of index.php is modified and <?php became =?php.

I changed the Position to enter to 20 to set what to modify to the comment to have the Wordpress operate normally.
I searched k, which I randomly typed, from the search box in the left bottom, finding "Sample Page".
I clicked a link "your dashboard" there and found a form for logging in (wp-login.php).

I downloaded wordpress-5.8.2-ja.zip from this page to search for a way to enable me to login as admin:

ダウンロード | WordPress.org 日本語

wp-login.php'login' の処理 (1104行目~) を見ると、get_user_by という関数を用いていることがわかった。
grep を用いてこの関数の定義を探すと、wp-includes/pluggable.php の102行目に見つかり、WP_User::get_data_by を用いていることがわかった。
get_data_bygrepで探すと、wp-includes/class-wp-user.php の191行目に見つかったが、今回の目的にはあまり役に立たなそうだった。

wp-login.php に戻って読み進めると、1142行目で wp_signon という関数を用いていることがわかった。
grep を用いてこの関数の定義を探すと、wp-includes/user.php の33行目に見つかった。
さらに、その下 (124行目) に wp_authenticate_username_password という関数が定義されており、その中に以下の部分 (174行目) があった。

I read the part to process 'login' in wp-login.php (from the 1104th line), and found that it uses a function get_user_by.
I searched for a definition of this function using grep, and found it at the 102nd line of wp-includes/pluggable.php. The function is using WP_User::get_data_by.
I searched for get_data_by via grep and found it at the 191st line of wp-includes/class-wp-user.php. It didn't look useful for current purpose.

I returned to wp-login.php and looked further. As a result, I found that it uses a function wp_signon on the 1142nd line.
I searched for a definition of this function using grep and found that at the 33rd line of wp-includes/user.php.
I also found a function wp_authenticate_username_password below the function (the 124th line), and found this part (the 174th line) in the function:

if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {

この ! をビット反転により空白に書き換えれば、判定が逆転し、間違ったパスワードを入力することでログインできるようになりそうである。
バイナリエディタでこの ! の位置を調べると、5389 (0x150d) であることがわかった。

フォームのFilenameに /var/www/html/wp-includes/user.php、Positionに 5389、Flipping-bitに 0 を入力し、Wordpressにアクセスした。
Sample Page にある「your dashboard」のリンク先は http://198.51.100.51:12345//wp-admin/ のように wp-admin の前にスラッシュが2個入っており、このまま操作してもうまくいかなかった。
スラッシュを1個消した http://198.51.100.51:12345/wp-admin/ にアクセスし、現れたログイン画面の「Username or Email Address」に admin、「Password」に a を入力して「Log In」ボタンを押すと、Dashboardが現れた。

このDashboardにおいて、Appearance → Theme Editor を開いた。
そして、「Theme Header (header.php)」を開き、<?php wp_body_open(); ?><?php wp_body_open(); passthru("/readflag"); ?> に書き換え、「Update File」を押した。
その後Wordpressのトップページにアクセスすると、flagが表示された。

Changing ! here to a space via a bit flipping should reverse the condition and enable to login by entering a wrong password.
I checked the place of this ! using a binary editor. It was 5389 (0x150d).

I entered /var/www/html/wp-includes/user.php as Filename, 5389 as Position, and 0 as Flipping-bit to the form, and opened Wordpress.
The destination of the "your dashboard" link on the "Sample Page" had two slashed before wp-admin like http://198.51.100.51:12345//wp-admin/, and using this as-is didn't work well.
I accessed a URL with one slash removed like http://198.51.100.51:12345/wp-admin/. Then, I entered admin as "Username or Email Address" and a as "Password" to the login form appeared.
Hitting the "Log In" button, the Dashboard appeared.

On the Dashboard, I opened "Theme Editor" in "Appearance".
Then, I opened "Theme Header (header.php)", changed <?php wp_body_open(); ?> to <?php wp_body_open(); passthru("/readflag"); ?>, and hit the "Update File" button.
After that, I opened the top page of Wordpress. As a result, the flag appeared.

hitcon{if your solution is l33t, please share it!}

HITCON CTF 2021