Synapse raw socket set syn/ack flags (Will pay $ for example) lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Trenatos · 2022-03-29 18:21 I'm in infosec as an appsec engineer but working my way towards pentesting. It's great fun and I use FPC for all sorts of things, but I figured I'd try to make a port scanner in FPC to learn more, but I've gotten stuck. Using Synapse, going the simplest route and just connecting works fine, but I'd like to mimic something nmap does to be more stealthy, and to do that I need to control the various flags on a raw request. I can not figure out how to set or read flags in a raw request. I'm happy to pay someone USD$50 if they can write up a simple example of: how to create a raw request, set the syn flag, read response flag, set the ack flag, as this will help my learning and I can expand from there. ---------------------------------------------------------------------- Warfley · 2022-03-29 18:30 I don't know about synapse, but the FPC ships the sockets unit a cross plattform wrapper of the berkeley sockets api for unix and winsock2 (which is berkley sockets compatible) on windows. With this you can create a raw socket and send IP packets directly: https://linux.die.net/man/7/raw Here is an example I found for both UDP and TCP with manual header control: https://www.tenouk.com/Module43a.html ---------------------------------------------------------------------- Trenatos · 2022-03-29 20:05 Thanks but those are based on C. They do show the overall process which I get, but I need a more concrete example (Thus the offer to pay) ---------------------------------------------------------------------- Warfley · 2022-03-29 22:23 If you want to go into IT-Sec, especially pen testing, you need to familiarize yourself with C. C code runs the world, all the systems APIs for POSIX and Windows are C first, and all the documentation is going to be in C. Also the most vulnerable code is probably going to be C code (like someone using printf). And this is especially true if you want to do anything with respect to networking code, because in networking the Socket API is king, and everything here is C. The good thing is, if you know Pascal, C is very easy, as it is basically just a little bit of different syntax. Let's take the example I have shown: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #define PCKT_LEN 8192This is the C way of writing an untyped constant (defines are worse than constants, but it's the closest thing C has to a constant) so in Pascal you write: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const PCKT_LEN = 8192;Next we have structs, which are basically records. If a struct in C has a : after a field, this is a bit field, and therefore equivalent to pascals bitpacked structs. You could try to translate the structs directly from C, but what I find in such situations much better is to get the header structure from somewhere else and try to implement it yourself (especially as their example honestly does not look right, this is not the IP header): Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   // See: https://www.wikiwand.com/en/IPv4#/Header  PIPHeader = ^TIPHeader;  TIPHeader = bitpacked record    // switched up because of bit order in FPC is the other way around than is read within a byte    IHL: 0..15; // 4 bit    Version: 0..15; // 4 bit    // Also switched because of bit order    ECN: 0..3; // 2 bit    DSCP: 0..63; // 6 bit    TotalLength: Word; // 16 bit    Identification: Word; // 16 bit    // Again the switch because of bitorder, for that reason offset was broken up into lower and upper    OffsetUpper: 0..31; // 5 bit    Flags: 0..7; // 3 bit    // The rest is in the order given    OffsetLower: Byte; // 8 bit    TTL: Byte; // 8 bit    Protocol: Byte; // 8 Bit    Checksum: Word; // 16 Bit;    SourceIP: Cardinal; // 32 bit    DestIP: Cardinal; // 32 bit  end;You can, like me here, use the Pascal types, if you know their size and know the fields, if you are unsure and just want to copy the C code, use the ctypes unit, which for example has "cuchar" which is the same as "unsinged char" or "cuint" which is unsigned int and so on. In Pascal it is a convention to always declare your pointer types if you intend to use them (foreshadowing), and therefore I created PIPHeader as pointer to TIPHeader So you can do this for the TCP header. The next thing there is the computation of a checksum: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unsigned short csum(unsigned short *buf, int nwords){       //        unsigned long sum;        for(sum=0; nwords>0; nwords--)                sum += *buf++;        sum = (sum >> 16) + (sum &0xffff);        sum += (sum >> 16);        return (unsigned short)(~sum);}Which is a function that returns an unsigned short (16 bit word), over a buffer of "nwords" number of 16 bit words. * indicates a pointer to the data, the ++ for this matter gives back the pointer, which can be used to access the data, and afterwards increments the pointer to point to the next element in the array. In Pascal we can either build this similarly, using Inc and ^ operator. The >> operator is the shift right oeparator, & is (bitwise) And and ~ is (bitwise) not: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function Checksum(Buff: PWord; Count: Integer): Word;var  sum: QWord; // equivalent to unsigned longbegin  sum := 0; // the first bit of the for loop: initialize sum to 0  while Count > 0 do // the second bit of the for loop: check if count > 0  begin    // The code of the for loop:    sum += buff^; // *buff    Inc(buff); // buff++    Dec(Count); // the last bit of the for loop: decrement count  end;  sum := (sum shr 16) + (sum And $FFFF);  sum += (sum shr 16);  Result := not sum; // bitwise notend;This is a literal translation, you can clean this up to have a more concise and readable function, according to the RFC: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i function Checksum(Buff: PWord; Count: Integer): Word;var  i: Integer;begin  Result := 0;  for i:=0 to Count do    Result := (Result + Buff[i]) + (Result + Buff[i]) Shr 16; // ones complement addition: add and then add carry  Result := not Result; // ones complement of sum: bitwise not of resultend; Then in the document begins the main, which is just the entry point for the compiler, argc and argv are what ParamCount and ParamStr is in Pascal. This example then declares all the variables in the beginning, which is neat, because this is how we do things in pascal: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i int sd;// No data, just datagramchar buffer[PCKT_LEN];// The size of the headersstruct ipheader *ip = (struct ipheader *) buffer;struct tcpheader *tcp = (struct tcpheader *) (buffer + sizeof(struct ipheader));struct sockaddr_in sin, din;int one = 1;const int *val = &one; Again, * is pointer, & in C takes the pointer of a variable, which is equivalent to @. Aside from that casts in C are (type)var while in pascal it is type(var). So we get this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  sd: Integer;  // No data/payload just datagram  buffer: Array[0..PCKT_LEN-1] of Byte; // Char in C is what we usually use byte for  // Our own headers' structures  ip: PIPHeader;  tcpheader: PTCPHeader;   // Source and destination addresses: IP and port  sin, din: sockaddr_in; // type provided by the sockets unit  one: Integer;  val: PInteger;begin  // Initializing the variables:  ip := PIPHeader(@Buffer);  tcpheader := PTCPHeader(@Buffer + SizeOf(TIPHeader));  one := 1;  val := @one;The whole one and val thing is a bit stupid tbh, but you will notice this when you look at the code later. The rest is simple imperative code, that is very similar to pascal. There is just one notable thing, in c the operator "->" is the same as ^. in pascal, so ip->ip_ihl is equivalent to ip^.IHL here. And Memset is FillChar. Lastly, the socket functions in pascal have an fp prefix, so instead of having Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);becomes: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i sd := fpsocket(PF_INET, SOCK_RAW, IPPROTO_TCP); This is pretty much everything you need to know to understand this piece of code. I will not translate that code for you (even though this writeup was probably more effort than doing it myself directly), because, no offense, but if you are not willing to learn how to read C code, I don't think you will get far in such areas of IT-Sec. And it is not hard, it requires some training, but it's something that shouldn't take much more than a day or two to get to a point where you can easiely understand what the C code is doing. Also you should familiarize yourself with reading the Man pages and RFC standards if you want to do any of this more often. Sometimes you might also need to get deeper, during my time working in software verification I had problems where I had to consult the POSIX standard or even the Linux kernel source to figure out how stuff works. And at least at this point, you need to know C