Nmap Development mailing list archives

Re: payload file prototype


From: David Fifield <david () bamsoftware com>
Date: Fri, 19 Feb 2010 09:35:57 -0700

On Thu, Feb 18, 2010 at 12:43:25PM -0500, Jay Fink wrote:
On Mon, Feb 15, 2010 at 9:49 PM, David Fifield <david () bamsoftware com> wrote:

I don't know what you mean by the bare value and a loop. You might have
to do some things like defining operator< on proto_port to make it fit
the interface of std::map. Once you've done that, lookup is something
like

       std::map<struct proto_port, struct payload>::iterator it;
       it = Payload.find(tmp_proto_port);
       if (it == Payload.end())
               return NULL;
       else
               return &*it;

voila - some test stuff I put together last night and beat upon at
lunch today, the only issue I have right now is *getting* the payload
back but I'm sure I'll figure it out - once that is done it becomes
the plug and chug of initializing the global map, note I cut out
includes and any gunk for readability:


using namespace std;

void fake_payload(void); // temporary til init is done
void find_payload (u8 proto, u16 dport);
static std::map<struct proto_dport, char *> payload;
static int pairmatch = 0;

struct proto_dport {
  u8  proto;
  u16 dport;

  /* Compares one protocol/destination port pair and returns result */
  bool operator<(const struct proto_dport &other) const {
    if (proto == other.proto)
     if (dport == other.dport) pairmatch = 1;
  }
};

The operator< function can't be right; it doesn't return a value. You
need to return true when the this object is "less than" the other
object. std::map is a sorted tree structure internally, and uses the
ordering you define with operator<. It's not supposed to work by setting
a global flag inside the operator.

My guess is that the function will always "return" false the way you've
written it, though it's really undefined behavior. That won't work when
there's more than one payload in the map. Compile with warnings turned
on; that will catch errors like this.

void fake_payload (void) {
  struct proto_dport pp;
  static char example[] = "\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00";

  pp.proto = 17;
  pp.dport = 53;
  payload[pp] =  example;
}

Make example into a struct instead of a char array. (The struct will
contain a char array.)

void find_payload (u8 proto, u16 dport) {
  std::map<struct proto_dport, char *>::iterator it;
  char payload_string[4096];
  struct proto_dport pp;

  pp.proto = proto;
  pp.dport = dport;
  it = payload.find(pp);
  if (pairmatch == 1)
    printf("Match found\n");
}

Here, instead of checking a global flag, compare the iterator against
payload.end(). Have find_payload return either the it object or the
struct contained in the map:

        return *it;

/* XXX Wrapper test stuff */
const char *get_udp_payload(u16 dport, size_t *length) {
  find_payload(17, dport); /* 17 is UDP */
  return "nada for now";
}

Use IPPROTO_UDP instead of 17.

int main(int argc, char **argv) {
  const char *payload;
  size_t payload_length;
  u8 dport = 0;

  if (argv[1]) dport = atoi(argv[1]);
  fake_payload(); /* Load up a fake payload */
  payload = get_udp_payload(dport, &payload_length);
  return 0;
}

The get_udp_payload interface looks good. In your mockup you should have
get_udp_payload return a real value.

David Fifield
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/

Current thread: