ctfのお勉強 ksnctf #1 #2 Easy Cipher #8 Basic is secure? #10 #!

ksnctfを解いてみた

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.8 Basic is secure?

pcapをダウンロードしてWiresharkで眺める。
とりあえずhttpに絞り込みをして。
f:id:skymay:20170131133808p:plain

認証しているところを見るとフラグが出てくる。
f:id:skymay:20170131133847p:plain

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 人感センサーからカメラ撮影してメール送信しちゃう

ラズベリーパイで遊ぶ

少し前に買って放置されていたRaspberryPi で遊んでみました。
人感センサーをつけて、反応したらカメラ撮影してそのままGmail使ってメールを投げます。

パーツを揃える

  • ラズパイ:Raspberry Pi Model B+ (Plus)
  • ラズパイカメラ:Raspberry Pi Video Module Raspberry Pi Camera Board 775-7731
  • 人感センサー: 焦電型赤外線(人感)センサーモジュール SB412A





接続する

接続はこんな感じ。

f:id:skymay:20171211134750p:plain
接続

センサーはジャンパーケーブルで直接接続しました。5V,GPIO4,GROUND
f:id:skymay:20160904105849j:plain

f:id:skymay:20171209111656j:plain


人感センサーのデータシートはここ
焦電型赤外線(人感)センサーモジュール 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 とかその辺のエラーだった気がします。

写真をとって貯め続けるので、容量注意してください。
メールで送られるので上書きでも良いかも。

最終動作テスト

スクリプトを起動して、メールが受信されるか確認します。

まとめ

ハード部分は全然詳しくないのですが、いろいろなサイトを参考にしながら、意外に簡単にできました。
Web経由で再起動、ストリーミング操作機能とかをつけてもおもしろいかもしれない。ラズパイ可能性は無限大ですね。
いずれは自宅警備を格安ラズパイロボットへ。

AWS(ELB)+nginx+unicornの設定の際にはまったポイント。

AWS+nginx+unicornの設定の際にはまったポイント。

基本的な導入については他の方々が書いているのでこちらとか、グーグル先生を参照ください。
qiita.com

構成

構成としてはこんな感じ。外からポートhttps443で受けて、中はhttp80で。
permissionとか、csrfActionController::InvalidAuthenticityToken errorエラーが出たりと結構はまりました。
f:id:skymay:20160817151922p:plain


- まずはログの確認。どこまで通信できてますか。エラーは出てませんか。

/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. csrfActionController::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環境で。

f:id:skymay:20160312141620p:plain


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