ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [시스템 해킹] pwnable.kr 5번(passcode) 봅시다
    카테고리 없음 2020. 2. 9. 02:30

    >


    안녕하세요 코드 사기꾼입니다오늘은 pwanble.kr의 5번 문재를 풀겠습니다.


    >


    사고를 클릭해보니 로그인 시스템을 만들었다고 적혀 있네요. 컴퍼 하나 에러는 생성하지 않았지만 warning은 과인이 왔습니다(여담:gcc에서는 warning을 무시할 수 있습니다).자, 사고와 접속해 보도록 하겠습니다.


    의문에 접속하고 passcode.c라는 파 1을 열어 본 결과입니다. 100바이트만의 주소 공간에 이름을 입력 받아 passcode1과 passcode2가 각 338150,13371337과 함께라면 flag을 나타내우이뭉네요. 그렇지만 이상하게도 login함수에서 scanf를 사용할 때 주소 값이 아닌 주소 값이 가리키는 변수의 값을 전달한 것으로 확인할 수 있습니다. passcode의 변수는 초기화 되어있지 않은데 스토리군요. 왜 warning이 나왔는지 알 것 같아요.자 그럼 소스도 다 봤으니까 디스어셈블링 해볼게요


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


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


    >


    반면 Dynamic 방식은 공유 라이브러리를 자신의 메모리 공간에 적재하여 여러 실행파 하나로 공유하여 사용하는 방식입니다.


    >


    Dynamic 방식으로 컴퍼 하나를 실행하면 프로시저를 호출할 때 PLT와 GOT를 사용하게 됩니다. 그 이유는 메모리에 라이브러리를 적재시켜 사용하고 있기 때문에 프로시저의 호출 주소를 모르기 때문입니다.


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


    GOT(GlobalOffsetTable)란 PLT가 참조하는 실제 프로시저의 주소가 들어 있는 테이블입니다. PLT와 GOT는 프로시저가 처음 호출하는지 여부에 따라 루틴을 달리합니다.만약에 프로시저를 처음 호출할 경우에는 프로시저의 PLT에서 GOT로 넘어가는데 GOT가 프로시저의 주소를 모르는 상태이기 때문에 dl_runtime_resolve라는 함수를 사용하여 필요한 프로시저의 주소를 알고 이를 GOT에 써서 호출합니다.


    >


    그러나 2번째의 동작에서는 GOT가 기위 프로시저의 주소를 알고 있는 상태이므로 즉석 GOT를 참조 칠로프로시ー쟈을 부르히스.


    >


    설명을 드리면, 이야기가 길어졌는데, 다시 본론으로 돌아가서 passcode의 첫 번째 변수에 특정 프로시저의 GOT 주소를 쓰고 그 프로시저로 이동하는 GOT overwrite라는 비법을 사용해서 문제를 풀겠습니다.


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


    >


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


    >


    간단합니다. 디스어셈블링된 코드를 보고 시스템 즉시 이전 설치 주소를 확인합니다.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.