기능 추가하고 그러면서 새로 만들었습니다.

기능은

1. 회원가입

2. 로그인

3. 프로필

4. 게시글

5. 댓글

6. 포인트 순위

7. 검색

 

이렇게 7가지로 크게 볼 수 있을 것 같습니다.

 

git으로 올려놓기만 하겠습니다...

 

https://github.com/Nesquitto/Web_Hacking_study/tree/master/SummerStudy

 

Nesquitto/Web_Hacking_study

Web Hacking Study. Contribute to Nesquitto/Web_Hacking_study development by creating an account on GitHub.

github.com

 

이번 웹 페이지의 가장 큰 특징은 몇 가지 기능들을 모듈로 나눴다는것에 있습니다.

 

아무튼... 전 그거에 의의를 가지려고요..ㅎ

'Web-기초 > AWS 웹서버' 카테고리의 다른 글

웹사이트 취약점 찾기...  (0) 2020.07.31
파일 입출력까지 끝냈습니다.  (0) 2020.05.23
여러 기능구현 페이지  (0) 2020.04.22
웹서버 ubuntu  (0) 2020.04.22
AWS Window에서 Bitnami WAMP 다운로드  (0) 2020.04.20

허우... Grown up은 FSB인데... 어려워서... note로 넘어왔는데... 이것도 어렵네여...

 

main
print_menu
edit_note
edit_desc

이렇게 4개 함수가 있으며,

win 함수로 클리어하면 되는 문제입니다.

 

 

우선 이 문제를 풀기 위해 보아야 할 곳은 .bss 영역입니다.

 

BSS 영역이 이런식으로 구성되어 있는데 여기서 s변수와 buf 변수의 거리가 32라는 것을 알아야합니다.

물론 다른 방법으로 풀 수도 있겠지만요.

 

아무튼, BSS영역이란 변수를 선언할 때 초기값이 0이나 null 값인 경우 데이터가 할당되는 공간입니다. 이와 반대로 어떤 값이 들어간 상태로 변수가 선언되면, 다른 DATA 영역으로 들어가게 됩니다. 

왜 이렇게 구분되는지는 잘 모르겠지만 인터넷이 그렇다고 하네요...

 

다시 돌아와서 우리가 저 부분을 어떻게 사용할거냐? 라고 한다면! 

edit_note

edit_note 부분에서 strncpy로 buf의 데이터를 v0만큼 s에 붙여넣게 되는데, 여기서 처음에 buf에 입력시켜줄 때 v0가 32보다 크게 된다면 저기 bss영역에 데이터가 들어갈 때 s를 넘어서서 buf에까지 데이터를 덮어쓰게 됩니다.

free를 통해 할당한 메모리를 해제하더라도 데이터는 남게 되는거죠.

 

저걸 잘 이용한다면 문제를 풀 수 있는데요. 문제를 정말 풀기 전에 이 개념도 알아야합니다.

PLT와 GOT의 개념입니다.

모든 함수에는 이 PLT와 GOT가 존재합니다.(아마도요..?)

PLT는 GOT로 점프하는 코드가 들어있으며, GOT는 실제 함수의 주소를 가지고 있습니다.

말하자면 PLT는 GOT의 값을 참고해서 실제 함수의 주소로 점프한다는 것이죠.

 

아직 제 식견이 부족해서 맞는지는 모르겠지만 이 문제는 GOT Overwrite 문제가 아닐까 싶습니다.

 

다시 또 문제로 돌아와서, 위의 edit_note에 s에 strncpy를 통해 값을 넣는데 이를 이용해서 buf에도 덮어쓸 수 있다고 했었습니다.

edit_desc

이제 이 코드를 실행하게 되면 buf에 32만큼의 데이터를 입력받게 되는데요.

입력받기 전에 저기 if문 보이나요?

저 부분 때문에 이런 공격이 가능한 겁니다.

buf에 값이 없을 때 malloc을 통해 동적 할당한다. 이기 때문에 아까 우리는 위에서 buf에 덮어써서 값이 존재하는 상태이므로 넘어갈 수 있게 됩니다.

 

그. 래. 서 read를 할 때 사용하는 buf에는 이미 데이터가 존재하는 상태라는 것이죠.

 

이 다음부터는 저도 큰 확신을 가지고 풀이를 작성하는것이 아닙니다...

이제 아무것도 몰라서 풀이를 봤는데... 저 buf에 read나 printf의 GOT 값을 넣더라고요?

 

그래서 GDB로 확인해봤습니다.

만약에 32개만큼 A를 넣고 64비트니까 8바이트 주소를 입력하면?

왜인지는 모르겠지만... RSI에 BBBBBBBB(주소입력자리)가 들어가서, 두번째 인자로 들어가네요?

아무튼 저기가 원래 그 자리인가봐여...

 

그래서? 저 B의 자리에 read의 GOT의 주소를 넣을 수 있게 되며, 그 뒤에 edit_desc에서 buf에 win의 주소를 넣으면,  GOT에서 jmp 하는 주소가 win의 주소가 되게 됩니다.

 

이렇게 입력하면 됩니다.

addr2가 read의 GOT이고, addr이 win의 주소입니다.

끄읕... 질문 해결하러 공부하러갑니다...

 

 

 

* 질문: bss 영역에 있는 s변수를 오버플로우 시켜 buf 변수에 GOT 주소를 덮어씌우고, 다시 read를 통해서 buf에 일정 바이트를 입력 받을 때 왜 GOT의 주소에 그 데이터가 들어가는 것일까? buf 변수에 GOT 주소가 값으로 들어간거라면, 똑같이 buf 변수에 데이터가 입력받아져야 하는거 아닐까?

 

* 질문: 위의 질문에서 혹시 오버플로우를 시키고 buf 변수에 덮어씌울 때 첫 8바이트는 buf의 주소를 나타내는 값이 아니었을까?

 

* 질문: 어떤 함수의 인자로 들어갈 때 그게 주소값이면, 주소값 내에 있는 값을 가져오는걸까..?

'Hacking-기초 > [PWN] Pwnable.xyz' 카테고리의 다른 글

[PWN] GrownUp (50pts)  (0) 2020.08.07
[PWN] xor (50pts)  (0) 2020.08.01
[PWN] misalignment (50pts)  (0) 2020.07.28
[PWN] add (50pts)  (0) 2020.07.28
[PWN] sub (50pts)  (0) 2020.07.28

네 misalignment 문제인데요. IDA로 디스어셈블 해서 보면 Add 문제와 상당히 비슷하게 생겼습니다.

 

배열을 이용해서 문제를 푸는 방식인것은 동일한데요.

조건이 달라지긴 했습니다.

3735928559가 보이는데 이는 16진수로 바꿨을 때 deadbeef입니다.

그리고 이 값을 47244640437로 바꿔야하죠.

 

이거 전 문제와 상당히 비슷해서 쉬울 줄 알았는데... 좀 어려웠습니다.

 

일단 제가 알고 있어야 했던것은 v5+7의 의미입니다. 

그리고 QWORD의 의미도 있고요.

 

GDB를 보고 풀어보려고 했는데... 문제에서 GDB를 사용하지 말라고 하네요..ㅎ

 

어쩔 수 없죠.

 

제가 삽질을 많이 해서 결론만 적겠습니다.

 

47244640437를 16진수로 바꿨을 때 B 0000 00B5가 됩니다.

scanf에서 16진수로 값을 입력하게 되면, 리틀 엔디안 방식으로 들어가기 때문에

B 0000 00B5는 b5 00 00 00 0b가 되어 입력되게 됩니다. 하지만 이건 문제에서 원하는 것과는 다르죠.

 

그래서 우리는 b5 00 00 00 0b로 입력해줘서 리틀 엔디안을 거치면, b 00 00 00 b5가 되게 해야합니다.

또 문제를 보니 v5+7번째에서부터 넣게 되네요.

 

이걸 종합해보면

0   1   2   3  4  5  6   7   8   9  10 11 12 

00 00 00 00 00 00 00 00 00 00 00 00 00 

00 00 00 00 00 00 00 b5 00 00 00 0b

이렇게 입력이 되어야 하는 것이죠.

 

이게 뭔지 모르실거같은데. 

숫자 3개 줄에서

첫 번째 줄은 v5로부터 떨어진 거리입니다. v5+7이기 때문에 앞선 7칸이 00으로 채워져야 합니다.

두 번째 줄은 그냥 자리를 나타내기 위한 수입니다. v5로부터 0칸 떨어진 위치, 1칸 떨어진 위치, 등등을 나타냈습니다.

세 번째 줄은 실제로 입력되어야 할 공간입니다. 여기서는 첫 번째 줄의 7 위치부터 11위치까지만 똑같으면 됩니다. if문에서 저부분만 검사하기 때문이죠. ㅎㅎ

예를 들어

00 00 00 00 00 00 00 b5 00 00 00 0b

ff ff ff ff ff ff ff b5 00 00 00 0b

이런 식으로 입력되어도 상관 없다는 겁니다.

 

아무튼 저런 식으로 데이터가 들어가도록 해야하는데...

 

저걸 통째로 계산하려면...

b000000b500000000000000

이걸 10진수로 바꾼

3.4043351210772203e+27

이걸 써야하는데... 도저히 사용할 엄두가 나지 않습니다.

인터넷 보니까 다들 나누기도 하고 그래서 저도 나눴습니다.

 

배열 한칸의 길이가 8바이트니까...

저기 위에 

이거에서

0이 첫번째 배열 변수, 8이 두번째 배열 변수가 될거니까...

b5 00 00 00 00 00 00 00

0b 00 00 00

이렇게 두개로 나눌 수 있습니다. 위치만 제대로 들어가면 되는거죠 뭐...

 

그래서 이걸 입력을 하도록 하면?

 

b5 00 00 00 00 00 00 00 = -5,404,319,552,844,595,200

0b 00 00 00 = 184,549,376

 

이렇게 두개를 입력해주면 됩니다. 10진수로 입력을 받기 때문이죠.

 

-5,404,319,552,844,595,200를 v5[0]에 입력하고

184,549,376를 v5[1]에 입력하게 되면?

이렇게 코드를 구성할 수 있게 되며,

 

이렇게 답을 찾을 수 있게 됩니다.

'Hacking-기초 > [PWN] Pwnable.xyz' 카테고리의 다른 글

[PWN] xor (50pts)  (0) 2020.08.01
[PWN] note (50pts)  (0) 2020.07.30
[PWN] add (50pts)  (0) 2020.07.28
[PWN] sub (50pts)  (0) 2020.07.28
[PWN] Welcome (50pts)  (0) 2020.07.28

add 문제입니다.

 

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int result; // eax
  __int64 v4; // [rsp+8h] [rbp-78h]
  __int64 v5; // [rsp+10h] [rbp-70h]
  __int64 v6; // [rsp+18h] [rbp-68h]
  __int64 v7[11]; // [rsp+20h] [rbp-60h]
  unsigned __int64 v8; // [rsp+78h] [rbp-8h]

  v8 = __readfsqword(0x28u);
  setup();
  while ( 1 )
  {
    v4 = 0LL;
    v5 = 0LL;
    v6 = 0LL;
    memset(v7, 0, 0x50uLL);
    printf("Input: ", argv, v7);
    if ( (unsigned int)__isoc99_scanf((__int64)"%ld %ld %ld", (__int64)&v4, (__int64)&v5, (__int64)&v6) != 3 )
    // scanf로 3개의 인자 값을 받아오고, 정상적인 3개 인자가 들어오지 않으면 실행
      break;
    v7[v6] = v4 + v5; // v4와 v5를 더한 값을 v7 배열의 v6번째 자리에 입력
    argv = (const char **)v7[v6];
    printf("Result: %ld", argv);
  }
  result = 0;
  __readfsqword(0x28u);
  return result;
}

main 함수입니다.

 

그리고 찾아보니 win 함수도 있습니다.

그냥 일로 ret 주소를 바꾸라는거같네요.

 

v7[v6]인걸 보니 v6의 값을 바꿔서 ret주소에 가도록 하고? 그 값을 저 win 함수의 주소로 바꿔버리면 될 것 같습니다.

 

배열의 크기가 11개니, 11개 공간 + sfp + ret로 해서 v6가 13이면 될 것 같네요.

 

그리고? 이동할 주소를 gdb를 통해 찾아봅시다.

 

0x400822 라고 하네요.

이제 이걸 10진수 정수로 입력받으니 변환시켜서 입력해주면 될 것 같습니다.

 

4196386이네요 ㅎ

 

이렇게 하고 실행하면?

 

이렇게 나옵니다!

 

끄읕

'Hacking-기초 > [PWN] Pwnable.xyz' 카테고리의 다른 글

[PWN] xor (50pts)  (0) 2020.08.01
[PWN] note (50pts)  (0) 2020.07.30
[PWN] misalignment (50pts)  (0) 2020.07.28
[PWN] sub (50pts)  (0) 2020.07.28
[PWN] Welcome (50pts)  (0) 2020.07.28

sub 문제입니다.

https://pwnable.xyz 

 

pwnable.xyz

 

pwnable.xyz


IDA로 디스어셈블 한 코드를 먼저 보시죠

 

설명을 덧붙이면..?

 

__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  int v4; // [rsp+0h] [rbp-18h]
  int v5; // [rsp+4h] [rbp-14h]
  unsigned __int64 v6; // [rsp+8h] [rbp-10h]

  v6 = __readfsqword(0x28u);
  sub_A3E(a1, a2, a3);
  v4 = 0;
  v5 = 0;
  _printf_chk(1LL, "1337 input: ");
  _isoc99_scanf("%u %u", &v4, &v5); // scanf 받기 때문에 이거일거라 생각했는데...
  if ( v4 <= 4918 && v5 <= 4918 ) // 둘 다 4918을 넘기면 안됩니다.
  {
    if ( v4 - v5 == 4919 ) // 빼서 4919여야 합니다.
      system("cat /flag");
  }
  else
  {
    puts("Sowwy");
  }
  return 0LL;
}

딱 저 세줄밖에 없어요...

 

%u가 부호없는 10진수라는데... 

그냥 한번 넣어봤습니다.

 

..?

그냥 되네요..?

 

왜지?

 

하면서 제출도 해봤습니다.

 

ㅇㅁㅇ;;;

나왔습니다...

왜지?

 

왜지?

 

왜지?

 

scanf에서 자료형을 정해주는건 그렇게 받아야하기 때문인거 아니었나요?

 

찾아보니까... 어차피 두 변수는 정수형이라서 음수를 넣으면 음수로 표현이 된다고 하네요..?

 

흐으으음...

 

그냥 끝내기에는 뭔가 그러니까 어셈블리 코드나 보고 가겠습니다...

 

메인 함수의 주소를 찾았고?

 

이게 메인함수의 어셈블리입니다...

 

끄읕...

'Hacking-기초 > [PWN] Pwnable.xyz' 카테고리의 다른 글

[PWN] xor (50pts)  (0) 2020.08.01
[PWN] note (50pts)  (0) 2020.07.30
[PWN] misalignment (50pts)  (0) 2020.07.28
[PWN] add (50pts)  (0) 2020.07.28
[PWN] Welcome (50pts)  (0) 2020.07.28

+ Recent posts