ctfのお勉強 ksnctf #1 #2 Easy Cipher #8 Basic is secure? #10 #!
ksnctfを解いてみた
とりあえず正解者の多い問題から順番に
problem.1 Test Problem
サンプル問題なのでコピー&ペーストで終わります。
problem.2 Easy Cipher
よくある暗号ね。
回転させるやつ。ぱっと見想像できるけども、総当たりのプログラム書いてみた。
tmp="EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yr\ ggref nsgre vg va gur nycunorg. EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag E\ bzr. Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT." alph = Array('a'..'z') alph_up = Array('A'..'Z') for i in 1..26 do a="*["+i.to_s+"]" tmp.each_char {|ch| if ch!=" " && ch!="." && ch!="," if j=alph.index(ch) a << alph[(i+j)%26] elsif j=alph_up.index(ch) a << alph_up[(i+j)%26] end elsif ch==" " a << " " end } puts a end
pythonだとdecodeのrot13指定すると一行で行けるらしいよ。
他にはtranslateとか。
import string rot13 = string.maketrans( "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz", "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") string.translate("Hello World!", rot13) ("Hello World").decode("rot13")
problem.10 #!
"#!" をグーグルで検索するだけ。
FLAG_S??????
つづく。
freerdpを使ってPass the Hashをテストする
FreeRDP
RDPを利用する場合、通常ユーザー名と平文パスワードを入力するかと思いますが、
パスワードの代わりにNTLMハッシュ や LMハッシュを使用して、認証を行います。
コマンドラインで簡単に試してみたい場合はpth-winexeなどのツールがありますが、
今回はfreerdpの機能を用いてハッシュでログインしてみます。
FreeRDP
利用用途としては
- ハッキング理解を深める
- パスワードを忘れてしまってなんとかしたい(ハッシュ取得は別の記事で)
悪いことをしたい
まずはアップデートとインストールから
$>apt-get update $>apt-get install freerdp-x11
あとは簡単。/uでユーザー名、/ptnでハッシュ、/dドメイン名、/vで接続先を指定しアクセスします。
$>xfreerdp /u:username /ptn:ハッシュパスワード /d:domain /v:192.168.0.102
RaspberryPi 人感センサーからカメラ撮影してメール送信しちゃう
パーツを揃える
- ラズパイ:Raspberry Pi Model B+ (Plus)
- ラズパイカメラ:Raspberry Pi Video Module Raspberry Pi Camera Board 775-7731
- 人感センサー: 焦電型赤外線(人感)センサーモジュール SB412A
接続する
接続はこんな感じ。
センサーはジャンパーケーブルで直接接続しました。5V,GPIO4,GROUND
人感センサーのデータシートはここ
焦電型赤外線(人感)センサーモジュール SB412A: センサ一般 秋月電子通商 電子部品 ネット通販
ラズパイのGPIO配置はここ。
GPIO: Models A+, B+, Raspberry Pi 2 B and Raspberry Pi 3 B - Raspberry Pi Documentation
設定する
まずは、ソフトウェアを諸々アップデートします。
いろいろバグとかでハマっても面倒なので。
#パッケージアップデート $> sudo apt-get update $> sudo apt-get upgrade #アプリケーションのアップデート $> sudo rpi-update
cameraを有効化
sudo rspi-config
enable cameraでenableにします。
センサーの設定GPIO4に指しているので、export設定をします。
センサーに反応があるとgipo4のvalueファイルに1、反応がなくなると0が出力されます。
$sudo echo 25 > /sys/class/gpio/export $cd /sys/class/gpio/gpio4 $sudo echo in > direction
動作確認
センサーでうまく値が入ってくるか確認します。
カメラの動作もとりあえずコマンドで単体チェックします。
$raspistill -o test.jpg
スクリプトを書く
gpioのvalueを確認して1が入っていた場合はカメラで写真をとってメール送信します。
メールがたくさん送られてきても面倒なので、sleep入れて少し止めています。
from __future__ import print_function import socket import time import RPi.GPIO as GPIO GPIO.setmode(GPIO.BCM) GPIO.setup(4, GPIO.IN) from contextlib import closing import time import picamera import datetime import smtplib import threading from email import Encoders from email.Utils import formatdate from email.MIMEBase import MIMEBase from email.Header import Header from email.MIMEMultipart import MIMEMultipart from email.MIMEText import MIMEText from email.mime.image import MIMEImage def main(): while True: inputValue = GPIO.input(4) if (inputValue == True): filename=capture() send(filename) time.sleep(300) time.sleep(1) def send(file): img = [file] send_email_img('no_reply@gmail.com', '******@gmail.com', u'Alert', u'Alert\n', img) def send_email_img(from_addr, to_addr, subject, body, imgs=[], server='smtp.gmail.com', port=587): encoding='utf-8' msg = MIMEMultipart() mt = MIMEText(body.encode(encoding), 'plain', encoding) if imgs: for fn in imgs: img = open(fn, 'rb').read() mj = MIMEImage(img, 'png', filename=fn) mj.add_header("Content-Disposition", "attachment", filename=fn) msg.attach(mj) msg.attach(mt) else: msg = mt msg['Subject'] = Header(subject, encoding) msg['From'] = from_addr msg['To'] = to_addr msg['Date'] = formatdate() ADDRESS = "******@gmail.com" _user = "*************************" _pass = "************************* " smtp = smtplib.SMTP(server, port) smtp.ehlo() smtp.starttls() smtp.ehlo() smtp.login(_user, _pass) smtp.sendmail(from_addr, [to_addr], msg.as_string()) smtp.close() def capture(): camera = picamera.PiCamera() camera.hflip = True camera.vflip = True camera.resolution = (480,360) now = datetime.datetime.now() fmt_name = "pic_{0:%Y%m%d-%H%M%S}.png".format(now) time.sleep(2) camera.capture(fmt_name) time.sleep(2) camera.close() return fmt_name if __name__ == '__main__': main()
他のサイトでcamera.close()の記載がないところがありますが、これないとエラーで止まります。
キャプチャ取り忘れたんですが、Out of resourcesとかOut of memory とかその辺のエラーだった気がします。
写真をとって貯め続けるので、容量注意してください。
メールで送られるので上書きでも良いかも。
最終動作テスト
スクリプトを起動して、メールが受信されるか確認します。
AWS(ELB)+nginx+unicornの設定の際にはまったポイント。
構成
構成としてはこんな感じ。外からポートhttps443で受けて、中はhttp80で。
permissionとか、csrfのActionController::InvalidAuthenticityToken errorエラーが出たりと結構はまりました。
- まずはログの確認。どこまで通信できてますか。エラーは出てませんか。
/var/log/nginx/access.log
/var/log/nginx/error.log
rails_home/log/unicorn.log
rails_home/log/production.log または rails_home/log/development.log
1. nginxでpermission denyエラーがでている。
permissionエラーの場合。nginxでよくでたりします。
この場合、ファイル・フォルダに権限を与えましょう。
chmod 755 /home/rails_home/
下位フォルダだけ権限を与えていて、上位フォルダの権限がない可能性もあるので、しっかりと確認を。
2. nginxでsocketがないと言われている
nginxとunicorn.rbの設定を再度確認しましょう。
unicorn.rbで設定した
listen "/tmp/unicorn.sock"
とnginx.confで設定した下記パスが一致してますか。
upstream unicorn { server unix:/home/unicorn_sample/tmp/unicorn.sock; }
この例の場合違っていますので、「/tmp/unicorn.sock」に修正しましょう。
設定変更後は各プロセスの再起動を忘れずにしましょう。
3. csrfのActionController::InvalidAuthenticityToken error
offにするという手もあります。日本語の多くのページでオフにする記載をみかけますが、セキュリティ上よくありません。
nginxの設定を見直しましょう。
root設定はあってますか。locationのheader設定はあってますか。
http { upstream unicornapp { server unix:/tmp/unicorn.sock; } server { listen 80 default_server; listen [::]:80 default_server; server_name localhost; root /home/rails_home/public; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://unicornapp; } }
4. ELBでInServiceにならない
ヘルスチェックでこけています。
まずはnginxでヘルスチェックのアクセスログがのっかてきているかを確認してみましょう。
/var/log/nginx/access.log
のっていない場合はAWSのセキュリティポリシーで対象のポートを閉じてませんか?
EC2上からcurl/wgetコマンドでヘルスチェック先へのアクセスを確認してみましょう。ページがない可能性があります。
$curl http://localhost/
おまけ1
empty gifでヘルスチェック(nginxまでのヘルスチェック)
location = /healthcheck.html { access_log off; empty_gif; }
health_check用のコントローラーを準備
上の設定だと裏が死んでいても気づかないので、こちらの方が良いかと。
rails g controller health_check
class HealthCheckController < ApplicationController def index render :text => "Alive\n", :status =>200 end protected def allow_http? true end end
route.rb
get "health_check" => "health_check#index"
おまけ2
サーバー設定を隠す。
レスポンスのヘッダーにサーバー設定がのっかてきます。
このままだとセキュリティ上よろしくないので、見えないようにすることをおすすめします。
Server: nginx/1.8.1
nginx.confに下記を追加して再起動してください。
バージョン情報はのってこなくなります。
http { server_tokens off; }
書き換えてnginx自体の表示もなくせますが、それはまたの機会に。
Linkedin oauthでこける
invalid redirect_uri. This value must match a URL registered with the API Key.
急にこんなエラーでこける。それもproduction環境で。
linkedinのdeveloperページで承認リダイレクトURLを設定。
設定先はエラーが出ている画面の箇所
&redirect_uri=https%3A%2F%2Fwww.*************.com%2Fauth%2Flinkedin%2Fcallback&
この場合だと
https://www.*********.com/auth/linkedin/callback
この設定でとりあえずこのエラーは回避。
あ。最後にLinkedinのDeveloperページの下部にある更新ボタンで更新を忘れずに。
devise 確認メールのあれこれ
確認メールのurlアドレスをhttpsに変更
app/views/devise/mailer/confirmation_instructions.html.erb
confirmation_url(@resource, :confirmation_token => @token, protocol: "https")
確認メールの開発用と公開用の設定
ここでsmtpとかドメイン設定とかを忘れずに
config/environments/development.rb
config/environments/producation.rb
# General Settings config.app_domain = 'www.hogehoge.com' # Email config.action_mailer.delivery_method = :smtp config.action_mailer.perform_deliveries = true config.action_mailer.default_url_options = { host: config.app_domain } config.action_mailer.smtp_settings = { address: 'smtp.hogehoge.com', port: '587', enable_starttls_auto: true, user_name: 'hogehoge', password: ENV['MAIL_KEY'], authentication: :plain, domain: 'hogehoge' }
パスワードは環境変数へ
$export MAIL_KEY=foofoo