ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [시스템 해킹] pwnable 이야…
    카테고리 없음 2020. 1. 18. 03:25

    >


    안녕하세요, 코드 사기꾼입니다.오항 선은 pwanble.kr의 5번 사고를 풀겠습니다.


    >


    문제를 클릭해보니 로그인 시스템을 만들었다고 나와있네요. 코무 파 1에러가 발생하지는 않았지만, warning은 자신 왔습니다.(여담:gcc에서는 warning을 무시할 수 있습니다.) 각 설과 문제로 접속해 보도록 하겠습니다.


    문제에 접속해서 passcode.c 라는 파일을 열어본 결과이다. 첫 00바이트만의 주소 공간에 이름을 입력 받아 passcode첫 passcode2가 각 338첫 50첫 337첫 337과 함께라면 flag를 보이고 주지요.그러나 이상하게도, login함수로 scanf를 사용할 때, 주소값이 아닌 주소값이 알려주는 변수의 값을 전달했음을 확인할 수 있습니다. passcode 변수는 초기화도 안됐는데 말야. 왜 warning이 나왔는지 알 수 있습니다.그럼 소스도 다 봤으니 디스어셈블링 해봅시다.


    welcome 프로시저의 디스어셈블링 결과입니다.  welcom+48을 보면 scanf가 실행되는 것을 볼 수 슴니다. scanf는 함수 실행 전에 변수의 주소값 및 포맷 스트링을 인제로 받습니다.지금 쥬소가프에 들어간 부분(lea)가 ebp-0x70만 없어서 name배열은 아마 ebp-0x70에서 ebp-0x70+0x64(10진 수백)까지 정의되고 있습니다. 나쁘지 않은 특별한 일이 없으니 login 프로시저의 디스어셈블링 결과를 보도록 하겠습니다.


    login+24를 보면 어느 특정 값을 edx에 이양하는 모습을 볼 수 있으나 이는 scanf앞에 인제로 쓰려고 자신 왔기 때문에 passcode하나로 유추할 수 있다 같은 방법으로 passcode2번 유추할 수 있습니다. 유추된 passcode하나그와 passcode2의 주소 값은 이렇게 있다.passcode하나:ebp-0x하나 0, passcode2:ebp-0xc에서도 쵸은이에키 이상한 것이 꼭 우리는 welcome프로시저에서 name의 할당 구역이 ebp-0x70~ebp-0xc인 것을 확인하였습니다. 유추된 passcode하나의 주소 값을 보면 name의 마지막 4바이트의 구간임을 알 수 있는데, 이것은 passcode한 초기화되지 않아 빚어지는 뭉지에죠무이다니다. 이를 통해 name 배열을 입력받을 때 passcode 하나의 값을 함께 넣을 수 있을 것이다. 그런데 아무리 생각 봐도 passcode2에 값을 입력하는 법은 떠오르지 않네요.우리는 새로운 국면에 도달했습니다. 기존의 어프로치로는 문재를 해결할 수 없다고 생각되어 다른 방법을 생각해본 결과, 프로그램의 동작 순서를 변경하고 굳이 passcode를 검증하는 if문을 거치지 않고 시스템 함수에 접근하는 방법이 있을 것 같습니다.기본적인 것부터 생각해 보도록 합시다. 우리가 컴(1을 추진하고 객체 파 1을 실행하도록 하려면 프로시저의 실행 코드를 찾고 객체 파 1과 연결시켜야 한다. 이런 프로시저가 컴(1 되어 모이는 곳을 우리는 공유 라이브러리로 있다.이처럼 필요한 객체 파 1을 연결시키는 작업을 Linking라고 합니다만, 이 Linking방식은 두가지가 있습니다. Dynamic과 Static 방식입니다. Static방식은 파 1을 촉발할 때 라이브러리 스토리울 포함한 실헹파 1을 만들기 이다니다.


    >


    한편 Dynamic방식은 공유 라이브러리를 하그와잉의 메모리 공간에 적재하고 다양한 실헹파 1로 공유하고 사용하는 방식 이다니다.


    >


    Dynamic 방식으로 컴파일을 진행하면, 프로시저를 호출할 때 PLT와 GOT라는 것을 사용하도록 합니다. 그 이유는 메모리에 라이브러리를 적재시켜 사용했기 때문에 프로시저의 호출 주소를 알 수 없기 때문이다.


    PLT(Procedure Linkage Table)란 외부 프로시저를 연결하는 테이블입니다. PLT를 통해 다른 라이브러리에 있는 프로시저를 호출하여 사용할 수 있습니다.


    GOT(Global Offset Table)란 PLT가 참조하는 실제 프로시저 주소가 들어간 테이블입니다 PLT와 GOT는 프로시저가 아내 sound 호출밖에 없는지에 따라 그렇게 루틴을 달리 할 것입니다.만약 프로시저를 처sound 호출할 경우에는 프로시저의 PLT에서 GOT로 점프하는데, GOT가 프로시저의 주소를 알 수 없는 상태이기 때문에 dl_runtime_resolve라는 함수를 사용하여 필요한 프로시저의 주소를 알 수 있어서 이를 GOT에 써서 불러낼 것입니다.


    >


    그러나 2번째의 동작에서는 GOT가 이미 프로시저의 주소를 알고 있는 상태여서 곧 GOT를 참조 칠로프로시ー쟈을 부르히슬 것이다.


    >


    설명하다 보니 이야기가 길어졌지만 다시 본론으로 돌아가서 우리는 passcode 하나의 변수에 특정 프로시저의 GOT 주소를 적어서 해당 프로시저로 이동하는 GOT overwrite라는 비결을 이용해 문재를 해결합니다.


    name함수를 받을 때 passcode한 값을 정할 수 있기 때문에 우리는 scanf이후 코드인 fflush함수의 주소를 passcode하나에 넣어 passcode2에는 system함수의 즉석의 전 단계 인스트럭션을 넣어 문제를 풀어 보겠습니다. 그러기 위해서는 가장 먼저 flush가 GOT를 알아야 합니다.


    >


    fflush의 GOT값은 0x804a004이다. 그럼 passcode2에 들일 가치가 어떻게 구할 수 있을까요?


    >


    쉬울 것이다 디스어셈블링된 코드를 보고 system 바로 앞의 인스트럭션 주소를 확인하면 됩니다0x080485e3네요 그러나 passcode2는 퍼센트 d(한 0진수)형식으로 값을 받기 때문에 우리도 가격을 한 0진수로 변환된 것 345일 4일 47을 넣어 줘야 한다.자, 완성된 페이로드는 다음과 같이 될 것입니다. name의 마지막 4바이트는 passcode것의 값이어서 name에 불필요한 가격 96바이트를 넣고 마지막으로 fflush의 GOT을 넣습니다. 그리고 passcode2값 입력을 위해서 일 345일 4일 47를 넣어 줄것입니다.payload:'a'*96+"\x04\xa0\x04\08"+"것 345일 4일 47"


    >



    댓글

Designed by Tistory.