cgi fuzzing

794 views
Skip to first unread message

floyd

unread,
Mar 14, 2016, 3:50:03 PM3/14/16
to afl-users
Hi *

I have a closed-source ELF binary that is run as a cgi binary on a web
server. Before I start using my poor C skills I just wanted to know if
I'm on track here:

- Write a wrapper in C
- Read zero delimited arguments from stdin (similar to
experimental/argv-fuzz-inl.h)
- Put the arguments with setenv into the environment variables (all
these described here: http://www.cgi101.com/book/ch3/text.html )
- Depending on the use case read some more arguments from stdin and use
as command line args for the closed source binary
- call the binary with execve from the wrapper
- Run afl-fuzz with -Q on the wrapper

Should that work? I'm not sure if QEMU mode will cover the paths of the
closed-source binary as well?

My other approach would be to use dyninst to instrument the binary so I
don't need QEMU mode anmyore...

Thoughts?

cheers,
floyd

--
floyd
@floyd_ch
http://www.floyd.ch

floyd

unread,
Mar 16, 2016, 12:11:51 PM3/16/16
to afl-...@googlegroups.com
If anyone is interested, that's what I hacked up:

https://github.com/floyd-fuh/afl-cgi-wrapper

I'm still testing. Feedback welcome.

cheers,
floyd

Brandon Perry

unread,
Mar 16, 2016, 12:48:18 PM3/16/16
to afl-...@googlegroups.com

> On Mar 16, 2016, at 11:11 AM, floyd <fl...@floyd.ch> wrote:
>
> If anyone is interested, that's what I hacked up:
>
> https://github.com/floyd-fuh/afl-cgi-wrapper
>
> I'm still testing. Feedback welcome.
>

Are you at least able to discover new paths with this method? Thanks for sharing.
> --
> You received this message because you are subscribed to the Google Groups "afl-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to afl-users+...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

signature.asc

Michal Zalewski

unread,
Mar 16, 2016, 1:05:22 PM3/16/16
to afl-users
> I'm still testing. Feedback welcome.

Looks OK, you'd need to disable the forkserver, right? (Or compile
both with AFL, but in this case, you basically end up disabling the
forkserver anyway.)

Maybe take the name of the target binary as a command-line argument
(or an env variable)?

/mz

floyd

unread,
Mar 17, 2016, 7:40:14 AM3/17/16
to afl-...@googlegroups.com
>> I'm still testing. Feedback welcome.
>
> Looks OK, you'd need to disable the forkserver, right? (Or compile
> both with AFL, but in this case, you basically end up disabling the
> forkserver anyway.)

That's why I had "I'm not sure if QEMU mode will cover the paths of the
closed-source binary as well?" in my first Email. I guess the answer is
no. The fuzzing looks pretty healthy (at first):
http://pastebin.com/ZabvW6UH . Started with:

afl-fuzz -i output2/ -o output3 -t 130 -Q -x
someStringsFromDisassembly.txt /opt/fuzzing-smpw/execve-wrapper.elf

However, I think the 50 paths are probably just the wrapper paths but
not the cgi-binary's paths. This should answer Brandon's questions as
well. So I could just as well use -n at the moment. Or am I wrong?

I guess the only way to get paths for the cgi binary is by using dyninst
and not running in QEMU mode?

Michal, I don't get why disabling the forkserver would help in this
case? Can you elaborate?

> Maybe take the name of the target binary as a command-line argument
> (or an env variable)?

Yes I should change that.

cheers,
floyd

Sj Puzzor

unread,
Mar 17, 2016, 11:36:17 AM3/17/16
to afl-...@googlegroups.com
Hi, 

I previously fuzzed cgi with afl. 
You need to disable forkserver indeed, or there won't be more path in the true target. I didn't see your code.
I used a wrapper too but I disabled forkserver.
The problem is caused by setenv in my understand. Qemu has an option to set env with -E, and it will process it to apply an environment for the target, but with forkserver, you cant change that env after the first run even if you secondly run qemu with a different option of -E. You can experiment it with a cgi program you write it yourself.

Thanks
@Puzzor
--
You received this message because you are subscribed to the Google Groups "afl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to afl-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
From gmai mobile
Shi Ji(@Puzzor)

Sj Puzzor

unread,
Mar 17, 2016, 11:40:43 AM3/17/16
to afl-...@googlegroups.com
Aha, a slight look on your code, it seems you just use setenv? I'm not sure it will work.... If I remember correctly, this method cant work with qemu mode. Have you try that?


On Thursday, March 17, 2016, floyd <fl...@floyd.ch> wrote:
--
You received this message because you are subscribed to the Google Groups "afl-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to afl-users+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Michal Zalewski

unread,
Mar 17, 2016, 12:04:28 PM3/17/16
to afl-users
> I guess the only way to get paths for the cgi binary is by using dyninst
> and not running in QEMU mode?

Ah, sorry, I completely missed the QEMU part.

Here's an idea: modify afl_forkserver() in afl-qemu-cpu-inl.h.
Specifically, look for this:

if (!child_pid) {

/* Child process. Close descriptors and run free. */

afl_fork_child = 1;
close(FORKSRV_FD);
close(FORKSRV_FD + 1);
close(t_fd[0]);
return;

}

...and just before "return;", read stuff from stdin or input file and
put it into env variables. That may give you just what you're looking
for.

Cheers,
/mz

floyd

unread,
Apr 7, 2016, 12:34:04 PM4/7/16
to afl-...@googlegroups.com
Hi Puzzor, Michal

On 17/03/16 16:36, Sj Puzzor wrote:
> I previously fuzzed cgi with afl.
> You need to disable forkserver indeed, or there won't be more path in
> the true target. I didn't see your code.
> I used a wrapper too but I disabled forkserver.
> The problem is caused by setenv in my understand. Qemu has an option to
> set env with -E, and it will process it to apply an environment for the
> target, but with forkserver, you cant change that env after the first
> run even if you secondly run qemu with a different option of -E. You can
> experiment it with a cgi program you write it yourself.

@Puzzor: Your right, setenv doesn't seem to work with -Q.

I actually started to write simple cgis for debugging. The open source
case where I compile the cgi with afl-clang and use the wrapper I wrote
(see closed-source-afl-showmap.sh in [1]) works fine. Now I need to
figure out the "closed source" part. So far nothing worked for me.

You mentioned the -E option of QEMU. How did you set that one?

On 17/03/16 17:04, Michal Zalewski wrote:
> Here's an idea: modify afl_forkserver() in afl-qemu-cpu-inl.h.
> Specifically, look for this:
>
> if (!child_pid) {
>
> /* Child process. Close descriptors and run free. */
>
> afl_fork_child = 1;
> close(FORKSRV_FD);
> close(FORKSRV_FD + 1);
> close(t_fd[0]);
> return;
>
> }
>
> ...and just before "return;", read stuff from stdin or input file and
> put it into env variables. That may give you just what you're looking
> for.

@Michal: I tried adding a simple setenv("HTTP_HOST", "TESTTESTTEST", 1);
in afl-qemu-cpu-inl.h where you said (and cleaned and newly build qemu
support), however, the variable doesn't get set (tested with
closed-source-afl-showmap.sh in [1]) and the example child process won't
print it. Any other ideas?

[1] https://github.com/floyd-fuh/afl-cgi-wrapper

cheers,
floyd

Michal Zalewski

unread,
Apr 7, 2016, 11:06:42 PM4/7/16
to afl-users
> @Michal: I tried adding a simple setenv("HTTP_HOST", "TESTTESTTEST", 1);
> in afl-qemu-cpu-inl.h where you said (and cleaned and newly build qemu
> support), however, the variable doesn't get set (tested with
> closed-source-afl-showmap.sh in [1]) and the example child process won't
> print it. Any other ideas?

Hm, dunno, presumably QEMU either messes with the environment, or
creates a shadow copy for the translated code, instead of using a
shared one. I'm not very familiar with QEMU user mode internals, but
it's probably easy to fix once you figure out what's happening...

/mz
Reply all
Reply to author
Forward
0 new messages