Why does CVE-2007-2447 require /= to work?

I’m doing writeups on old boxes that I’ve completed and doing a deep dive into the code of each exploit to learn how it works. I understand everything about how CVE-2007-2447 works OTHER than why it requires " /= " to work. Exploit is used on Lame.

EDIT: I notice in another writeup they don’t use it when manually sending the information via impacket, I’m starting to question how well I understand this exploit.

Bump

I love the question and the fact you dare asking it.

I looked around a little bit and it’s indeed not too clear why that’s needed, right.

I just used Google to look at this, so do take my words with a big grain of salt:
Note how cve-details says:
“…to execute arbitrary commands via shell metacharacters…”

If you look here:

Then you see “/=” is indeed some obscure conditional operator, much like “+=” but only for division.

But, this still doesn’t answer your question.

A few easy things you could do is for example use a different special conditional operator, like “*=” and see what happens. Then try something that’s not a conditional operator, like just “/”. It may isolate the question “is this due to a conditional operator?”.
However, even in the case this might give you like a tiny bit of information, this too won’t bring you a definitive answer, cause it actually all depends on the code that preceded it.

What is indeed curious: you say you can run the exploit without the magical “/=”? Have you tested that yourself?

Anyway, I don’t know the answer and I’m kinda sorry to say that finding the answer is no simple task. At the very least it will be time consuming. I think your final answer can only come from:

  • either you find the source code and see where this code is executed. It should show you the full command and then this should start to make a whole lot more sense. If sourcecode is available, maybe you’re lucky and the cve number is mentioned in the repositories that maintain the code.
  • or you’re down to debugging. If you know what binary is affected, then things are a bit easier: open the binary in IDA or whatever and hunt down the part where this code first executes and follow the path of this variable input you give. Somewhere along the line, you should see the entire command that’s responsible for it’s vulnerability… but this can be quite the undertaking man. If you don’t know what binary holds the code, then yeah… in that case you’re in it for the long ride.
  • or ask someone who wrote an exploit, but even there: coders don’t won’t not necessary know why they coded it. The guy who found the exploit will. But I’m guessing most people will just be happy knowing the magic sequence and never get to the question you’re asking here.

I’m sorry it’s not a definitive answer, but I must say:
I do believe this kinds of questions are the exact ones a hackers should ask him/herself and I love the fact you dare asking it. It will set you apart from many others.

If you ever find out, do let me know. If I do the box sometime and feel brave enough to ask the same question, I’ll let you know too.

Best of luck man.

Edit: This whole post ended up being wrong. @Azele figured it out and did a writeup on it.

@opt1kz thanks for the clarification man. Very enlightening to read.

I’m curious, can you say something about how you traced back to the execl() in this case? If you could be somewhat specific about it, that’d be cool.
I honestly never decompiled anything like samba, so I wouldn’t really know where to start or is is just all comprised in one executable and less fragmented than I think? ‘services’ always seem a bit more elusive when it comes to finding where you should start to look.

“Someone wrote an exploit for it, released it and from that point forward everyone just copied the payload without thinking or asking the question you did.”

…wouldn’t be surprised one bit about that.

@gnothiseauton No decompilation or heavy reverse engineering is necessary in this case, as Samba is open source.

As noted by CVE - CVE-2007-2447 the vulnerable versions are 3.0.0 through 3.0.25rc3. You can find most of those old versions at Index of /pub/samba/stable. I happened to grab 3.0.20.

It’s a fairly big project, so instead of crawling through all the files by hand:

root@kali:/media/sf_shared/samba-3.0.20# grep -R "map script" *
-*- snip -*-
source/lib/username.c:	/* first try the username map script */
-*- snip -*-

Taking a look at that file, we see this:

	/* first try the username map script */
	
	if ( *cmd ) {
		char **qlines;
		pstring command;
		int numlines, ret, fd;

		pstr_sprintf( command, "%s \"%s\"", cmd, user );

		DEBUG(10,("Running [%s]\n", command));
		ret = smbrun(command, &fd);
		DEBUGADD(10,("returned [%d]\n", ret));

So it’s just putting the supplied username onto the end of a command string (cmd in this case is /etc/samba/scripts/mapusers.sh as set by the config file) and then tossing that into smbrun(). Okay, so where’s smbrun()?

root@kali:/media/sf_shared/samba-3.0.20# grep -R "smbrun(" *
-*- snip -*-
source/lib/smbrun.c:This is a utility function of smbrun().
source/lib/smbrun.c:int smbrun(char *cmd, int *outfd)
-*- snip -*-

That function just does a bunch of process/permissions housekeeping, and then right at the very bottom:

	execl("/bin/sh","sh","-c",cmd,NULL);  
	
	/* not reached */
	exit(82);
	return 1;

Browsing through the code above this, it’s very clear that the cmd variable is never sanitized. So user (our input) gets put directly into cmd, then cmd gets tossed directly into execl(), giving us command execution via:

sh -c /etc/samba/scripts/mapusers.sh "our_input_here"

Note: I actually messed up the quotation marks in my previous post, but it doesn’t even matter because of how straightforward this vulnerability is.

If you take a look at a newer, fixed version of Samba you’ll instead see that smbrun() is now just a wrapper function which calls smbrun_internal() with the sanitize argument set to True. What’s that do? Well, back to the execl() call:

		const char *newcmd = sanitize ? escape_shell_string(cmd) : cmd;
		if (!newcmd) {
			exit(82);
		}
		execl("/bin/sh","sh","-c",newcmd,NULL); 

Easy peasy. Two greps and some patience and anyone could stumble on dumb vulnerabilities like this. :slight_smile:

@opt1kz @gnothiseauton
Thank you guys so much! I’m pretty sure I understand this exploit fully now.

I took a peek into the smbclient code and found out why the “/” is required after this as the server’s code didn’t seem to have anything that interacts with it. I’m not 100% sure if it’s against the rules or not to post a link to an article that I wrote but here it is. ¯\(ツ)

At first I was under the assumption it was passed to bash like gnothiseauton was saying, but it’s actually just used by smbclient to separate out the DOMAIN and USERNAME fields in the request! I still have no idea where the = came from though lol.

Nice writeup. And no, as far as I know it’s not against the rules.

I was also under the assumption that it got passed to bash which I why I was blah-blah-blah’ing about it seemingly being useless. Looks like I was wrong! I didn’t think to go as far as actually analyzing SMB. Good stuff!

Removing my original reply and replacing it with a link to your post so people wandering by don’t get confused.

@opt1kz just wanted to thank you for your detailed answer. It’s always really inspiring to read things and I value the time you took to give the explanation. Thanks man.

@Azele thanks for the article! That’s the kind of stuff I really like: fresh, critical thinking original insights. It’s awesome you bring stuff that’s not already been recycled 7 times! I’d vote for more of this :smiley:
Thanks for sharing

P. S. I’d be in favor by the way that you keep posting about such articles here.