気まぐれブログ(日記・技術記事・研究のことなど)

気まぐれに更新します.温かい目で見ていただければ...

アドレスリークにおけるexploitコード

CTFにおいてpythonでexploitコードを書くことは頻繁にあるので, ここでコードとその詳細についてまとめておきます.

コード

from socket import *
from telnetlib import Telnet
from time import time, sleep
from sys import argv
from struct import pack, unpack

# cを受け取ったら, ret(cを含む)をreturn
def read_until(s, c):
    ret = ""
    while 1:
        ret += s.recv(1)
        if ret.endswith(c):
            return ret

# 0x12345678 => \x78\x56\x34\x12 
# <Qは64ビット, <Iは32ビット
def p(x):
    return pack("<Q", x)

# \x78\x56\x34\x12 => 0x12345678 => 305419896
# <Qは64ビット, <Iは32ビット
def u(x):
    return unpack("<Q", x)[0]

# telnet通信
def interact(s):
    print("[*] interactive mode")
    t = Telnet()
    t.sock = s
    t.interact()

# リモート接続かローカル接続か
if len(argv) >= 2 and argv[1] == "r":
    print("[*] connect to remote")
    HOST = "***.***.***.***" 
    PORT = *****

    # 以下, offsetの記述
    PUTS_OFF = *****
    SYSTEM_OFF = *****
    BINSH_OFF = *****
else:
    print("[*] connect to local")
    HOST = "localhost"
    PORT = 9999
    PUTS_OFF = *****
    SYSTEM_OFF = *****
    BINSH_OFF = *****

# メイン関数
def main():
    # メインの記述---

    # ---ここまで

    interact(s) # telnet通信

if __name__ == "__main__":
    main()

read_untilメソッド

関数名: read_until
引数: ソケットオブジェクトs, 文字列c
内容: cを受けとったら, それまでに受信していたデータをreturnする.

(例) read_until(s, 'hirata')を実行しているとする. "hello, hirata"というデータを受信したら, "hello, hirata"をそのままreturnする.

pメソッド

関数名: p
引数: 16進数値
内容: 0x12345678 => \x78\x56\x34\x12というような変換をする.

uメソッド

関数名: u
引数: 文字列数値 ('\x78\x56\x34\x12' のような感じ)
内容: \x78\x56\x34\x12 => 0x12345678 => 305419896というような変換をする.

interactメソッド

関数名: interact
引数: ソケットオブジェクト
内容: telnet通信を行う.

mainメソッド

関数名: main
引数: なし
内容: mainの内容を実装していく.