利用反射转换对象list到csv

扒自一工程。。可以学习一下.net中反射的简单用法 /// <summary> /// Take object List as input and export to csv which will be prompt save as dialog /// </summary> /// <typeparam name="T"> Type of object</typeparam> /// <param name="listToExport"> Object list to export</param> /// <param name="seperateChar"> character to use as scv separator</param> public static string ExportListToCSV<T>( List<T> listToExport, string seperateChar) { Int32 success = 0; StringBuilder export = new StringBuilder(); try { string seperator = "" ; StringBuilder builder = new StringBuilder(); //获取表头的 PropertyInfo[] fieldInfo = listToExport[0].GetType().GetProperties(); foreach (PropertyInfo col in fieldInfo) { if (!col.PropertyType.FullName.Equals("System.Data.EntityKey") && !col.PropertyType.FullName.Equals("System.Data.EntityState" )) { builder.Append(seperator).Append(col.Name); seperator = seperateChar; } } export.AppendLine(builder.ToString()); foreach (T dataItem in listToExport) { PropertyInfo[] allProperties = dataItem.GetType().GetProperties(); seperator = ""; StringBuilder builderTmp = new StringBuilder(); //真正求数据域的 foreach (PropertyInfo thisProperty in allProperties) { if (!thisProperty.PropertyType.FullName.Equals("System.Data.EntityKey") && !thisProperty.PropertyType.FullName.Equals("System.Data.EntityState" )) { object value = thisProperty.GetValue(dataItem, null); String propetyValue = (value == null ? String.Empty : value.ToString()); builderTmp.Append(seperator).Append(propetyValue); seperator = seperateChar; } } ++success; export.AppendLine(builderTmp.ToString()); } } catch (Exception ex) { throw ex; } return export.ToString(); } if (!thisProperty.PropertyType.FullName.Equals("System.Data.EntityKey") && !thisProperty.PropertyType.FullName.Equals("System.Data.EntityState")) ...

2013-02-02 · 1 min · bystander

操作系统的死锁和内存管理

这部分是最后一部分笔记。《现代操作系统》第三版的笔记就这样了。 死锁; 把需要排他性使用的对象称为资源,资源分为可抢占的和不可抢占的。可抢占资源可以从拥有它的进程中抢占而不会具有任何副作用。存储器就是可抢占的。不可抢占资源是指在不引起相关的计算失败的情况下,无法把它从占有她的进程处抢占过来。比如CD刻录机,如果一个进程开始刻盘,突然分配给CD刻录机到另一进程,就会划坏CD盘。死锁会发生在不可抢占资源中 死锁的规范定义:如果一个进程集合中的每个进程都在等待只能由该进程集合中的其他进程才能引发的事件,那么,该进程集合就是死锁的。 死锁的四个必要条件 1.互斥条件。每个资源要么已经分配给一个进程,要么就是可用的。 2.占有和等待条件,已经得到了某个资源的进程可以再请求新的资源。 3.不可抢占条件,已经分配给一个进程的资源不可强制性的被抢占,他只能由占有她的进程显式的释放。 4.环路等待条件。死锁发生时,系统中一定有友两个/多个进程组成的一条回路,该环路中的每个进程都在等待着下一个进程所占有的资源。 死锁处理的四种策略 1.忽略该问题,如果可以忽略。则忽略 2.检测死锁并恢复,让死锁发生,检测他们是否发生,一旦发生。采取行动。 3.仔细对资源进行分配。动态的避免死锁。 4.通过破坏引起的四个必要条件之一。防止死锁发生。 银行家算法就是对每个请求进行检查。检查如果满足这一请求是否会达到安全状态,或是,那么满足这请求,若否。就推迟这一请求的满足。为了看状态是否安全。类似于银行家投资。看自己是否有足够的资源满足客户。如果可以。就认为投资是可以收回的。接着检查最接近最大限额的一个客户。如果所有投资最终都被收回。则该状态安全。 通信死锁:两个/以上的进程发送消息通信。A向B发送请求信息,然后阻塞直到B回复。假设请求信息丢失,A将阻塞等待回复。B则阻塞等待一个向其发送命令的请求。则发生死锁。他不能通过对资源排序/安排调度来避免,因此。采用了超时来中断通信死锁。 活锁:两个进程A和B,A获得1.B获得2.轮询请求对方的。没有进程被阻塞。看起来像是死锁发生了。就叫做活锁。 内存管理 每个linux进程都有一个地址空间,逻辑上有三段组成:代码。数据和堆栈段。代码段包含了形成程序可执行代码的机器指令。通常是只读的。是由编译器把源码转换成机器码形成的。 数据段包含了所有程序变量。字符串。数字和其他数据的存储。由两部分,初始化数据和未初始化数据。后者即为BSS,符号起始块。加载后被初始化为0.数据段可以修改。可以增加数据段的大小。 第三段是栈段。大多数机器里。从虚拟地址空间的顶部/附近开始。并且向下生长。 linux内存由三部分组成。前两部分是内核和内存映射,被钉在内存中。页面从不换粗。内存的其他部分,被划分为页框。每个页框都可以包含一个代码。数据或栈页面。 window如何知道系统配置的细节呢。答案就是windows会挂载一种特殊的文件系统,其为小文件做了优化,到名字空间,也就是注册表。注册表被阻止成了不同的卷,称作储巢。hive。一个叫做system的储巢会在系统启动时。装入内存。这里面包含了驱动什么设备工作。什么软件要初始化。那些变量等等。

2013-02-02 · 1 min · bystander

操作系统中的输入输出

输入输出 I/O硬件: I/O设备分为两类:块设备和字符设备,块设备吧信息存储在固定大小的块中,每个块有自己的地址,传输以块为单位,每个块都能独立于其他块读写,硬盘,CD-ROM和USB盘都是常见的块设备。字符设备是以字符为单位发送和接收一个字符流,而不考虑任何块结构,字符设备不可寻址,也不寻道,打印机,网络几口,鼠标,以及大多数与磁盘不同的设备都可看作是字符设备。 I/O设备一般由机械部件和电子部件两部分组成,通常分开处理,实现模块化和通用设计,电子部件称作设备控制器/适配器,在个人计算机上,通常以主板上的芯片的形式出现,或者以插入PCI的印刷电路板的形式出现。控制器卡上通常有一个连接器,通向设备本身的电缆可以插入到这个连接器中, 控制器的任务是吧串行的位流转换成字节块,并进行必要的错误校正工作,字节块通常首先在控制器内部的一个缓冲区中按位进行组装,然后再对校验和进行校验并证明字节块没有错误后再将它复制到主存中。 每个控制器都有几个寄存器用来和cpu通信,通过写入这些寄存器,操作系统可以命令设备发送数据等等操作。 1.内存映射io 将所有控制寄存器映射到内存空间中,每个寄存器被分配一个唯一的内存地址,并且不会有内存被分配这一地址,这样的系统称为内存映射I/O,通常位于地址空间的顶端。使用内存映射io,设备控制器只是内存中的变量,c语言可以和其他变量一样寻址,这样,I/O设备驱动程序就可以采用c语言编写。 2.DMA 无论CPU是否具有内存映射I/O,他都需要寻址设备控制器以便和他们交换数据,但浪费eficpu时间,所以经常使用直接存储器存储。可独立于cpu访问地址总线。 没有DMA的时候,首先控制器从磁盘驱动器串行的一位一位的读一个块,直到将整块信息放入控制器的内存缓冲区中,接着,他计算校验和,以保证没有读错误发生,然后控制器产生一个中断,当操作系统开始运行时,它重复地从控制器的缓冲区中一次一个字节/一个字的读取该块的信息,并将其放入内存中。 当有DMA的时候,首先CPU通过设置DMA控制器的寄存器对它进行编程,所以DMA控制器知道将什么数据传送到什么地方,(第1步)DMA控制器还要向磁盘控制器发送一个命令,通知他从磁盘读数据到其内部的缓冲区中,并且对校验和进行检验,如果磁盘控制器中的缓冲区中的数据是有效的的。那么DMA开始 DMA控制器通过在总线上发出一个读请求到磁盘控制器而发起DMA传送(第2步),这一读请求和其他一样,并且磁盘控制器并不关心是来自DMA还是CPU,一般情况下,要写的内存地址在总线的地址线上,所以磁盘控制器从内部缓冲区中读取下一个字的时候,她知道要写的什么地方,写到内存是另一个标准总线周期,(第3步) 当写操作完成时,磁盘控制器在总线上发起一个应答信号到DMA(第4步),于是DMA控制器部增要使用的内存地址,并且步减字节计数,如果字节计数仍然大于0,则从父2-4步。完成后产生中断告诉cpu,操作系统开始工作时,数据已经在内存中了。 中断: 将机器留在一个明确状态的中断称为精确中断,四个特征,1.PC保存在一个已知的地方。2.PC所指向的指令之前的所有指令都已经完全执行。3.PC所指向的指令之后的所有指令都没有执行。4.PC所指向的指令的执行状态是已知的。注意,对于PC所指向的指令以后的指令,并没有禁止他们开始执行,而只是要求在中断发生之前必须撤销他们对寄存器或内存所做的任何修改。 I/O软件: 设计I/O软件时一个关键的点就是设备独立性,意思是我们可以访问任意I/O设备而无需事先指定设备。也就是对于不同的I/O硬件。同一段程序是可以的。 具有标准接口的驱动程序的工作方式如下:对于每一种设备类型,例如磁盘和打印机。操作系统定义一组驱动程序必须支持的函数,对于磁盘而言,这些函数自然的包含读和写,除此之外还包含开启和关闭电源,格式化以及其他与磁盘有关的事情。驱动程序通常包含一张表格,这张表格具有针对这些函数指向驱动程序自身的指针。当驱动程序装载时,操作系统记录下这张函数指针表的地址。所以当操作系统需要调用一个函数时,可以通过表格发出间接调用。这张函数指针表定义了驱动程序与操作系统其他部分之间的接口。 **双缓冲:**当第二个缓冲区正在复制用户空间的时候,第一个缓冲区用来接收新的字符。以这样的方法。两个缓冲区轮流使用。称为双缓冲。 磁盘臂调度算法: 读/写一个磁盘块需要时间:1.寻道时间(将磁盘臂移动到适当的柱面上所需的时间)2.旋转延迟(等待适当扇区旋转到磁头下所需的时间)。3.实际数据传输时间。 一个磁盘子系统具有如下特性:当一个写命令发给它时,磁盘要么正确地写数据,要么什么也不做,让现有的数据完整无缺的留下,这样的系统称为稳定存储器,并且是在软件中实现的。目标是不惜一切代价保持磁盘的一致性。 **时钟:**两种。1种是直接接到电源线上。就可以每个电压周期产生一个终端。现在比较少。另一种是由晶体振荡器,计数器和存储寄存器三个构成。当把一块石英晶体适当的切割并且安装到一定的压力之下时就可以产生非常精确的周期性信号。时钟启动时,存储寄存器的值被复制到计数器中,每一个脉冲使计数器-1,直到为0,产生中断。

2013-02-01 · 1 min · bystander

操作系统中的文件系统

文件系统 进程,地址空间,文件这些抽象概念均是操作系统中的重要概念,如果理解了这三个概念,就迈上了成为一个操作系统专家的道路。 文件系统存放在磁盘上,多数磁盘划分为一个/多个分区,每个分区有一个独立的文件系统,磁盘的0号扇区称为主引导记录,也就是MBR,用来引导计算机,MBR的结尾就是分区表了。该表给出了每个分区的起始和结束地址。表中的一个分区被标记为活动分区。在计算机被引导时,BIOS读入并执行MBR,MBR做的第一件事就是确定活动分区,读入他的第一个块,称为引导块,并执行之,引导块中的程度将装载该分区中的操作系统,为统一起见,每个分区都从一个启动块开始,即使它不含有一个可以启动的操作系统。 文件的实现: 1.连续分配,每个文件作为一连串连续数据存储在磁盘上。实现简单,读操作性能好,一次就可以了。但不足是删除之后不能移动,因为成本太高,使得空块增多。碎片化严重。更诡异的是对于文件编辑软件,实现无法准确预测大小,如果预测错了。。就跪了。 //研究那些具有清晰和简洁概念的老式系统和思想是很重要的,因为他们可能以一种令人吃惊的方式在未来系统中获得应用。 2.链表分配 为每个文件构造磁盘块链表,一个文件分为N个文件块,N个文件块构成一个链表,存储在物理上的多个地方。顺序读取很方便,但随机读取则相当缓慢,由于指针的存在,每个磁盘块存储数据的字节不再是2的整数次幂,导致系统运行效率降低,因为很多程序都是以2的整数次幂来读写磁盘的。 3.在内存中采用表的链表分配 去除每个文件块在磁盘上的指针字,放入内存的一个表上,就可以解决上一个分配的不足。直观的例子如图。 文件A使用了磁盘块4,7,2,10,12 内存中这样的表格称为文件分配表,也就是FAT了。主要缺点是对于大磁盘的小块,这种表需要的内存占用太大。。不太适用。 4.i节点 记录各个文件包含哪些磁盘块的方法是给每个文件赋予一个称为i节点的数据结构,其中类除了文件属性和文件块的磁盘地址.相对于在内存中采用表的方式,这种机制的优势在于只有对应文件打开时,其i节点才进入内存. 文件系统的一致性检查分为两种:块的一致性检查和文件的一致性检查.构造两张表,一张跟踪块在文件中的出现次数,另一张跟踪该块在空闲表中的出现次数,如果一致,则某一块必然在两个表中1/2中为1,如果某一块没有出现在任何一张表中,则称为块丢失,浪费了磁盘空间.解决方法是让文件系统检验程序把他们加入到空闲表中 如果在空闲表中出现了两次.则重新建议建议空闲表即可. 如果在文件表中出现了两次.则比较麻烦. 文件系统性能 1.高速缓存,最常用,指的是一系列的块,逻辑上属于磁盘.但实际上被保存在内存上.基本算法是检查全部的读请求,查看在高速缓存中是否有所需要的块,如果存在,就读,否则读入高速缓存在复制到其他地方. 2.块提前读,在需要用到块之前,试图提前将其写入高速缓存,从而提高命中率.比如某个文件有n个块,则请求k块的时候,则同时预读k+1块.只适用于顺序读取的文件,对随机读取文件,则没有效果/反效果. 3.减少磁盘臂运动 把所有可能顺序读取的块放在一起,当然最好是放在同一个柱面上,从而减少磁盘臂的移动次数.

2013-01-31 · 1 min · bystander

操作系统中的页面置换算法

最近读完了《现代操作系统》。页面置换算法的读书笔记。其他的笔记慢慢整理一下在博客做个备份。 虚拟内存的基本思想:每个程序都拥有自己的内存空间,这个空间被分割成很多块,每一块称为一页/页面,每一页有连续的地址范围,这些页被映射到物理内。 页面置换算法 1.最优页面置换算法,每个页面都可以用在该页面首次被访问前所需要执行的指令数作为标记。因此我们选择标记最大的页面,也就是把不愉快的事情往后拖延。但是,唯一的问题是无法实现。 2.最近未使用页面置换算法。系统每一个页面设置两个状态位,当页面被访问时设置R位,当被修改时设置M位,包含在页表项中,初始时,都被设置0,R被定期地清零,以区别最近没有被访问和被访问的页面。NRU算法随机的从类编号最小的非空类中挑选一个页面淘汰之, 根据R和W可以将页面分为4类 0没有被访问,没有被修改/1没有被访问,被修改/2已被访问,没有被修改/3已被访问,已被修改。第一类只有在定期清R的时候才会出现。 隐含的意思是,淘汰一个没有被访问的已修改页面要比淘汰一个被频繁使用的干净页面要好。 3.先进先出置换,找出最先进入的替换掉,很少单独使用 4.第二次机会页面置换算法。FIFO可能将经常使用的页面置换出来。为此,检查最老页面的r位,如果R为0,则既老又没有被使用,则就置换掉,如果是1,就清0,放在链表尾,修改装入时间为最新。继续搜索。 5.时钟页面置换算法,第二次机会算法经常要在链表中移动页面,更好的方法是将页面保存在一个类似钟面的环形链表中,表针指向最老的页面。发生缺页时,如果R是0就 淘汰该页面,并插入新页面,然后表针前移,如果是1,就清除R并前移,直到找到一个R位为0的页面。这也是时钟的由来 [![](/images/e198f5889716b00f06a452789f0c413474927e87.jpg)](http://leaverimage.b0.upaiyun.com/32235_o.jpg) 6.最近最少使用页面置换算法。在发生缺页时,置换未使用时间最长的页面,这个策略称为LRU,最简单的一个实现策略是有一个64位计数器,每条指令执行完加1.每个页表项必须有一个足够容纳这个计数器值的域,每次访问内存后,将C值保存到被访问页面的页表项,一旦中断,检查所有页面项的计数器值,找到最小的即可。 7.NFU最不常用算法,是LRU的软件模拟实现。每个页面与一个软件计数器管理。初值为0,每次时钟中断时,操作系统扫描内存中的所有页面,将每个页面中的R位值加到他的计数器上,计数器的值即为访问的频繁程度。该算法的问题是记住的事情太多,如果第一次执行扫描的时间最长。比如第一次某个页面的值很大。这个很大的值会影响到下一次扫描,结果操作系统将置换有用的页面而不是不再使用的页面。 8.修改一下NFU:R位被加进之前,将计数器右移一位,同时将R加到计数器的左端。即为老化算法 9.工作集页面置换算法。一个进程当前正在使用的页面的集合称作他的工作集。基本思路是找出一个不在工作集中的页面并淘汰它。 10.工作集时钟页面置换算法。基于时钟算法,并且使用了工作集信息。 页面调度算法总结; 最好的两种算法是老化算法和工作集时钟算法,分别基于LRU和工作集。具有良好的页面调度性能。

2013-01-30 · 1 min · bystander

现代操作系统的调度

这几天在读《现代操作系统》,想起当时学这门课的时候,并没有感觉那么爽,现在通读这本书,知识的过渡性和结构性令我叹服。感受操作系统的魅力吧。 批处理系统中的调度: 1.先来先服务 2.最短作业优先 只有在所有的作业都可以同时运行(也即同时到达)的情况下,最短作业优先算法才是最优化的。 3.最短剩余时间优先-最短作业优先的抢占式版本。调度算法总是选择剩余时间最短的那个进程运行,注意,运行时间必须提前掌握,当一个新的作业到达时,其整个时间同当前进程的剩余时间做比较,如果更少。就运行新进程。可以使新的短作业获得良好的服务。 交互式系统的调度 1.轮转调度。 最古老,最简单,最公平切使用最广,每个进程被分配一个时间片。如果进程在时间片结束之前阻塞或结束,则CPU立即切换。调度程序只是维护一张可运行进程列表,当进程用完它的时间片后,就被移到队列的末尾。时间片太短会导致进程切换过多,降低CPU效率,设置的太长又引起对短的交互请求的响应时间变长。通常20-50ms算合理。 2.优先级调度 为了防止高优先级进程无休止的运行下去,可以在一个时钟中断里降低当前进程的优先级,如果这导致该进程的优先级低于次高优先级的进程,则切换或者也可以赋予每个进程一个时间片。可以和轮转调度一起工作,设置每个优先级上有多个进程。优先运行高优先级,并未高优先级上的进程按照轮转换着运行,如果高优先级没了。就进入到较低优先级。。。问题是如果不偶尔对优先级进行调整,则可能发生饥饿现象。 3.多级队列 CTSS的设计者发现为CPU密集型进程设置较长的时间片比频繁的分给他们很短的时间片更为高效(减少了交换次数),但长时间的进程又会影响响应时间,方法是设立优先级类,最高优先级类里的进程运行1个时间片。次高运行2个。以此类推。当一个进程用完分配的时间片后,被移动到下一类。大致算法都是用于讨好交互用户和进程,而不惜牺牲后台进程 //故事:可以采用只要终端上有Enter键按下,就将该终端上的进程移到最高优先级类。假设当前进程急需交互,但是。一个人发现了。大家都开始用。。。理论和实际差异太大。。哈哈 4.最短进程优先 这个很好立即,但难点在于如何找出最短的那个。一种方法是根据过去的行为推测。假设每个命令执行时间为T0,下一次运行时间为T1,则可以根据aT0+(1-a)T1来估计时间。。a被用来决定尽快忘掉老的运行时间还是记住它。这种算法成为老化算法。通常选a=1/2 5.保证调度 就是保证每个用户获得cpu的1/n,系统需要跟踪进程的cpu时间,他实际获得如果多于应该获得的。则转向实际获得小于应该获得的。 6.彩票调度 保证调度很难实现,而彩票调度算法是向进程提供各种系统资源的彩票。一旦需要做出一项调度决策时,就随机抽出一张彩票。谁获得谁就上。比如视频服务器,可以为不同的帧速率提供不同的彩票。然后分配cpu 7.公平分享调度 这个就考虑到了进程的所有者。需要我们定义公平的含义。是保证每个用户只占用的时间相等还是其他了。 实时系统的调度: 可以分为硬实时和软实时,前者必须满足绝对的截止时间,后者则可以容忍一些。用户级线程系统是不知道的。用户级和内核级的差异主要在性能,用户级需少量的机器指令,而内核级需要很多的。过程。采用轮转和优先级调度更常见一些。 //操作系统的大神们太强大了。哲学家进餐问题居然可以通过拿起左边叉子以后,检测右边是否可用,如果不可用,则等待一个随机的时间。这种方案是可行的。在极少的情况下不可用。。

2013-01-24 · 1 min · bystander

社工字典生成工具

在家无聊写了这个工具,主要是为了防止自己这一直写随笔把本行忘了。。也熟悉一下代码。。暂时不放源代码了。以后改的好一点再发吧。 作者:bystander 博客:http://leaver.me 转载请注明出处! 涉及到的东西有: 1.C#隐藏TabControl的header部分,前面的文章有介绍 2.获取窗体全部的某一类控件(这个无聊的话抽象出一个通用的方法出来,以后就可以直接用了) /// <summary> /// 获取所有的文本框控件 /// </summary> /// <param name="control"></param> /// <returns></returns> private List<TextBox> GetAllControls(Control control) { foreach (Control con in control.Controls) { if (con.Controls.Count > 0) { GetAllControls(con); } else if (con is TextBox) { tBoxList.Add(con as TextBox); } } return tBoxList; } 3.文件操作 4.字符串操作 反正很简单,主要就是写的时候思路要清晰。知道大部分使用密码的规则。处理一下生日格式。否则后面很麻烦。。相应的验证也比较少。界面依然毫无美感。。 总结: 现在发现在控件命名上越来越顺利了。自我感觉良好。后面慢慢的要开始尝试使用学到的一些新的技术点。。 下载:社工字典生成工具

2013-01-21 · 1 min · bystander

C#隐藏TabControl标签栏

今天考过了微软的那个70-562和70-536的考试。然后下午把软件体系结构的作业做了。然后看了一下栈溢出,我博客首页右侧的那个就是我的栈溢出id了。。 然后就看到了这个问题。这个问题。我曾经遇到过。貌似大家知道比较多的是两种。第一种就是设置大小。 tabControl1.SizeMode = TabSizeMode.Fixed; tabControl1.ItemSize = new Size(0, 1); 但是这样你注意看的话,左上角有个小的瑕疵。这个没办法的。。还有一种比较低级但还算有效的方法就是在设计的时候将TabControl向上移动。运行以后就会遮住了。 我当时不过取巧了。好像就用的第二种。。今天看到这个题目的时候,就做了下标记。刚才去看。大牛已经给出答案了。就是自己继承一个TabControl控件。重写 void WndProc(ref Message m) 方法,在方法里拦截系统消息。 using System; using System.Windows.Forms; class TablessControl : TabControl { protected override void WndProc(ref Message m) { // Hide tabs by trapping the TCM_ADJUSTRECT message if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1; else base.WndProc(ref m); } } 具体用法。就是在你的项目里新建一个类文件。然后把上面的代码拷进去。然后编译一下。就会在工具箱里多出一个TablessControl控件。拖进来即可使用。当然你也可以自定义一个用户控件。都不是事。这个控件设计时标签页可见。运行时由于拦截了信息消息。标签栏就不可见了。堪称完美。。

2013-01-11 · 1 min · bystander

SQL注入中的WAF绕过技术

作者:bystander 博客:http://leaver.me 论坛:法克论坛 目录 1.大小写绕过 2.简单编码绕过 3.注释绕过 4.分隔重写绕过 5.Http参数污染(HPP) 6.使用逻辑运算符 or /and绕过 7.比较操作符替换 8.同功能函数替换 9.盲注无需or和and 10.加括号 11.缓冲区溢出绕过 1. 大小写绕过 这个大家都很熟悉,对于一些太垃圾的WAF效果显著,比如拦截了union,那就使用Union UnIoN等等。绕过 2. 简单编码绕过 比如WAF检测关键字,那么我们让他检测不到就可以了。比如检测union,那么我们就用%55 也就是U的16进制编码来代替U, union写成 %55nION,结合大小写也可以绕过一些WAF,你可以随意替换一个或几个都可以。。 也还有大家在Mysql注入中比如表名或是load文件的时候,会把文件名或是表明用16进制编码来绕过WAF都是属于这类。 3. 注释绕过 这种情况比较少,适用于WAF只是过滤了一次危险的语句,而没有阻断我们的整个查询 > /?id=1+union+select+1,2,3/* 比如对于上面这条查询,WAF过滤了一次union和select,那么我们在之前在写一个注释的语句,让他把注释里面的过滤掉,,并不影响我们的查询。。 所以绕过语句就是: > /?id=1/*union*/union/*select*/select+1,2,3/* 还有一种和注释有关的绕过: 比如 > index.php?page_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3,4…. 可以看到,只要我们把敏感词放到注释里面,注意,前面要加一个! 4. 分隔重写绕过 还是上面的例子,适用于那种WAF采用了正则表达式的情况,会检测所有的敏感字,而不在乎你写在哪里,有几个就过滤几个。。 我们可以通过注释分开敏感字,这样WAF的正则不起作用了,而带入查询的时候并不影响我们的结果 > /?id=1+un/**/ion+sel/**/ect+1,2,3-- 至于重写绕过,适用于WAF过滤了一次的情况,和我们上传aaspsp马的原理一样,我们可以写出类似Ununionion这样的。过滤一次union后就会执行我们的查询了 > ?id=1 ununionion select 1,2,3-- 5. Http参数污染(HPP) 比如我们有这样的语句: > /?id=1 union select+1,2,3+from+users+where+id=1-- 我们可以重复一次前面的id值添加我们的值来绕过,&id=会在查询时变成逗号 > /?id=1 union select+1&id=2,3+from+users+where+id=1-- 这种情况成功的条件比较多,取决于具体的WAF实现。。 再给出一个例子说明用法 > /?id=1/**/union/*&id=*/select/*&id=*/pwd/*&id=*/from/*&id=*/users-- 具体分析的话就涉及到查询语句的后台代码的编写了。 比如服务器是这样写的: > select * from table where a=".$_GET['a']." and b=".$_GET['b']." limit ".$_GET['c']; 那我们可以构造这样的注入语句: > /?a=1+union/*&b=*/select+1,pass/*&c=*/from+users-- 最终解析为: > select * from table where a=1 union/* and b=*/select 1,pass/*limit */from users-- 可以看到,这种方式其实比较适合白盒测试,而对于黑盒渗透的话,用起来比较麻烦。但是也可以一试。 6. 使用逻辑运算符 or /and绕过 > /?id=1+OR+0x50=0x50 > /?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74 顺便解释一下第二句话,从最里面的括号开始分析,select+pwd+from+users+limit+1,1 这句是从users表里查询pwd字段的第一条记录,比如是admin, 然后mid(上一句),1,1就是取admin的第一个字符,也就是a, lower(上一句)就是把字符转换为小写, 然后ascii就是把a转换成ascii码,看等不等于74. 7. 比较操作符替换 包括!= 不等于,<>不等于,< 小于,>大于,这些都可以用来替换=来绕过, 比如上一个例子,要判断是不是74,假设=被过滤,那么我们可以判断是不是大于73,是不是小于75,然后就知道是74了。。很多WAF都会忘了这个。 8. 同功能函数替换 Substring()可以用mid(),substr()这些函数来替换,都是用来取字符串的某一位字符的。 Ascii()编码可以用hex(),bin(),也就是16进制和二进制编码替换 Benchmark() 可以用sleep()来替换,这两个使用在基于延时的盲注中,有机会给大家介绍 如果连这些都屏蔽了,还有一种新的方法 ...

2013-01-06 · 1 min · bystander

远程管理Demo(C#)

一个C#的通信的例子 1.服务端,服务端通过ip和端口生成客户端之后,点击开始监听后,便开启监听线程持续监听,同时注册断开连接和收到信息的事件。收到来自TcpClient 流中的信息后,解析之,如果是连接信息,就添加到连接列表,这样服务端就可以显示多个客户端了。如果是断开信息,就删掉。如果服务端想要给客户端发消息,就选中该客户,然后填写信息,就会调用连接类的发送方法。 2.客户端,也就是被控端,被控端通过tcp连接到远端ip,然后发送连接成功状态,随后异步读取。读取到信息后调用解析方式。然后处理。。 3.服务端如何生成客户端。其实也比较简单。就是写好客户端以后,保存为文本。然后通过CodeDomProvider的相关方法来编译即可。代码如下: public static bool Compile(string EXE_Name, string Source) { CodeDomProvider Compiler = CodeDomProvider.CreateProvider("CSharp"); CompilerParameters Parameters = new CompilerParameters(); CompilerResults cResults = default(CompilerResults); Parameters.GenerateExecutable = true; Parameters.OutputAssembly = EXE_Name; Parameters.ReferencedAssemblies.Add("System.dll"); Parameters.CompilerOptions = " /target:winexe"; Parameters.TreatWarningsAsErrors = false; cResults = Compiler.CompileAssemblyFromSource(Parameters, Source); if (cResults.Errors.Count > 0) { foreach (CompilerError CompilerError_loopVariable in cResults.Errors) { CompilerError error = CompilerError_loopVariable; MessageBox.Show("Error: " + error.ErrorText, "", MessageBoxButtons.OK, MessageBoxIcon.Error); } return false; } else if (cResults.Errors.Count == 0) { return true; } return true; } 源码下载:CSharp RAT Example.zip

2013-01-04 · 1 min · bystander