Security concern ThinkPHP

I have noted in the logs an unexpected entry:

==> web.error.log <==
[2020-05-12 08:21:35 +0000] [4189] [ERROR] Error handling request /index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=md5&vars[1]
[]=HelloThinkPHP
Traceback (most recent call last):
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 53, in application
    init_request(request)
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 108, in init_request
    frappe.init(site=site, sites_path=_sites_path)
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 150, in init
    local.conf = _dict(get_site_config())
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 224, in get_site_config
    sys.exit(1)
SystemExit: 1

Could the fact that ThinkPHP is used an indication that an attempt to exploit the ErpNext/Frappe framework is in progress? I.e. https://securitynews.sonicwall.com/xmlpost/thinkphp-remote-code-execution-rce-bug-is-actively-being-exploited/ refers.

A further log entry:

==> web.error.log <==
[2020-05-12 08:23:05 +0000] [4189] [ERROR] Error handling request /GponForm        /diag_Form?style/
Traceback (most recent call last):
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 53, in application
    init_request(request)
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 108, in init_request
    frappe.init(site=site, sites_path=_sites_path)
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 150, in init
    local.conf = _dict(get_site_config())
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 224, in get_site_config
    sys.exit(1)
SystemExit: 1

On checking fail2ban logs:

awk '($(NF-1) = /Ban/){print $NF,"("$NF")"}' /var/log/fail2ban.log | sort | logresolve | uniq -c | sort -n

we note repeated attempts by 110.249.212.46 (110.249.212.46) and 121.164.35.72 (121.164.35.72) and 121.180.208.154 (121.180.208.154) to gain access.

Checking https://www.abuseipdb.com/check/110.249.212.46 confirms that both IP addresses are listed. Unfortunately only China Unicom Hebei Province Network is reported and without additional information or effort the originating host machine cannot be located.

For this to succeed the target server apparently must be running PHP (to discover a vulnerable controller for a remote code execution RCE attack)?

That’s not the case with ERPNext so presumably it’s immune.

Thanks for reporting this, best to please inform Frappe to confirm all is well:

https://erpnext.com/security/references

https://erpnext.com/security/report?new=1

https://erpnext.com/security

Thank you.

I have noted that the attempts to gain access is targeted against NGINX, SSH and the ERPNEXT interface. For what it is worth, I would definitely suggest that people self-hosting focus on security. It was an extensive exercise to harden the server by for instance moving the Lynis score to 85 points (https://cisofy.com/lynis/), to secure the router, attend in detail to fail2ban configuration, the specific ufw rules, making entries in the nginx config files, looking at DNS, securing mail, checking and changing user groups & permissions, double check code on GitHub, etc etc. In the circumstances, if I had to start over, I would probably just pay ERPNEXT to host a service. Security is an ongoing exercise and to do it right takes substantial resources.

For a quick check on fail2ban i normally run this script maybe once in a while:

echo "####################"
echo "Baned last log"
echo "####################"
awk '($(NF-1) = /Ban/){print $NF}' /var/log/fail2ban.log | sort | uniq -c | sort -n 
echo "####################"
echo "Banned in all files"
echo "####################"
zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | sort | uniq -c 
echo "##################"
echo "Banned by subnet"
echo "##################"
zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | awk -F\. '{print $1"."$2"."}' | sort | uniq -c  | sort -n | tail
echo "###############"
echo "Banned by date"
echo "###############"
zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $5,$1}' | sort | uniq -c 


aureport -au -i
aureport -au -i --success
aureport -au -i --failed
aureport -l --success
aureport -l --failed
aureport -l --success --summary -i
aureport -l --failed --summary -i
echo ""
echo "####################"
echo "MOST PROBLEMATIC IP"
echo "####################"
echo ""
zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $NF}' | awk -F\. '{print $1"."$2"."}' | sort | uniq -c  | sort -n | tail 
echo ""
echo "#####################################"
echo "Grouping by Date and Fail2Ban section"
echo "#####################################"
echo ""
zgrep -h "Ban " /var/log/fail2ban.log* | awk '{print $5,$1}' | sort | uniq -c 
echo ""
echo "#####################################"
echo "Grouping by IP address and Hostname"
echo "#####################################"
echo ""
awk '($(NF-1) = /Ban/){print $NF,"("$NF")"}' /var/log/fail2ban.log | sort | logresolve | uniq -c |     sort -n

My notes here is not at all intended to state that ERPNEXT itself is insecure. ERPNEXT is just one component of a system, and most likely an unauthorized person will target the operating system itself and not necessarily the FRAPPE stack.

3 Likes

Thank you for bringing this up. It really helps people who have self hosted.

We have noted a further attack surface on hardware -

[2020-05-13 12:19:53 +0000] [5403] [INFO] Booting worker with pid: 5403
[2020-05-13 12:20:19 +0000] [5403] [ERROR] Error handling request /GponForm/diag_Form?style/
Traceback (most recent call last):
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 53, in application
    init_request(request)
  File "/opt/bench/erpnext/apps/frappe/frappe/app.py", line 108, in init_request
    frappe.init(site=site, sites_path=_sites_path)
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 150, in init
    local.conf = _dict(get_site_config())
  File "/opt/bench/erpnext/apps/frappe/frappe/__init__.py", line 224, in get_site_config
    sys.exit(1)
SystemExit: 1

This relates to DASAN GPON home routers exploits (see https://isc.sans.edu/forums/diary/DASAN+GPON+home+routers+exploits+inthewild/23677/).
image

It is possible to bypass authentication simply by appending “?images” to any URL of the device that requires authentication, as demonstrated by the /menu.html?images/ or /GponForm/diag_FORM?images/ URI. One can then manage the device. This is what we are seeing, and it is possible that others may have these routers in use.