Write up (Wargame)/Pwnable

[pwnable.xyz] xor 풀이

그믐​ 2022. 12. 24. 02:31
반응형

analysis


canary 없음.

 

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // [rsp+Ch] [rbp-24h]
  __int64 v4; // [rsp+10h] [rbp-20h] BYREF
  __int64 v5; // [rsp+18h] [rbp-18h] BYREF
  __int64 v6; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v7; // [rsp+28h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  puts("The Poopolator");
  setup();
  while ( 1 )
  {
    v6 = 0LL;
    printf(format, argv);
    v3 = _isoc99_scanf("%ld %ld %ld", &v4, &v5, &v6);
    if ( !v4 || !v5 || !v6 || v6 > 9 || v3 != 3 )
      break;
    result[v6] = v5 ^ v4;
    argv = (const char **)result[v6];
    printf("Result: %ld\n", argv);
  }
  exit(1);
}

 

main에서는 숫자 3개를 입력받아서

숫자 중 0이 있거나 마지막 숫자가 9보다 크면 break한다.

 

result의 v6 인덱스에는 v5와 v4를 xor한 값이 들어간다.

result는 bss에 존재한다.

relro에 의해 result의 oob를 이용해서 got overwrite는 불가능하다.

 

argv를 사용한다는 점에서 이상하다.

printf에 argv를 그대로 넣는 점에서 fsb가 가능하지 않을까

안 되는 것 같더라.

 

또 특이한 점은 code 영역이 rwx 권한을 모두 가진다는 것이다.

 

oob를 이용하여 코드 수정이 가능하다.

종료 조건 이후 실행하는 call exit 부분을 partial overwrite를 통해 win으로 우회가 가능할까

 

pie에서 exit 함수는 0x830으로 끝나고 win 함수는 0xa21로 끝난다.

 

exploit


그러면

 

main에서 main+148이 call exit이고

main+153이 다른 instruction인걸로 보아

 

148부터 152까지가 call exit 관련인듯 한데

어딜 바꿔야할까

 

https://aidencom.tistory.com/190

 

[ Assembly ] JMP, CALL 명령 주소 계산법

umbum.dev/102 jmp, call instruction 주소 계산 Intel x86 architecture에서 JMP, CALL 명령어는 5Byte로 opcode와 operand는 다음과 같다. ```c JMP : E9 XX XX XX XX CALL : E8 XX XX XX XX ``` 이 때 operand는 절대주소 값이 아니라, 현

41d3n.xyz

 

0xe8이 call 이라는 뜻이고

뒤에 4byte가 상대주소로 쓰인다.

 

oob를 통해서 뒤 4byte를 바꿔주면 된다. 뭘로 바꾸지

상대 주소 = 목적지 주소 - rip - 5라고 한다.

 

목적지 주소는 win 주소..

 

0xff ff ff 54이다.

 

그러면  main+149에 54, main+150에 ff 넣으면 된다.

 

음. 위치를 계산하는건

 

(main+149 - result)/8을 했더니 -262887이 나온다.

 

주소가 잘 안들어간다.

 

맨 뒤가 무시된다. 왜징

대충 뒤에 00을 주고 

 

 

0xffffff5401 1 -262887

 

정확히는 

1099511583745 1 -262887 하니까 win이 들어간다.

 

gdb에서는 되든거 같더니 안된다.

 

그러면 다른 풀이처럼 0xffffff54e9 1 -262887로 해본다.

 

1099511583977 1 -262887

 

이건 또 된다.

 

왜지..

gdb랑 실제랑 다른갑다. 어떻게 보면 뒷자리가 들어가지 않는게 이상하니까

 

 

 

반응형