ビギナー向けCTF  Houseplant CTF のwrite up

# ビギナー向けCTF  Houseplant CTF のwrite up

Houseplant CTFと言うCTFに参加してきました。

https://houseplant.riceteacatpanda.wtf/home

取れた点数は4300点で
問題は何問中何問解いて190位でした。日本勢では6位と言えば強そうではある。
ビギナーの域は出ない。

<img width="912" alt="スクリーンショット 2020-04-27 20.19.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323266/b073ef9d-b157-c172-56e7-497630534904.png">

# beginners

## beginner1
When Bob and Jia were thrown into the world of cybersecurity, they didn't know anything- and thus were very overwhelmed. They're trying to make sure it doesn't happen to you.
Let's cover some bases first.

cnRjcHt5b3VyZV92ZXJ5X3dlbGNvbWV9

ボブとジアがサイバーセキュリティの世界に投げ込まれたとき、彼らは何も知らなかったため、非常に圧倒されました。彼らはそれがあなたに起こらないことを確認しようとしています
最初にいくつか基本を覚えましょう。

cnRjcHt5b3VyZV92ZXJ5X3dlbGNvbWV9

##### 回答
とりあえずよくわからない文字列が与えられたらbase64,base32,シーザー暗号あたりを試します

cyberchefでググったら便利なサイトが見つかります。
今回の問題はbase64でデコードすればフラグが見えました。
rtcp{youre_very_welcome}

## beginner2

Bob wanted to let you guys know that "You might not be a complete failure."
Thanks, Bob

72 74 63 70 7b 62 6f 62 5f 79 6f 75 5f 73 75 63 6b 5f 61 74 5f 62 65 69 6e 67 5f 65 6e 63 6f 75 72 61 67 69 6e 67 7d

和訳
ボブはあなたたちに「あなたは完全な失敗ではないかもしれない」と知らせたかったのです。
ありがとう、ボブ

72 74 63 70 7b 62 6f 62 5f 79 6f 75 5f 73 75 63 6b 5f 61 74 5f 62 65 69 6e 67 5f 65 6e 63 6f 75 72 61 67 69 6e 67 7d

##### 回答
とりあえずよくわからない数値が与えられたらAsciiコードの文字に直せないか確認します。
予想通りでした
rtcp{bob_you_suck_at_being_encouraging}

## beginner3

Fun fact: Jia didn't actually know what this was when they first started out. If you got this, you're already doing better than them ;-;

162 164 143 160 173 163 165 145 137 155 145 137 151 137 144 151 144 156 164 137 153 156 157 167 137 167 150 141 164 137 157 143 164 141 154 137 167 141 163 137 157 153 141 171 77 41 175

和訳
おもしろい事実：Jiaは、最初にこれが何であるかを実際には知りませんでした。これを手に入れたら、あなたはすでに彼らよりもうまくやっています;-;

162 164 143 160 173 163 165 145 137 155 145 137 151 137 144 151 144 156 164 137 153 156 157 167 137 167 150 141 164 137 157 143 164 141 154 137 167 141 163 137 157 153 141 171 77 41 175

##### 回答
この数字はそのままasciiコードにはできなさそうです。が最初の二文字を先ほどの問題と比べると差が同じであることがわかるのでなんとかすればasciiに直せることがわかります。また、この数字たちをよくみると8以上の数字がありません。
と言うわけで8進数としてasciiに変換します

rtcp{sue_me_i_didnt_know_what_octal_was_okay?!}

## beginner4
Caesar was stabbed 23 times by 60 perpetrators... sounds like a modern group project

egpc{lnyy_orggre_cnegvpvcngr}

和訳
シーザーは60人の加害者によって23回刺されました...現代のグループプロジェクトのように聞こえます

egpc{lnyy_orggre_cnegvpvcngr}

##### 回答
問題でシーザーと言っていることからもわかるようにシーザー暗号です。
13文字ずらせばいけます(俗に言うROT13)。
シーザー暗号は記号がそのままなのでわかりやすいです。

rtcp{yall_better_participate}


## beginner5

beep boop

-- .- -. -.-- ..--.- -... . . .--. ... ..--.- .- -. -.. ..--.- -... --- --- .--. ...

Remember to wrap the flag in the flag format rtcp{something}

和訳
ピッぽっぱっ
-- .- -. -.-- ..--.- -... . . .--. ... ..--.- .- -. -.. ..--.- -... --- --- .--. ...
フラグのフォーマットを忘れないでください,rtcp{何か}

##### 回答
これはツートントンなやつです。モールス信号
デコードするとMANY_BEEPS_AND_BOOPSになるので
rtcp{MANY_BEEPS_AND_BOOPS}
となります。

## beginner6
i'm so tired...


26 26 26 26 26 26 26 26 19 12 5 5 16 9 14 7 9 14 16 8 25 19 9 3 19


*disclaimer: DON'T DO THIS KIDS. only sleep in math.

Remember to wrap the whole thing in the flag format rtcp{}

和訳
疲れた。。

26 26 26 26 26 26 26 26 19 12 5 5 16 9 14 7 9 14 16 8 25 19 9 3 19

*免責事項：この子供はしないでください。数学だけで眠る。

フォーマット忘れないでね

##### 回答
今回の数字は26までしかありません。なのでアルファベットの何番目かを数値で表したものと思われます。
そうしてデコードすると
zzzzzzzzsleepinginphysics
となるのでフラグは
rtcp{zzzzzzzzsleepinginphysics}
です。

## beginner7
Don't go around bashing people.

igxk{fmovhh_gsvb_ziv_nvzm}

和訳
人をからかうことを避けてください。

igxk{fmovhh_gsvb_ziv_nvzm}

##### 回答
記号がそのまま残っているのでシーザー暗号かと思いましたが違うようです。
問題文でググっているとatbashと言う暗号があることを知りました。文字の順番を反転させるみたいです。
と言うことでatbashにかけると

rtcp{unless_they_are_mean}

## Beginner 8 

You either mildly enjoy bacon, think it's a food of the gods, or are vegan/vegetarian.

00110 01110 00100 00000 10011 00101 01110 01110 00011 00011 01110 01101 10011 10010 10011 00000 10001 10101 00100

Remember to wrap the flag in rtcp{}
Hint Make sure you use the "complete" alphabet.
和訳

あなたはベーコンを穏やかに楽しむか、それが神々の食べ物だと思うか、またはビーガン/ベジタリアンです。

00110 01110 00100 00000 10011 00101 01110 01110 00011 00011 01110 01101 10011 10010 10011 00000 10001 10101 00100

フォーマット気をつけて

ヒント「完全な」アルファベットを使用してください。
##### 回答
見たところ2進数5文字で2の5乗である32より小さい数字が並んでます。
やはりアルファベットに直すと

GOEATFOODDONTSTARVE
となります。
なので
rtcp{GOEATFOODDONTSTARVE}

## beginner9 は解けませんでした
base64デコードして出てきたモールス信号をデコードして数値にして文字にして、、と言う流れで
zeziyvzyziと言う文字列が出てきたけどその後どうするかわからなかった
そもそもここまでで何か見落としていた..?


# Crypt(以降問題和訳は載せません)
## CH3COOH 解けませんでした
換字式暗号と思ったけどもしかして違うのか自分の勘がなさすぎるのか。

## Sizzle
Due to the COVID-19 outbreak, we ran all out of bacon, so we had to use up the old stuff instead. Sorry for any inconvenience caused...

Dev: William

 Hint! Wrap your flag with rtcp{}, use all lowercase, and separate words with underscores.
 Hint! Is this really what you think it is?

問題文と一緒にファイルが渡される、中身は
....- ..... ...-. .--.- .--.. ....- -..-- -..-. ..--. -.... .-... .-.-. .-.-. ..-.. ...-- ..... .--.. ...-- .-.-- .--.- -.... -...- .-... ..-.- .-... ..-.. ...--
となっている。
ぱっと見モールス信号なのでモールス信号としてデコードしてみるもわからない。
問題文ではbaconがなんだと言っているのでbacon暗号ではと考えて-を1,.を0として文字に変換すると
BACONBUTGRILLEDANDMORSIFIEDが出て来る。
rtcp{BACONBUTGRILLEDANDMORSIFIED}


## "fences are cool unless they're taller than you" - tida
They say life's a roller coaster, but to me, it's just jumping over fences.

tat_uiwirc{s_iaaotrc_ahn}pkdb_esg

##### 回答
cyberchefを使っていろいろしていると
rail fence cipher decodeと言うのがあったため
それを適用(key=3)
tcp{ask_tida_about_rice_washing}rと言う文字列が出て来る
rtcp{ask_tida_about_rice_washing}

## Returning Stolen Archives

So I was trying to return the stolen archives securely, but it seems that I had to return them one at a time, and now it seems the thieves stole them back! Can you help recover them once and for all? It seems they had to steal them one at a time...

問題とともにintercepted.txtと returningstolenarchives.pyがダウンロードできる
#####回答
intercepted.txtには
n = 54749648884874001108038301329774150258791219273879249601123423751292261798269586163458351220727718910448330440812899799 
e = 65537
ct = [52052531108833646741308670070505961165002560985048445381912028939564989677616205955826911335832917245744890104862186090,24922951057478302364724559167904980705887738247412638765127966502743153757232333552037075100099370197070290632101808468,313331277271377968970423092381735365071910022477243917765250046468356(略)]
と言う内容が入っている、nとeがあるあたりRSA暗号っぽい
returningstolenarchives.pyは
p,q,e,flagと言う変数を用いて暗号化してくれるようだ
がn=p*qとしているのでnだけ与えればpとqは必要なさそう
また適当な文字をデコードすると一文字ずつデコードしてリストに追加しているようなので総当たりで行けそうだと考えてコードを書いた
総当たりする文字列の定義がとても適当である

```

e = 65537

def encrypt(n, e, plaintext):
  #print("encrypting with " + str(n) + str(e))
  encrypted = []
  for char in plaintext:
    cipher = (ord(char) ** int(e)) % int(n)
    encrypted.append(cipher)
  return(encrypted)

n = 54749648884874001108038301329774150258791219273879249601123423751292261798269586163458351220727718910448330440812899799

ans=[52052531108833646741308670070505961165002560985048445381912028939564989677616205955826911335832917245744890104862186090,24922951057478302364724559167904980705887738247412638765127966502743153757232333552037075100099370197070290632101808468,31333127727137796897042309238173536507191002247724391776525004646835609286736822503824661004274731843794662964916495223,37689731986801363765434552977964842847326744893755747412237221863834417045591676371189948428149435230583786704331100191,10128169466676555996026197991703355150176544836970137898778443834308512822737963589912865084777642915684970180060271437,31333127727137796897042309238173536507191002247724391776525004646835609286736822503824661004274731843794662964916495223,32812400903438770915197382692214538476619741855721568752778494391450400789199013823710431516615200277044713539798778715,48025916179002039543667066543229077043664743885236966440148037177519549014220494347050632249422811334833955153322952673,52052531108833646741308670070505961165002560985048445381912028939564989677616205955826911335832917245744890104862186090,32361547617137901317806379693272240413733790836009458796321421127203474492226452174262060699920809988522470389903614273,4363489969092225528080759459787310678757906094535883427177575648271159671231893743333971538008898236171319923600913595,47547012183185969621160796219188218632479553350320144243910899620916340486530260137942078177950196822162601265598970316,32361547617137901317806379693272240413733790836009458796321421127203474492226452174262060699920809988522470389903614273,33230176060697422282963041481787429356625466151312645509735017885677065049255922834285581184333929676004385794200287512,32315367490632724156951918599011490591675821430702993102310587414983799536144448443422803347161835581835150218650491476,6693321814134847191589970230119476337298868688019145564978701711983917711748098646193404262988591606678067236821423683,32710099976003111674253316918478650203401654878438242131530874012644296546811017566357720665458366371664393857312271236,49634925172985572829440801211650861229901370508351528081966542823154634901317953867012392769315424444802884795745057309,50837960186490992399835102776517955354761635070927126755411572132063618791417763562399134862015458682285563340315570436]

strs='abcdefghijklmnopqrstuvwxyz{}_!?0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!#$%&()0=~|{}`*+<>?,./_]:;@@[[\^-'

ct = encrypt(n, e, flag)
print(ct,len(ct))

for i in range(len(ans)):
  for c in strs:
    x=encrypt(n,e,c)[0]
    if x==ans[i]:
      break
  print(c,end='')
```
結果フラグが得られる
rtcp{cH4r_bY_Ch@R!}

## Rivest Shamir Adleman
A while back I wrote a Python implementation of RSA, but Python's really slow at maths. Especially generating primes.

Dev: Tom
 Hint! There are two possible ways to get the flag ;-)

ZIPファイルが渡される

##### 回答
ZIPファイルには
generate_keys.py	requirements.txt
component.txt		secrets.txt.enc
decrypt.py		yafu
encrypt.py		public-key.json
が入っている
RSAによって暗号化されているsecrets.txt.encを復号すればいいようだ
decrypt.pyを読むと秘密鍵のあるjsonファイルを指定してあげれば復号できそうだ
public-key.jsonにはeが5でnが600桁もある
これは間違いなく自力で素因数分解できないと思ったが大きすぎるのも問題で素因数がとても大きい場合は
factorDBってサイトのデータベースに巨大素数と素因数が保存されているらしい
と言うことでfactorDBのサイトを使ってみると2つの素因数pとqがもとまった。
あとはRSA暗号の秘密鍵dをpとqを使って作る
$$ d = e^{-1}(mod (p-1)(q-1)) $$
modinvでぐぐると出て来る。
そうしてできたdとnをprivatekey.jsonと言う名前で保存し
decrypt.pyを実行すると

```
 .--.
/.-. '----------.
\'-' .--"--""-"-'
 '--'
rtcp{f1xed_pr*me-0r_low_e?}
```

と言う結果が得られる

## Rainbow Vomit
o.O What did YOU eat for lunch?!

The flag is case insensitive.

Dev: Tom
 Hint! Replace spaces in the flag with { or } depending on their respective places within the flag.
 Hint! Hues of hex
 Hint! This type of encoding was invented by Josh Cramer.

と一緒にoutput.pngがダウンロードできる

##### 回答
output.pngはなんともカラフルな画像である

![output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323266/7c9d92ae-2aed-a431-6970-966d0a18c469.png)

これがなんなのかヒントを見ながら調べてみると
https://www.geocachingtoolbox.com/index.php?lang=en&page=hexahue
こんなページを見つけた
６マスの色で文字を表現しているようだ
このページの形式に従って頑張ってこれを読むプログラムを書いたら良い
定義をたくさん書くの大変でした。

```
import cv2
import numpy as np
img=cv2.imread('output.png')

def getColors(x,y):
  ret=[]
  ret.append(img[y*3+2,x*2+2])
  ret.append(img[y*3+2,x*2+2+1])
  ret.append(img[y*3+2+1,x*2+2])
  ret.append(img[y*3+2+1,x*2+2+1])
  ret.append(img[y*3+2+2,x*2+2])
  ret.append(img[y*3+2+2,x*2+2+1])
  return ret

h,w,_=img.shape
maxX=(w-2)//2
maxY=(h-2)//3

blue=[255,0,0]
green=[0,255,0]
red=[0,0,255]
yellow=[0,255,255]
lblue=[255,255,0]
lred=[255,0,255]
white=[255,255,255]
black=[0,0,0]
gray=[128,128,128]

ca=[lred,red,green,yellow,blue,lblue]
cb=[red,lred,green,yellow,blue,lblue]
cc=[red,green,lred,yellow,blue,lblue]
cd=[red,green,yellow,lred,blue,lblue]
ce=[red,green,yellow,blue,lred,lblue]
cf=[red,green,yellow,blue,lblue,lred]
cg=[green,red,yellow,blue,lblue,lred]
ch=[green,yellow,red,blue,lblue,lred]
ci=[green,yellow,blue,red,lblue,lred]
cj=[green,yellow,blue,lblue,red,lred]
ck=[green,yellow,blue,lblue,lred,red]
cl=[yellow,green,blue,lblue,lred,red]
cm=[yellow,blue,green,lblue,lred,red]
cn=[yellow,blue,lblue,green,lred,red]
co=[yellow,blue,lblue,lred,green,red]
cp=[yellow,blue,lblue,lred,red,green]
cq=[blue,yellow,lblue,lred,red,green]
cr=[blue,lblue,yellow,lred,red,green]
cs=[blue,lblue,lred,yellow,red,green]
ct=[blue,lblue,lred,red,yellow,green]
cu=[blue,lblue,lred,red,green,yellow]
cv=[lblue,blue,lred,red,green,yellow]
cw=[lblue,lred,blue,red,green,yellow]
cx=[lblue,lred,red,blue,green,yellow]
cy=[lblue,lred,red,green,blue,yellow]
cz=[lblue,lred,red,green,yellow,blue]

chlist=[ca,cb,cc,cd,ce,cf,cg,ch,ci,cj,ck,cl,cm,cn,co,cp,cq,cr,cs,ct,cu,cv,cw,cx,cy,cz]

num0=[black,gray,white,black,gray,white]

num1=[gray,black,white,black,gray,white]
num2=[gray,white,black,black,gray,white]
num3=[gray,white,black,gray,black,white]
num4=[gray,white,black,gray,white,black]
num5=[white,gray,black,gray,white,black]
num6=[white,black,gray,gray,white,black]
num7=[white,black,gray,white,gray,black]
num8=[white,black,gray,white,black,gray]
num9=[black,white,gray,white,black,gray]
nums=[num0,num1,num2,num3,num4,num5,num6,num7,num8,num9]

comma=[white,black,black,white,white,black]
period=[black,white,white,black,black,white]
blank=[white,white,white,white,white,white]
def check(checkarray,template):
  for i in range(6):
    if not (checkarray[i]==template[i]).all():
      return False
  return True

for y in range(maxY):
  print()
  for x in range(maxX):
    for i,ch in enumerate(chlist):
      if check(getColors(x,y),ch):
        print(chr(97+i),end='')
      if check(getColors(x,y),blank):
        print(' ',end='')
        break
    for i in range(10):
      if check(getColors(x,y),nums[i]):
        print(i,end='')
    if check(getColors(x,y),comma):
      print(',',end='')
    if check(getColors(x,y),period):
      print('.',end='')
    
```

実行結果

```
there is such as thing as a tomcat but have you ev 
er heard of a tomdog. this is the most important q 
uestion of our time, and unfortunately one that ma 
y never be answered by modern science. the definit 
ion of tomcat is a male cat, yet the name for a ma 
le dog is max. wait no. the name for a male dog is 
 just dog. regardless, what would happen if we wer 
e to combine a male dog with a tomcat. perhaps wed 
 end up with a dog that vomits out flags, like thi 
s one rtcp should,fl5g4,b3,st1cky,or,n0t
```
hintにあるように最後の部分の空白を{}に変更し、
rtcp{should,fl5g4,b3,st1cky,or,n0t}


とけたcryptはこれが全て

# Forensics

## Neko Hero
Please join us in our campaign to save the catgirls once and for all, as the COVID-19 virus is killing them all and we need to provide food and shelter for them!
nya~s and uwu~s will be given to those who donate!
and headpats too!

##### 回答

もらった画像の
相方が解いた、画像の最下位ビットを強調すればいいらしい。


Forensicsで解けたのはこれだけ

# Misc
## Spilled Milk

oh no! i'm so clumsy, i spilled my glass of milk! can you please help me clean up?

真っ白な画像が渡される。
どこをどう見ても人間には区別がつかない白である。が画素値が1だけ違うのだろうと読んでwindowsのペイントで色を塗る。

かろうじて読めるので読む

rtcp{th4nk$_f0r_h3lP1nG!}

## Zip-a-Dee-Doo-Dah

I zipped the file a bit too many times it seems... and I may have added passwords to some of the zip files... eh, they should be pretty common passwords right?

Dev: William
 Hint! A script will help you with this, please don't try do this manually...
 Hint! All passwords should be in the SecLists/Passwords/xato-net-10-million-passwords-100.txt file, which you can get here : https://github.com/danielmiessler/SecLists/blob/master/Passwords/xato-net-10-million-passwords-100.txt
or alternatively, use "git clone https://github.com/danielmiessler/SecLists"

1819.zipがダウンロードできる
##### 回答
1819.gzを解凍すると1818.tarが手に入る
それを解凍すると1817.tarそしてその中の1816.zipがありパスワードがかかっている。そしてヒントにあるサイトにパスワード一覧がある。(100)
そのため手作業だと最悪1819*100試行しなければいけないのでは？と考えられる。
のでZip,gzip,tarを気合で見分けて総当たりを仕掛けるスクリプトを書く
途中ファイルが複数入ったファイルがあるが数字が大きい方は解凍しても空なので小さい数字の方を解凍する。

```

import gzip

f=open('passwordlist.txt')
lines=f.readlines()
list=[]
for line in lines:
  list.append(line.replace('\n',''))
list[0]='123456'
print(list)
f.close()

f=gzip.open('1819.gz')
x=f.read()
tmp=open('tmp',mode='wb')
tmp.write(x)
tmp.close()
f.close()

import tarfile
import subprocess
import os
import zipfile
count=0

def getname(dirs):
  min=9999
  minid=0
  for i,file in enumerate(dirs):
    n=int(file.split('.')[0])
    if min>n:
      min=n
      minid=i
  return dirs[minid]


while True:
  count+=1
  print(count)
  ret=subprocess.check_output(['file','tmp'])[:-1]

  print(ret)
  if ret=="tmp: POSIX tar archive (GNU)".encode():
    with tarfile.open('tmp') as tmp:
      tmp.extractall('./extracted')
    dirs=os.listdir('extracted')
    print(dirs)
    fname=dirs[0]
    if len(dirs)==2:
        fname=getname(dirs)
    subprocess.call(['mv','extracted/'+fname,'tmp'])
    subprocess.call(['rm','-rf','extracted'])

  if "tmp: gzip compressed data" in str(ret):
    with gzip.open('tmp') as tmp:
      print(tmp)
      x=tmp.read()
      tmp=open('tmp2',mode='wb')
      tmp.write(x)
      tmp.close()
    subprocess.call(['mv','tmp2','tmp'])
    subprocess.call(['rm','-rf','tmp2'])
  
  if "Zip archive data," in str(ret):
    with zipfile.ZipFile('tmp') as zip_file:
      for pwd in list:
        try:
          zip_file.extractall(path='extracted', pwd=pwd.encode())
          print('extraction is successful!')
          print(os.listdir('extracted'))
          dirs=os.listdir('extracted')
          fname=dirs[0]
          if len(dirs)==2:
              fname=getname(dirs)
          print(fname)
          subprocess.call(['mv','extracted/'+fname,'tmp'])
          subprocess.call(['rm','-rf','extracted'])
        except Exception:
          
          pass
      
      print('zip end?')
```
少しずつ解凍が進んでいく様子を見るのは楽しい。
最後まで解凍したらファイルがAscii textになって無限ループするのでプログラムを止めてファイルを確認する
flagはrtcp{z1pPeD_4_c0uPl3_t00_M4Ny_t1m3s_a1b8c687}

## Music Lab

Do you like my song? ♪

masterpiece.mid

これはMacのデフォルトアプリで開いたら文字っぽいのが見えたら読んだだけ、windowsだと苦戦するかも知れない？

なおたくさん読み間違えた
0とOの違いとか難しい
rtcp{MOZ4rt_W0uld_b3_proud}

## Satan's Jigsaw
Oh no! I dropped my pixels on the floor and they're all muddled up! It's going to take me years to sort all 90,000 of these again :(

Hint! long_to_bytes

渡されるのはchall.7z
##### 解凍
chall.7zを解凍すると1pxの画像ファイルが大量にある。ジグゾーパズルのようにこれを並べ替える問題らしい。
ファイル名は長い数字.jpgとなっている
ヒントにあるlong_to_bytesを調べると数値から文字列にする関数が引っかかるのでファイル名の数値の部分をこの関数にかけると "x y"と言う形式で座標が手に入るのでそれを並べ替えた画像を作成するプログラムを書く

```
from Crypto.Util.number import long_to_bytes
import os
import cv2
import numpy as np

dirname='chall/'
files=os.listdir(dirname)
height,width=300,300
imageArray = np.zeros((height, width, 3), np.uint8)
count=0
for file in files:
  count+=1
  if(count%1000==0):print(count) 
  x,y=str(long_to_bytes(file[:-4]))[2:-1].split(' ')
  img=cv2.imread(dirname+file)[0][0]
  x=int(x)
  y=int(y)
  imageArray[y,x]=[img[0] ,img[1],img[2]]
cv2.imshow('a',imageArray)
cv2.waitKey()

```
プログラムを実行し少し待てば画像が表示される

![ZigsawResult.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323266/7c8824d9-f28c-d070-d5fd-610740f51875.png)


画像上のQRコードを読めばフラグになる。

# OSINT
相方が解いた問題はあるが自分はしてないので省略

# Pwn
なんと一問もわかっていない

# ReverseEngineering
基本的にプログラムを読んでプログラムの流れを逆算すれば何とかなる、別記事に書く..はず。

# Web
I don't like needles

They make me SQueaL!

http://challs.houseplant.riceteacatpanda.wtf:30001

##### 回答
何だかとてもSQLインジェクションをして欲しそうなのでUserに以下を入力

```
' or 1=1; -- 
```

無事Logged Inと表示される。がそれ以上何も起きない。と言うことでページのソースを読むと?sauseと書かれたコメントがある
と言うわけでhttp://challs.houseplant.riceteacatpanda.wtf:30001/?sauce
にアクセスする
コードを見ると
flagman69と言うユーザーでログインしたらflagを表示するようなので

```
flagman69'; --  
```
これでフラグが表示される

rtcp{y0u-kn0w-1-didn't-mean-it-like-th@t}

## QR Generator

I was playing around with some stuff on my computer and found out that you can generate QR codes! I tried to make an online QR code generator, but it seems that's not working like it should be. Would you mind taking a look?

http://challs.houseplant.riceteacatpanda.wtf:30004

Hint! For some reason, my website isn't too fond of backticks...

##### 回答
リンクを踏んだ先のサイトでは文字が入力されるとQRコードが表示される。
読み込んでみると表示されたQRコードは入力文字の1文字目を表すQRコードのようだ
ヒントにあるようにバッククォートを入力するとQRコードの内容がErrorという文字列のQRコードになる。
ここから先何をすればいいのかわからずしばらく悩んだ
バッククォートを二個並べるとError出ないQRコードに戻る。
そして苦悩の果てに以下の文字を入力するとaのQRコードが表示されることがわかった

```
`echo a`
```
と言うことで

```
`eval ls`
```
と入力するとコマンドの出力一文字目であるRのQRコードが表示された、次にsedコマンドを使ってRを取り除く

```
`eval ls | sed "s/R//"`
```
すると今度はEが見える、と言うことで進めていくとlsコマンドの最初の行はREADME.mdだった
そのような感じでsedコマンドを組み合わせながらflag.txtがあることを確認しcatの確認していくと
flagが入手できる

rtcp{fl4gz_1n_qr_c0d3s???_b1c3fea}



# 終わりに
今回はビギナー向けのCTFと言うことで割と多めの問題が解けたのでとても楽しかった。


この記事を読んでいただきありがとうございます。ご指摘などございましたら是非よろしくお願いします。
もしコメントでここもっと詳しくとかあれば書きます。