来自TSec的分享,进行了尝试,成功搭建了一个进攻型的蜜罐
•掩蔽型 迷惑入侵者,保护服务器
•防护型 抵御入侵者,加固服务器
•进攻型 蜜罐收集信息分析
设置蜜罐,进行攻击预警,进行数据收集,要注意蜜罐的加固和隔离
蜜罐法律问题:监控蜜罐也要承担相应的法律后果,譬如说,有可能违反《反窃听法》。需要给每个蜜罐打上这样的标语:“使用该系统的任何人同意自己的行为受到监控,并透露给其他人,包括执法人员。”
•当入侵者进行恶意访问行为的时候,利用服务漏洞进行反射攻击
•本例为使用mysql的客户端攻击
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
Mysql Client Attack
这是mysql 5.7.1之前的漏洞,本来应该是客户端先申请上传文件,然后服务器端向客户端请求的 ,该命令用于实现服务器端从客户端上传文件
但这个请求我们可以伪造
实现一个伪造的mysql服务器 ,对连接用户进行文件申请
在公网上发布地址、用户名和密码
•将蜜罐披露在公网上一周
•主要为windows系统,有的是fuzz器
共655次来自53个ip的扫描
11台扫描主机判断为存在漏洞,均为windows系统,其中包含fuzz器
基于IDA Python的控制流图生成方案。
IDA Python生成的控制流图,其粒度大小与AFL识别的粒度大小基本相同。angr的粒度相比之下要小得多。因此angr所消耗的资源会更多,对于AFL插桩后的程序无法较好的完成控制流图 生成工作,因此尝试使用IDA Python进行控制流图的生成(AFL插桩后的程序大小竟然会扩到约10倍,有点恐怖)
IDA Python有三个库,其中提供一些API来提供一些功能
import idaapi
import idautils
import idc
使用IDA 打开程序后,按下Alt +F7选择脚本运行。
其实只要得到所有函数的F12的图的文件就可以了,那是WinGraph32的控制流图表示文件,用这个文件来得到控制流图会更简洁。。然后没找到批处理的方法。
所以就自己写了一个,处理跳转然后建立基本块间的可达关系然后得到控制流图。
def main():
start_time = time.time()
all_funcs = idautils.Functions()
GetDeclareFuncName()
ii=0;
for fn in all_funcs:
ii+=1
func_name = idc.GetFunctionName(fn)
fflags = idc.GetFunctionFlags(fn)
if func_name not in DeclareFuncName:
continue
#if func_name.find("main")!=0 or len(func_name)!=len("main"):
# continue
fout = open("out.txt", "a")
fout.write("FuncName: "+func_name +"\r\n")
fout.close()
DeclareFuncSit.append(blocknum)
f_blocks = idaapi.FlowChart(idaapi.get_func(fn), flags=idaapi.FC_PREDS)
for block in f_blocks:
dealblocks()
Tokyo Western的CTF,一道逆向题,队里没人做就给做了。
使用的是Z3求解器。。做完了和大佬说大佬推荐Sage。。下次再学。
solver.add(12==(flag[0]-96)*(flag[1]-96)*(flag[2]-96)*(flag[3]-96)*(flag[4]-96)*(flag[5]-96)
flag是32位的16机制字符串,这个比赛的flag都是这个样子。
程序中加了好多的的限制条件,如每个数字的出现次数、部分位置的加和结果、部分位置的异或结果等
使用Z3约束求解,由于是字符串所以使用了BitVec,(这么说难道用Int就可以进行正常的乘法运算了?,好像有点道理)
from z3 import *
flag = [BitVec('flag%d' % i,8) for i in range(32)]
solver = Solver()
ccc = [48,49,50,51,52,53,54,55,56,57,97,98,99,100,101,102]
mc = [0,1,3,8,11,12,15,18,20,21,26,30]
mi = []
f40 = [0x15e,0xda,0x12f,0x131,0x100,0x131,0xfb,0x102]
f60 = [0x52,0xc,0x1,0xf,0x5c,0x5,0x53,0x58]
f80 = [0x1,0x57,0x7,0xd,0xd,0x53,0x51,0x51]
fa0 = [0x129,0x103,0x12b,0x131,0x135,0x10b,0xff,0xff]
fnum = [3,2,2,0,3,2,1,3,3,1,1,3,1,2,2,3]
#54,57,97,99
mf40 = [BitVecVal(i,8) for i in f40]
mf60 = [BitVecVal(i,8) for i in f60]
mf80 = [BitVecVal(i,8) for i in f80]
mfa0 = [BitVecVal(i,8) for i in fa0]
mfnum = [BitVecVal(i,8) for i in fnum]
mccc = [BitVecVal(i,8) for i in ccc]
xx = 1
for i in range(11,16):
for k in range(fnum[i]):
xx*=ccc[i]
xx/=102
print xx
print 97*98*98*98*99*100*100*101*101*102*102
print 97+98+98+98+99+100+100+101+101+102+102
print 48*3+49*2+50+52*2+53+54*1+55*2+56*2+57
solver.add(flag[31]==53)
solver.add(flag[1]==102)
solver.add(flag[5]==56)
solver.add(flag[6]==55)
solver.add(flag[17]==50)
solver.add(flag[25]==52)
for i in range(32):
solver.add(flag[i]!=51)
if i in mc:
solver.add(flag[i]<=102)
solver.add(flag[i]>=97)
else:
solver.add(flag[i]<=57)
solver.add(flag[i]>=48)
for k in range(0,7):
solver.add(mf40[k]==flag[4 * k + 0]+flag[4 * k + 1]+flag[4 * k + 2]+flag[4 * k + 3])
solver.add(mf60[k]==flag[4 * k + 0]^flag[4 * k + 1]^flag[4 * k + 2]^flag[4 * k + 3])
#solver.add(v11 == f60[k])
for k in range(0,7):
solver.add(mfa0[k]==flag[k + 0]+flag[k + 8]+flag[k + 16]+flag[k+24])
solver.add(mf80[k]==flag[k + 0]^flag[k + 8]^flag[k + 16]^flag[k+24])
m1096 = BitVecVal(1096,8)
m782 = BitVecVal(782,8)
m1160 = BitVecVal(1160,8)
m96 = BitVecVal(96,8)
solver.add(m1096==flag[0]+flag[3]+flag[8]+flag[11]+flag[12]+flag[15]+flag[18]+flag[20]+flag[21]+flag[26]+flag[30])
solver.add(m782==flag[2]+flag[4]+flag[7]+flag[9]+flag[10]+flag[13]+flag[14]+flag[16]+flag[19]+flag[22]+flag[23]+flag[24]+flag[27]+flag[28]+flag[29])
solver.add(m96==(flag[8]-97)*(flag[11]-97)*(flag[12]-97)*(flag[15]-97)*(flag[26]-97)*(flag[20]-97))
#1,5,6,17,25,31
#solver.add(flag[0]==100)
#solver.add(flag[3]==98)
#solver.add(flag[21]!=102)
#solver.add(flag[30]!=97)
#solver.add(flag[18]!=102)
solver.add()
#solver.add(flag[2]==50)
solver.add(m1160==flag[0]+flag[2]+flag[4]+flag[6]+flag[8]+flag[10]+flag[12]+flag[14]+flag[16]+flag[18]+flag[20]+flag[22]+flag[24]+flag[26]+flag[28]+flag[30])
if solver.check() == sat:
m = solver.model()
s = []
char =""
for i in range(32):
s.append(m[flag[i]].as_long())
char+=chr(m[flag[i]].as_long())
print s
print char
#print(bytes(s))
else:
print('unsat')
ctf比赛中的Windwos Pwn题目愈发的多了,学一波
杂乱的Windwos相关知识
Windwos有三种调用方式,待续
如何将值放入xmm的方式,待续
下面是参考资料1中的描述
1 前四个整型或指针类型参数由RCX,RDX,R8,R9依次传递,前四个浮点类型参数由XMM0,XMM1,XMM2,XMM3依次传递。
2 调用函数为前四个参数在调用栈上保留相应的空间,称作shadow space或spill slot。即使被调用方没有或小于4个参数,调用函数仍然保留那么多的栈空间,这有助于在某些特殊情况下简化调用约定。
3 除前四个参数以外的任何其他参数通过栈来传递,从右至左依次入栈。
4 由调用函数负责清理调用栈。
5 小于等于64位的整型或指针类型返回值由RAX传递。
6 浮点返回值由XMM0传递。
7 更大的返回值(比如结构体),由调用方在栈上分配空间,并有RCX持有该空间的指针并传递给被调用函数,因此整型参数使用的寄存器依次右移一格,实际只可以利用3个寄存器,其余参数入栈。函数调用结束后,RAX返回该空间的指针。
8 除RCX,RDX,R8,R9以外,RAX、R10、R11、XMM4 和 XMM5也是易变化的(volatile)寄存器。
9 RBX, RBP, RDI, RSI, R12, R14, R14, and R15寄存器则必须在使用时进行保护。
10 在寄存器中,所有参数都是右对齐的。小于64位的参数并不进行高位零扩展,也就是高位是无法预测的垃圾数据。
1 当类继承了父类(父类含有虚函数),或者类中本来就有虚函数,那么编译之后就会产生虚表。
2 若A、B继承了父类C,那么在rdata段中将会有连续的空间存放A继承C的虚函数指针、B继承C的虚函数指针
3 实例化A或B时,将会在栈空间,则地址的首部放置指向虚表的指针,紧接着是各个局部变量;若是new()创建,则是堆空间,这时局部变量放置到栈空间,malloc的变量放置到堆空间。
参考另一篇文章请https://ble55ing.github.io/2019/08/18/WindowsPwn0/
https://introspelliam.github.io/2017/08/05/pwn/XMAN%E4%B9%8B%E6%97%85-windows-exploit-technique/
古老的Windows题,希望容易一点。
32位PE文件,可以申请20个节点,在0x4053fb的位置是Memory,记录着每个节点的各项内容的指针。
在0x5448位置有一个守卫变量,不为0的时候就没法执行shellcode。
功能有add,list,delete,run,set guard和exit。list可以得到node的信息。
主函数有栈溢出但是exit所以过。
本题中使用的是allocsc进行内存分配(分配的内存都是连着的没有堆头啥的)
如图为每次一个A然后最后是3次got表地址
接下来看allocsc的实现
int __cdecl allocsc(int size)
{
int v1; // edx@1
int result; // eax@2
v1 = size + NEXT; // int overflow
if ( size + NEXT < (unsigned int)(HEAP + HEAP_SIZE) )
{
NEXT += size;
result = v1 - size;
}
else
{
result = -1;
}
return result;
}
这里的size+NEXT是存在整数溢出的,为负数时总能通过校验。
使用这个allocsc的漏洞,将内存分配到Memory处,就是申请一个足够大的内存,将堆的接下来分配到note的起始处,然后再分配就可以改掉note中指针的值。然后可以用list函数去泄露内容,得到got表中的值,进而计算出配套dll中get_shell代码的位置。然后再分配一个较大的空间,去覆盖掉0x5448位置的守卫,就可以用run去运行get_shell了!!
每个HEAP有一个HEAP结构,一个heap结构有多个heap_segment
heap结构在每个堆的起始地址,由每个堆的0号堆段和自己的结构拼接而成,由图可见堆段大小为0x40,前0x40字节属于0号堆段。 0x40之后的heap结构用来保存堆的资产及必要信息。
+0x040 Flags : 2
+0x044 ForceFlags : 0
+0x048 CompatibilityFlags : 0
+0x04c EncodeFlagMask : 0x100000
+0x050 Encoding : _HEAP_ENTRY
+0x058 Interceptor : 0
+0x05c VirtualMemoryThreshold : 0xfe00
+0x060 Signature : 0xeeffeeff
+0x064 SegmentReserve : 0x1fd0000
+0x068 SegmentCommit : 0x2000
+0x06c DeCommitFreeBlockThreshold : 0x800
+0x070 DeCommitTotalFreeThreshold : 0x2000
+0x074 TotalFreeSize : 0x3c440
+0x078 MaximumAllocationSize : 0xfffdefff
+0x07c ProcessHeapsListIndex : 1
+0x07e HeaderValidateLength : 0x248
+0x080 HeaderValidateCopy : (null)
+0x084 NextAvailableTagIndex : 0
+0x086 MaximumTagIndex : 0
+0x088 TagEntries : (null)
+0x08c UCRList : _LIST_ENTRY [ 0x5a4ffe8 - 0x5a4ffe8 ]
+0x094 AlignRound : 0xf
+0x098 AlignMask : 0xfffffff8
+0x09c VirtualAllocdBlocks : _LIST_ENTRY [ 0x71009c - 0x71009c ]
+0x0a4 SegmentList : _LIST_ENTRY [ 0x710010 - 0x5760010 ]
+0x0ac AllocatorBackTraceIndex : 0
+0x0b0 NonDedicatedListLength : 0
+0x0b4 BlocksIndex : 0x00710260 Void
+0x0b8 UCRIndex : (null)
+0x0bc PseudoTagEntries : (null)
+0x0c0 FreeLists : _LIST_ENTRY [ 0x3c2b140 - 0x59ed748 ]
+0x0c8 LockVariable : 0x00710248 _HEAP_LOCK
+0x0cc CommitRoutine : 0x1bb2ba92 long +1bb2ba92
+0x0d0 StackTraceInitVar : _RTL_RUN_ONCE
+0x0d4 FrontEndHeap : 0x00150000 Void
+0x0d8 FrontHeapLockCount : 0
+0x0da FrontEndHeapType : 0x2 ‘’
+0x0db RequestedFrontEndHeapType : 0x2 ‘’
+0x0dc FrontEndHeapUsageData : 0x007161b0 -> 0
+0x0e0 FrontEndHeapMaximumIndex : 0x802
+0x0e2 FrontEndHeapStatusBitmap : [257] “???”
+0x1e4 Counters : _HEAP_COUNTERS
+0x240 TuningParameters : _HEAP_TUNING_PARAMETERS
+0x040 Flags 堆的flag由heapcreate时的flag参数控制,其中HEAP_GROWABLE(0x2)属性是默认的。且私有堆的flag要 or 0x1000.
创建时参数为4,flag为 2or 4 or 0x1000=0x1006
+0x050为之后解密HEAP_ENTRY头部的密钥
+0x060 Signature : 0xeeffeeff heap结构头签名
+0x078 MaximumAllocationSize 允许分配的最大空间,由于heapcreate时参数选择了0,这里允许分配整个地址空间大小。
+0x07c heap在peb堆数组中的索引
+0x074 TotalFreeSize : 0x3c440 全部free堆块的总大小。
+0x07e HeaderValidateLength heap结构头的大小
+0x0a4 SegmentList 堆段的链表,前向指针指向0号堆段,后向指针指向最后一个堆段。
+0x0c0 FreeLists 保存整个堆的空闲堆块,所有堆块的空闲堆块的集合