프로그래밍

c언어 취약점에 대해서

gets를 이용한 코드에서

 

 

#include <stdio.h>

#include <ctype.h>

 

#define H2D(x) ((x)<='9'?(x)-'0':(toupper(x))-'A'+10) //16進数1桁の文字を数値に

                                              // 0-9,a-f,A-Fのみ正しく動作する

static char st1[] = "This is a pen.";

static char st2[] = "I have an apple.";

 

// 目標:入力だけでこの関数を実行する

void sub2(void) {

  printf("Bingo!\n");

}

 

// gets()を使った危険な関数

int sub1(int hint) {

  char *p = st1;

  char str[] = "Hello, World!!!";

  char buf[32]; // gets()で入力される文字列のバッファ(小さいのですぐ溢れる)

  char *s,*d;

 

  // ヒントとして各変数や関数のアドレスを出す

  if (hint) {

    printf("各変数が格納されているアドレス:\n");

    printf("st1  : %p\n", st1);

    printf("st2  : %p\n", st2);

    printf("d    : %p\n", &d);

    printf("s    : %p\n", &s);

    printf("buf  : %p\n", buf);

    printf("str  : %p\n", str);

    printf("p    : %p\n", &p);

    printf("各関数のアドレス:\n");

    printf("sub1 : %p\n", sub1);

    printf("sub2 : %p\n\n", sub2);

  }

 

  puts("文字列を入力:");

  gets(buf);

 

  // bufに入力された文字列に%xxという形式の部分があれば

  // xxを16進数とみなして1バイトの値に置き換える

  s = d = buf; // sは入力文字、dは変換後を指すポインタ

               // 変換後のデータはbufに上書きされていく

  do {

    if(*s == '%') { // %があれば

      *d = H2D(*(s+1))*16+H2D(*(s+2)); // 16進数2桁の文字を数値に

      s+=3; // %xx

      d++;

    } else {

      *d++ = *s++;

    }

  } while(*d);

 

  puts("\n出力文字列:");

  puts(buf);

  puts(str);

  if (hint) {

    printf("ヒント:pの値 %p\n", p);

  }

  puts(p);

  return 0; // 返却値はいつも0のはず

}

 

int main(int argc, char *argv[]) {

  int r;

  char buf[4096]; // バッファオーバーフローしやすいように空間を空けてある

  r = sub1(argc > 1); // 引数があればヒントを出すように

  printf("sub1() returns %d\n", r); // sub1()の返り値表示

  return 0;

}

 

 

 

 

 

이 코드를 실행했을때

스크린샷 2021-04-15 21.40.51.png

welcome 을 입력하면

welcome이 첫번째줄

hello, woreld가 두번째

This is a pen 이 세번째 줄로 나올때

 

32bit가 넘는 입력을 하였을때는 

스크린샷 2021-04-15 21.42.39.png

이렇게 두번째줄이 welcome으로 변합니다.

 

 

 

 

하지만 세번째 줄을 바꿀려고 한다면 어떤 입력을 해야되는지 감이 안잡힙니다... 어떤식으로 하여야 될까요?? 질문이 처음이라 내용에서 이해 안되시는 부분이 있으면 말해주세요 

4개의 댓글

2021.04.15

C에서 벗어나서 Golang을 쓰자이제 ㅎㅎㅎ

0
2021.04.15

출력문자열 세번째는 p인데 st1 배열 내용을 바꿔야되지 않을까

그리고 힌트로 변수들 주소 보고 변수들 배치를 봐야됨

버퍼 오버플로우로 얼마나 덮어써야 하는지 나올듯

0
2021.04.15

1. buf 덮으려고 32byte 넣고

2. str 덮으려고 17 ~ 24바이트정도 넣으면 될건데 스택에 몇바이트 잡혔는지는 gdb로 까보거나 1바이트씩 늘려가면서 세그먼테이션 폴트 뜨는 바이트 수 확인하면 됨

3. 그 뒤로 출력 원하는 문자열 주소 넣으면 될 듯

4. 추가로 4byte 더미 넣어서 SFP 대충 덮어씌우고 ret주소 4바이트를 sub2 주소 넣으면 bingo 까지 뜰거

 

0
2021.04.15
@티벳여우

정말정말 감사합니다. 안되서 답답했는데 ㅠㅠ

0
무분별한 사용은 차단될 수 있습니다.
번호 제목 글쓴이 추천 수 날짜 조회 수
5677 [프로그래밍] Exiftool 이거 일본어 못 읽는데 12 부터시작하는이세... 0 12 시간 전 128
5676 [프로그래밍] 반응형 웹페이지가 내가상상한거랑 좀 다르네 3 평택국 0 1 일 전 322
5675 [프로그래밍] 고졸 FE개발자 연봉, 상황에 조언좀.. 15 쾅꿍꿍 0 1 일 전 426
5674 [프로그래밍] 물경력들 보면 책임을 이해못하는것같음 5 mils 1 2 일 전 266
5673 [프로그래밍] GPT가 코딩 다해주네 3 겜신병자 0 3 일 전 610
5672 [프로그래밍] 크로스플랫폼의 욕심은 끝이없다 4 ye 0 5 일 전 340
5671 [프로그래밍] 월루중에 백준 풀어보고 있는데, 6 오뜨 0 6 일 전 611
5670 [프로그래밍] 같이 일했던 시니어급 개발자 아예 직무 바꿨네.. 15 흐린눈 2 7 일 전 611
5669 [프로그래밍] 안드로이드 스튜디오가 이상해요... 2 집에가게해줘 0 9 일 전 374
5668 [프로그래밍] 양심고백 5 너가전부옳아 0 10 일 전 354
5667 [프로그래밍] 멀티겜만드는거 첨인데 빡시네 4 아님나 0 10 일 전 405
5666 [프로그래밍] vscode에 이런 설정도 있나? 17 너가전부옳아 0 10 일 전 267
5665 [프로그래밍] 네트워크 관련 관련 질문드립니다 6 그러네요 0 12 일 전 197
5664 [프로그래밍] 언리얼 C++이라고 불리는 이유? 4 nyvux 0 12 일 전 317
5663 [프로그래밍] 코틀린과 swing 기능 관련 다시 질문 4 집에가게해줘 0 13 일 전 150
5662 [프로그래밍] 22대 총선 정보를 모아 볼 수 있는 사이트 2 마포구알짜땅주인 0 14 일 전 302
5661 [프로그래밍] 집에서 공부하는 개붕이 있냐 8 년차html개발자 0 15 일 전 467
5660 [프로그래밍] Mojo 써본사람 있음? 5 너가전부옳아 1 15 일 전 339
5659 [프로그래밍] 코린이 swing 질문좀... 1 집에가게해줘 0 16 일 전 149
5658 [프로그래밍] 파이썬 pillow-avif-plugin 라이브러리 gif->avif 변환 관... 3 부터시작하는이세... 0 16 일 전 121