Skip to content

Instantly share code, notes, and snippets.

@cedricvidal
Last active March 31, 2016 07:37
Show Gist options
  • Save cedricvidal/136673c4978dc9f426167421f693e7bf to your computer and use it in GitHub Desktop.
Save cedricvidal/136673c4978dc9f426167421f693e7bf to your computer and use it in GitHub Desktop.
Logback timestamp tampering example
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.quicksign.poc</groupId>
<artifactId>qs-logback-timestamp-altering</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.10.19</version>
</dependency>
</dependencies>
</project>
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.LoggingEvent;
/**
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a>
*/
public class TamperedTimestampLoggingEvent extends LoggingEvent {
private final long tamperedTimestamp;
public TamperedTimestampLoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray, long tamperedTimestamp) {
super(fqcn, logger, level, message, throwable, argArray);
this.tamperedTimestamp = tamperedTimestamp;
}
@Override
public long getTimeStamp() {
return tamperedTimestamp;
}
}
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import org.slf4j.LoggerFactory;
/**
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a>
*/
public class TamperedTimestampLoggingEventExample {
public static void main(String[] args) {
// One hour in the futur
final long tamperedTimestamp = System.currentTimeMillis() + 60 * 60 * 1000;
final String fqcn = "com.foo.bar";
Logger logger = (Logger) LoggerFactory.getLogger(fqcn);
final TamperedTimestampLoggingEvent event = new TamperedTimestampLoggingEvent(fqcn, logger, Level.INFO, "Hello", null, null, tamperedTimestamp);
logger.callAppenders(event);
}
}
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import ch.qos.logback.core.status.OnConsoleStatusListener;
import org.junit.Before;
import org.junit.Test;
import org.mockito.*;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
/**
* @author <a href="mailto:[email protected]">Cedric Vidal, Quicksign</a>
*/
public class TamperedTimestampLoggingEventTest {
@Captor
ArgumentCaptor<ILoggingEvent> captor;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testTamperTimestamp() {
// Using context that way instead of default context allows to mock components
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
// Remove default configuration
context.reset();
// Printout configuration problems
final OnConsoleStatusListener statusListener = new OnConsoleStatusListener();
statusListener.setContext(context);
statusListener.start();
context.getStatusManager().add(statusListener);
// Create mock appender which will allow to assert that the timestamp passed to it is actually tampered
final Appender<ILoggingEvent> appender = Mockito.mock(Appender.class);
appender.setContext(context);
appender.start();
// Register mock appender
context.getLogger("ROOT").addAppender(appender);
// Call appenders using logback API with a TamperedTimestampLoggingEvent
final String fqcn = "com.foo.bar";
final long tamperedTimestamp = System.currentTimeMillis() + 60 * 60 * 1000;
Logger logger = context.getLogger(fqcn);
final TamperedTimestampLoggingEvent event = new TamperedTimestampLoggingEvent(fqcn, logger, Level.INFO, "Hello", null, null, tamperedTimestamp);
logger.callAppenders(event);
// Check that the actual logged event timestamp has been tampered
Mockito.verify(appender).doAppend(captor.capture());
final ILoggingEvent actualLoggedEvent = captor.getValue();
assertEquals("Hello", actualLoggedEvent.getMessage());
assertEquals(tamperedTimestamp, actualLoggedEvent.getTimeStamp());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment