---
# System prepended metadata

title: 1/20 低レイヤ勉強会

---

# 1/20 低レイヤ勉強会

すみません、課題がおわらずpythonスクリプトの解説まで到達できませんでした。来週に回させてください
ただ、今回の内容でpythonスクリプトをある程度読み解けるようになるとは思うので、余裕があれば自分でやってみてください。

---
## 5.3 攻略
- main 関数の中で printf 関数は1 回しか呼ばれないので、libc のアドレスのリーク、main 関数を再度実行する、One-gadget RCE に飛ばす、という手順を取ります

- libc のアドレスのリークは、rsp からの相対アドレスが固定の値を読み出して求める(login3 問題と比べ、スタックに読み出したいアドレスを積む必要が無い)

- スタック中にもlibc のアドレスが存在します。
main 関数は、libc の__libc_start_main 関数から呼び出されるので、main 関数のリターンアドレスはlibc 中の 0x270b3 です(objdump -d -M intel libc-2.31.so > libc-2.31.so.txt )。
探すときはcall のオペランドがレジスタであることが目印になります。教科書の抜粋箇所参照

- GOP のアドレスを書き換えることにします。
    - 例えば、printf 関数のアドレスをOne-gadget RCE の
    - アドレスに書き換えると、プログラム中でputs 関数が呼び出されるとき、代わりにOne-gadget RCE が実行されます。
    **都合の良いことに、rot13 のmain 関数は最後にputs 関数を呼び出しています**。
    
    
>ソースコードではprintf 関数ですが、逆アセンブルしてみるとputs 関数になっています。
GCC は、書式文字列が書式指定子を含まず末尾が\n のprintf 関数の呼び出しを、末尾の\n を除いた文字列を引数とするputs 関数の呼び出しに変換します。
処理が等価でputs 関数のほうが高速だからでしょう

## rot13 のmain 関数のスタック 
(変数はソースコードを参照してください)

|アドレス|サイズ|内容|
|---|---|---|
|rbp-0x120| 0x0008| 未使用（rsp はここを指している）|
|rbp-0x118| 0x0004| 変数 i|
|rbp-0x114 |0x0004| 変数 d|
|rbp-0x110| 0x0100| 変数 buf|
|rbp-0x10| 0x0008 |未使用|
|rbp-0x8| 0x0008| カナリア（SSP有効のため）|
|rbp |0x0008| 古いrbp の値|
|rbp+0x8| 0x0008| main 関数からの戻り先のアドレス|

rsp の指すアドレスが書式指定子の%6\$lxに対応するので、rbp+0x8（= rsp+0x128）は、%43\$lx で参照することができます。

また、下記の攻撃スクリプトはbuf+0x80 以降に書き換えるアドレスを書いています。これは%24$lx以降が対応します。

> % \$? はおそらく文字化け、% \$lxが正しいと思われます。

### 引数とスタックの図解
![](https://i.imgur.com/gj1TE3s.png)
