8

I was wondering if anyone had some insight into the best way to fake a web service response rather than setting up a web server. For instance, while doing dynamic analysis of malware it's useful to redirect C&C traffic to your own fake web server that can reply in the same way.

Right now I've been using a python library and then manually replying with the HTTP responses but this is time consuming and kludgy.

EDIT: Not necessarily looking for an automated tool, just a faster way of doing it.

  • You are looking for this to be automated rather than manual? – this.josh Jul 10 '11 at 7:08
2

I created this tool (and lib) specifically for this purpose --

https://github.com/jar-o/dumdum

it handles GET/POST/etc, headers, JSON input as well. No need to write code, you simply specify which request to "match" and then tie that to a response.

I made it mainly because I was sick of writing a bunch of tiny Flask servers to handle various testing scenarios.

Right now I've been using a python library and then manually replying with the HTTP responses but this is time consuming and kludgy.

Exactly. The idea here is that given a certain HTTP input, you want to respond with a certain output. That output generally is pretty fixed in relation to the input. dumdum allows the matches to fall through to other responses, so you can simulate an actual functioning server.

6

I always like netcat for this kind of thing. In this instance you could create a copy of the real response from the C&C server using

nc candcserver.com 80

submit the headers you want to pass on the command line, press enter twice, and save it to a text file, and then serve up the file you just created using

while true; do sudo nc -l 80 < capturedpage.txt; done

and point the app your testing at 127.0.0.1

  • This would work great for static content and replaying a simple response. I'm not sure how well this would work for dynamic content like a value that has a timestamp in it. – Lizbeth Jul 12 '11 at 3:42
3

There might be some products which are capable of doing this, but I've written similar proxy myself where I wanted to serve local contents rather than remote for some uri's.

Here is a modification of my code written in python. It is based on the twisted library, so you might want to get it from here.

It will match for URL's with the netloc part equal to "security.stackexchange.com" and replace it with "www.xkcd.org".

I hope you are familiar with python, so you can add more functionality in this code. It should be easy to add logging, dynamically rewrite uri's and such.

Also, if you want to modify content in-transit from the malware and the C&C, take a look at my contribution for a content rewriting proxy: https://stackoverflow.com/questions/6491932/need-help-writing-a-twisted-proxy/6521024#6521024

from twisted.web import proxy, http
from twisted.internet import reactor

from urlparse import urlparse, urlunparse
fakeweb_netloc = "www.xkcd.org"
cc_netloc = "security.stackexchange.com"

class ProxyRequest(proxy.ProxyRequest):
    def process(self):

        res = urlparse(self.uri)
        netloc = res.netloc
        print self.uri

        if netloc == cc_netloc:
           netloc = fakeweb_netloc
        self.uri = urlunparse((res.scheme, netloc, res.path, res.params, res.query, res.fragment))

        proxy.ProxyRequest.process(self)

class MyProxy(http.HTTPChannel):
    requestFactory = ProxyRequest

class ProxyFactory(http.HTTPFactory):
    protocol = MyProxy

if __name__ == "__main__":
    factory = ProxyFactory()
    reactor.listenTCP(8080,factory)
    reactor.run()
2

Consider looking at Meddler:

Meddler is a HTTP(S) Generation tool based around a simple but powerful JScript.NET event-based scripting subsystem.

This is from the excellent Fiddler family of HTTP proxy tools.

1

You can proxy HTTP requests and intercept/modify requests/responses using Ronin::Web.proxy_server from the ronin-web (0.3.0.rc1) library.

$ gem install ronin-web --pre
$ ronin-web
>> Web.proxy_server do
|    every_request do |request|
|      # inspect the request (http://ronin-ruby.github.com/docs/ronin-web/Ronin/Web/Middleware/ProxyRequest.html)
|    end
end
[-] Starting Web Server on 0.0.0.0:8080
[2011-07-12 15:31:11] INFO  WEBrick 1.3.1
[2011-07-12 15:31:11] INFO  ruby 1.9.2 (2011-02-18) [x86_64-linux]
[2011-07-12 15:31:11] INFO  WEBrick::HTTPServer#start: pid=15697 port=8080
-1

Here a simple webserver that prints whatever was send in the POST/GET request, and returns a valid HTML response

#!/usr/bin/python3

import socket
from http.server import BaseHTTPRequestHandler, HTTPServer
import time

hostName = ""
hostPort = 80

class MyServer(BaseHTTPRequestHandler):

        # GET 
        def do_GET(self):
                self.send_response(200)
                self.wfile.write("".encode("utf-8")) #send back to client

        # POST 
        def do_POST(self):
                content_length = int(self.headers['Content-Length']) 
                post_data = self.rfile.read(content_length) 
                self.send_response(200)
                print(post_data)
                self.wfile.write("".encode("utf-8")) #send back to client



myServer = HTTPServer((hostName, hostPort), MyServer)
print(time.asctime(), "Server Starts - %s:%s" % (hostName, hostPort))

try:
        myServer.serve_forever()
except KeyboardInterrupt:
        pass

myServer.server_close()
print(time.asctime(), "Server Stops - %s:%s" % (hostName, hostPort))
  • Just like anywhere else, it would be nice if you could comment your code, and specifically, indicate how this answers the question. – schroeder Feb 12 '18 at 15:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.