这道题考察两个知识点:
1。int与unsigned int比较,用负数跳过比较,实现大量输入。
2。输入变相限制,在length_input -9之前,检查Alpha 和numeric,因为最后的输入是ret,填写要跳转的地址,必然包括0x7fff等,肯定过不了限制,题目用-9留下了8字节写ret。
3。对输入做限制,只能输入Alphanumeric shellcode ,网上找了一个现成人87 bytes Alphanumeric shellcode
https://www.exploit-db.com/exploits/35205
用ALPHA3,AE64等 shellcode转换工具,至少都是135个自己,超出了RET长度现在(name:0x60,rsp:0x8,total:104)。
Alphanumeric shellcode是一个不错的shellcode变种学习资料:
1.RET地址定位:
从function()退出后,RSP指向ret后一单元($ret+8), 通过两个pop,向高地址再移动两个位置,即$ret+0x18,push 0x30,后,RSP为$ret+0x10,再push rsp,pop rcx,rcx即为rsp内容,也就是$ret+0x10地址,后面基于这个地址做加减得$ret地址,存入RSI。
_start: # "XX"
pop %rax # 'X' add $0x8, %rsp ; so we dont overwrite the return pointer
pop %rax # 'X' add $0x8, %rsp ; so we dont overwrite the return pointer
prepare_ff: # "j0TYX45Pk13"
push $0x30 # 'j0'
push %rsp # 'T'
pop %rcx # 'Y' %rcx points to $0x30
pop %rax # 'X' %rax = 0x30
xor $0x35, %al # '45' %rax = 0x05
2。变种mov
如mov %rax,(m64),使用xor技巧(第二行为目的,上面加一行临时数据)
xor (m64),%rax
xor %rax,(m64)
这题暴露几个知识盲点,原来都看过,没有注意。
A.使用break在stack shellcode打断点,gdb会用int 3 (opcode 0xcc),替代指令,导致alpha判断时取到0xcc,觉得莫名其妙,后面用hbreak替代才没有这个问题。
B.stack上代码,不能用next/nexti调试,原因如上。
网友评论