├── MyCustomPublisher.cs ├── MyCustomPublisher.dll ├── MyCustomPublisherDataModel.xml └── README /MyCustomPublisher.cs: -------------------------------------------------------------------------------- 1 |  2 | /* 3 | MyCustomPublisher.cs - Custom Publisher created for an tutorial about 4 | creating custom publishers 5 | 6 | -brad.antoniewicz@foundstone.com 7 | 8 | I dont know what all the legal crap below says, but if you ask me, you can give this 9 | to anyone you want.. :) 10 | */ 11 | 12 | 13 | 14 | // 15 | // Copyright (c) Michael Eddington 16 | // 17 | // Permission is hereby granted, free of charge, to any person obtaining a copy 18 | // of this software and associated documentation files (the "Software"), to deal 19 | // in the Software without restriction, including without limitation the rights 20 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 21 | // copies of the Software, and to permit persons to whom the Software is 22 | // furnished to do so, subject to the following conditions: 23 | // 24 | // The above copyright notice and this permission notice shall be included in 25 | // all copies or substantial portions of the Software. 26 | // 27 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 28 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 29 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 30 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 31 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 32 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 | // SOFTWARE. 34 | // 35 | 36 | 37 | using System; 38 | using System.Collections.Generic; 39 | using System.Linq; 40 | using System.Text; 41 | using System.Net.Sockets; 42 | using System.IO; 43 | using System.Net; 44 | using NLog; 45 | using Peach.Core.IO; 46 | 47 | namespace Peach.Core.Publishers 48 | { 49 | [Publisher("MyCustomPublisher", true)] 50 | [Parameter("Host", typeof(string), "Hostname or IP address of remote host")] 51 | [Parameter("Port", typeof(ushort), "Destination port number", "0")] 52 | [Parameter("StrictLength", typeof(bool), "Enforce the ABC Proto Length Restrictions (may limit fuzz cases)", "true")] 53 | [Parameter("Timeout", typeof(int), "How many milliseconds to wait for data/connection (default 3000)", "3000")] 54 | [Parameter("Interface", typeof(IPAddress), "IP of interface to bind to", "")] 55 | [Parameter("SrcPort", typeof(ushort), "Source port number", "0")] 56 | [Parameter("MinMTU", typeof(uint), "Minimum allowable MTU property value", DefaultMinMTU)] 57 | [Parameter("MaxMTU", typeof(uint), "Maximum allowable MTU property value", DefaultMaxMTU)] 58 | public class MyCustomPublisher: SocketPublisher 59 | { 60 | private static NLog.Logger logger = LogManager.GetCurrentClassLogger(); 61 | protected override NLog.Logger Logger { get { return logger; } } 62 | private IPEndPoint _remote; 63 | 64 | public bool StrictLength { get; set; } 65 | 66 | public MyCustomPublisher(Dictionary args) 67 | : base("Udp", args) 68 | { 69 | } 70 | 71 | protected override bool AddressFamilySupported(AddressFamily af) 72 | { 73 | return (af == AddressFamily.InterNetwork) || (af == AddressFamily.InterNetworkV6); 74 | } 75 | 76 | protected override Socket OpenSocket(EndPoint remote) 77 | { 78 | _remote = (IPEndPoint)remote; 79 | Socket s = new Socket(remote.AddressFamily, SocketType.Dgram, ProtocolType.Udp); 80 | return s; 81 | } 82 | 83 | protected override void FilterOutput(byte[] buffer, int offset, int count) 84 | { 85 | base.FilterOutput(buffer, offset, count); 86 | 87 | if (_remote.Port == 0) 88 | throw new PeachException("Error sending a Udp packet to " + _remote.Address + ", the port was not specified."); 89 | } 90 | protected override void OnOutput(BitwiseStream data) 91 | { 92 | 93 | /* 94 | An Abc Proto Packet is structured: 95 | 96 | +-------+-------+-------+------- 97 | [ Hdr ][ Length ] 98 | [ Data ]... 99 | 100 | Hdr = 2 btyes, Length = 2 bytes (network byte order) 101 | Data is variable length 102 | */ 103 | 104 | // Calculate the Length of the Entire Encapsulated Packet (Data + Abc Proto Hdr Len [2 bytes] + Abc Proto Len [2 bytes] 105 | int totalPktLen = (int)data.Length + 4; 106 | 107 | if (StrictLength) { 108 | /* 109 | Here we're restricting the size of the mutated data. This is an important item to 110 | note. Long string mutations are a major part of fuzzing, and by implementing this 111 | sort of logic in our custom publisher, we're limiting our test cases. It might 112 | be a better approach to ignore this length restriction.. but i'll leave that up 113 | to the user via the StrictLength parameter. 114 | */ 115 | if (totalPktLen > 65535) { 116 | Logger.Debug("ABC Proto Max Packet Length Reached, capping at 65535"); 117 | totalPktLen = 65535; 118 | } 119 | 120 | if ( totalPktLen <= 0 ) { 121 | Logger.Debug("ABC Proto Min PacketLength Reached, just setting to 4 to account for header and length fields"); 122 | totalPktLen = 4; 123 | } 124 | } 125 | // Abc Proto Header - 1234 indicates the start of an abcproto packet 126 | byte[] abcProtoHdr = { 0x12, 0x34 } ; 127 | 128 | // Create a new buffer that will the final encapsulated packet 129 | var buffer = new byte[totalPktLen]; 130 | 131 | // Copy Abc Proto Header into our new buffer 132 | Array.Copy(abcProtoHdr, 0, buffer, 0, abcProtoHdr.Length); 133 | 134 | // Copy AbcProto Length into buffer after Abc Proto Hdr - We're also doing a bit of a int to short conversion here 135 | Array.Copy(BitConverter.GetBytes(totalPktLen - 4), 0, buffer, abcProtoHdr.Length, sizeof(ushort)); 136 | // Rearrange the Length to be in Big Endian (Network Byte Order) 137 | Array.Reverse(buffer, abcProtoHdr.Length, sizeof(ushort)); 138 | 139 | //Copy Data into buffer 140 | data.Read(buffer, abcProtoHdr.Length + sizeof(ushort), buffer.Length - 4); 141 | 142 | // Call the original OnOutput() using the buffer as our new BitStream 143 | base.OnOutput(new BitStream(buffer)); 144 | 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /MyCustomPublisher.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenSecurityResearch/CustomPeachPublisher/239a95b3d48d34e48499c30fedf18603ac8bcc48/MyCustomPublisher.dll -------------------------------------------------------------------------------- /MyCustomPublisherDataModel.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Custom Peach Publisher Tutorial Accessory Code 2 | By Brad Antoniewicz 3 | brad.antoniewicz@foundstone.com 4 | -------------------------------------------------- 5 | 6 | This code was written for a tutorial on creating 7 | custom Peach Fuzzer Publishers. 8 | 9 | The tutorial can be found on http://blog.opensecurityresearch.com 10 | 11 | To compile: 12 | 13 | dmcs MyCustomPublisher.cs -out:MyCustomPublisher.dll -target:library -r:Peach.Core.dll,NLog.dll 14 | 15 | Files: 16 | MyCustomPublisher.cs - C# Source code for the publisher 17 | MyCustomPublisher.dll - Compiled Publisher (can drop into peach binary folder) 18 | MyCustomPublisherDataModel.xml - PeachPit for invoking it 19 | 20 | 21 | Enjoy! 22 | --------------------------------------------------------------------------------