2009-360网络攻防比赛整理

360网络攻防007比赛第1题

磁盘保护挑战题
这个题一共写了5种写法的可能有重复的写法,先说说自己简单理解MBRPROT是怎么保护的首先加载MBRPROT后他会找到磁盘真实设备对象+0x28 DeviceExtension应该是个_FDO_EXTENSION结构会改变这个结构的+0xC DeviceObject 为自己的设备对象这样系统在进行读写操作时就会一步步的进入IoStartPacket函数中调用DeviceObject->DriverObject->DriverStartIo( DeviceObject, Irp )调用了MBRPROT的DriverStartIo函数然后他在自己的DriverStartIo进行判断是否为写1扇区的进行拦截。
MBRPROT拦截的流程

我的第1中写法是HOOK了IoStartPacket( 因为在IoStartPacket中会调用DriverStartIo进行读写)把调用DriverStartIo都改成atapi的DriverStartIo这样就再进行读写时就不会进到MBROPR的DriverStartIo中了。

第2中写法是自己找到真实设备对象然后把他的DeviceExtension+0xC DeviceObject改为正确的设备对象这样也不会进到MBROPR的DriverStartIo中了。
1,2种方法可以使任何软件工具都可以正常写入1扇区的。

第3种写法是自己直接发SRB写操作给atapi的DriverStartIo这样也会绕过MBRPROT的保护这样就可以写1扇区了但问题也出现了:如果说MBRPROT有2重保护的话我理解的是第1层是保护用WINHEX等不能往1扇区写入东西,就是拦截1扇区的写入,第2层是在拦截1扇区的写入同时自己也会发IRP来使1扇区清零的,这样如果你绕过第1层保护成功的写入了1扇区那你再用WINHEX查看并试着用WINHEX随便往1扇区写点东西来试MBRPROT的保护是否开启的时候MBRPROT也会让你第1次成功的写入变为没有的,这样我们刚才给atapi的DriverStartIo发的写操作也会变为没有的我采用的方法是在给atapi的DriverStartIo发写操作后HOOK atapi的DriverStartIo 判断如果是往1扇区写入操作的话我把他的Srb->DataBuffer内容改成自己的东西 因为MBRPROT清0操作会经过这里的。

第4中写法其实好像就是Debugman有的牛人说的可以从应用层穿透的方法,我用的就是开个线程每秒向0扇区写1024个字节的前512是读入的MBR后面就是自己要写入的东西了,因为MBRPORT应该是这样判断的if(Srb->QueueSortKey==1 && ……. 所以写0扇区就可以正常绕过他了。

第5中写法是发SRB写操作给DISK看机器狗的代码就行了 正常情况下加载MBRPROT后如果直接向Disk发送SRB写1扇区的话是不成功的他可以拦截,我这里把CDB10字节的控制码改成6字节长度的或12字节的向Disk发送SRB写1扇区的就可以成功写入 我理解在MBRPROT里他是这么判断的
if( Srb->QueueSortKey==1 && Srb->Function == SRB_FUNCTION_EXECUTE_SCSI &&
Srb->CdbLength == 0xA && …..

这样改为6字节长度就可以绕过的

我想也可以在加载MBRPORT后HOOK IoStartPacket 判断如果是向1扇区写入的话都改成6字节长度。

上面的叙述可能有错误的大概就这样的自己调是最好的帮助最好的理解,其实有很多东西是自己知道就是写不出来不知道该怎么用文字表达出来的……. 上面说的方法代码找个能放代码的地方放出来的

360网络攻防007比赛第2题
网络过滤挑战题这个题一共写了3种写法先说说自己理解的网络访问时小图标是怎么闪烁的吧
在netshell模块里CNETStatisticsCentral时间回调函数会调用 CNetStatisticsCentral::RefreshStatistics 然后调用CNetStatisticsEngine::UpdateStatistics在UpdateStatistics中根据WAN或LAN进行判 断如果是WAN则调用RasStatEngin::HrUpdateData如果为LAN则CLanStatEngine::HrUpdateData
先放个流程图的

先说WAN的,在RasStatEngin::HrUpdateData调用RASAPI32!RasGetConnetionStatistics然后调用rasman!RasconnectionGetStatistics然后调用rasman里的SubmitRequest然后把请求放入队列里好像是svshot里发DeviceIoControlFile MajorIOCTL为0x0E IOCTL为120034 给NDISWAN的IRP_MJ_DEVICE_CONTROL 例程 但初始化的时候NDISWAN的IRP_MJ_DEVICE_CONTROL 例程初始为NDIS的NDIS!ndisDeviceControlIrpHandler这样自然就进入NDIS!ndisDeviceControlIrpHandler在这里然后调用ndisDummyIrpHandler然后又会调回NDISWAN里->ndiswan!NdisWanIoctl->ndiswan!ExecuteIo然后在根据控制码0x0D调用GetStatistics

360网络攻防007比赛第2题

LAN的情况在CLanStatEngine::HrUpdateData 里调用NdisQueryStatistics函数然后直接发DeviceIoControlFile MajorIOCTL为0x0E IOCTL为17003E在InBuffer里为想要获得的东西如:

747e7d3c 00010107 80010104 80010114 00020101
747e7d4c 00020102 00020103 00020104 80020208
747e7d5c 80020201 80020207 80ffffff 80020213
747e7d6c 80020214 80020215 80010202 ffffffff

表明需要

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#define OID_GEN_LINK_SPEED 0x00010107
#define OID_GEN_MEDIA_IN_USE 0x00010104
#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114
#define OID_GEN_XMIT_OK 0x00020101
#define OID_GEN_RCV_OK 0x00020102
#define OID_GEN_XMIT_ERROR 0x00020103
#define OID_GEN_RCV_ERROR 0x00020104
#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208
#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 发送字节数
#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 接收字节数
#define OID_GEN_INIT_TIME_MS 0x00020213
#define OID_GEN_RESET_COUNTS 0x00020214
#define OID_GEN_MEDIA_SENSE_COUNTS 0x00020215
#define OID_GEN_PHYSICAL_MEDIUM 0x00010202

这些东西的如果调用成功就会在OutBuffer里有这些的如

0145f86c 65799 4 10000000 -2147417852
0145f87c 4 0 -2147417836 4
0145f88c 0 131329 8 82
0145f89c 0 131330 8 57
0145f8ac 0 131331 4 0
0145f8bc 131332 4 0 -2147352056
0145f8cc 8 52 0 -2147352063
0145f8dc 8 0 0 -2147352057
0145f8ec 8 0 0 -2130706433
0145f8fc 4 0 -2147352045 4
0145f90c 78 -2147352044 4 0
0145f91c -2147352043 4 0 -2147417598

刚才说道NdisQueryStatistics函数直接发DeviceIoControlFile到了NDIS!ndisDeviceControlIrpHandler里然后调用ndisQueryStatisticsOids函数在 ndisQueryStatisticsOids函数中会多次根据InBuffer里的OIDGEN**调用ndisQueryDeviceOid然后在memmove ,在ndisQueryDeviceOid中调用->ndisQuerySetMiniport->ndisMDoRequests->ndisMDispatchRequest然后根据网卡设置的查询例程再调用

我的第1种方法是HOOK ZwDeviceIoControlFile 在 NewZwDeviceIoControlFile中判断IoControlCode进行拦截

第2种方法是HOOK NDIS的ndisDeviceControlIrpHandler进行判断IoControlCode进行拦截

第3种方法是根据LAN或WAN进行HOOK 如果是LAN HOOK 网卡设备的MiniportQueryInformation 例程 关于找网卡设备自己注册的查询例程我是这么找的:网卡Miniport 驱动在初始化时会调用 NdisMRegisterMiniport或NdisIMRegisterLayeredMiniport来注册例程的,通过查看NDIS的ndisRegisterMiniportDriver函数会为此驱动新分配DriverObjectExtension并把传进来的NDIS_MINIPORT_CHARACTERISTICS结构COPY到Driver Extension的ClientDriverExtension +0x20的地方供后面调用再+0x24正好偏移到Miniport驱动的MiniportQueryInformation例程,WAN则HOOK ndiswan的GetStatistics

360网络攻防007比赛第4题

PE文件挑战题 这个题我提交时太大意了要不就100分了………..

这个题我也不想怎么说的,先构造个没有导入表的PE 首先获得返回地址根据返回地址判断下是在R0还是在R3就是做为驱动还是做为EXE,DLL调用的,根据不同的调用找到不同模块的基址然后在获得DbgPrint,MessageBox的地址调用。

我提交时自己测试成功的,提交时把代码放到IDE里着急以为可以的了提交了结果驱动加载时不成功的,早知道就把用命令行编译的提交了怪自己着急没有试的 鄙视自己